@gravity-ai/api 1.1.3 → 1.1.5

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,183 @@
1
+ import { d as Ad } from './types-DYbti_CZ.mjs';
2
+
3
+ /**
4
+ * @gravity-ai/api/opentui — Gravity ad rendering + tracking for OpenTUI terminals
5
+ *
6
+ * Two levels of abstraction:
7
+ *
8
+ * 1. `createGravityAdCard()` — batteries-included ad card. Creates the layout,
9
+ * populates content, handles height, wires tracking. One call to integrate.
10
+ *
11
+ * ```ts
12
+ * import { createGravityAdCard } from '@gravity-ai/api/opentui';
13
+ *
14
+ * const adCard = createGravityAdCard({ renderer, input });
15
+ * root.add(adCard.panel);
16
+ * adCard.showAd(ads[0]);
17
+ * ```
18
+ *
19
+ * 2. `gravityAdTracking()` — low-level tracking primitive. You build the layout,
20
+ * the SDK wires impression firing, click-to-open-browser, and hover/click.
21
+ *
22
+ * ```ts
23
+ * import { gravityAdTracking } from '@gravity-ai/api/opentui';
24
+ *
25
+ * const tracking = gravityAdTracking({ renderer, input, panel, clickTargets: [text] });
26
+ * tracking.setAd(ads[0]);
27
+ * ```
28
+ *
29
+ * Requires `@opentui/core` as a peer dependency.
30
+ */
31
+
32
+ interface GravityAdTrackingOptions {
33
+ /** OpenTUI renderer instance. */
34
+ renderer: any;
35
+ /** OpenTUI `InputRenderable` — focus returns here when hover ends. */
36
+ input: any;
37
+ /**
38
+ * The root renderable that represents the ad.
39
+ * `visible` is toggled by `setAd()` / `clear()`.
40
+ */
41
+ panel: any;
42
+ /**
43
+ * All renderables that should respond to mouse hover/click.
44
+ * Typically every child in the ad card so the entire surface is interactive.
45
+ * The panel itself is included automatically — no need to list it here.
46
+ */
47
+ clickTargets?: any[];
48
+ /** Called when an impression pixel fires. */
49
+ onImpression?: (ad: Ad) => void;
50
+ /** Called when the user clicks the ad (before the browser opens). */
51
+ onClick?: (ad: Ad) => void;
52
+ /** Custom hover-on handler. Called instead of the default cursor/pointer logic. */
53
+ onHoverIn?: (ad: Ad) => void;
54
+ /** Custom hover-off handler. Called instead of the default cursor/pointer logic. */
55
+ onHoverOut?: () => void;
56
+ }
57
+ interface GravityAdTracking {
58
+ /**
59
+ * Set the active ad. Fires the impression pixel, shows the panel,
60
+ * and wires click/hover to the ad's URL.
61
+ * Pass `null` to hide (same as `clear()`).
62
+ */
63
+ setAd: (ad: Ad | null) => void;
64
+ /** Hide the ad and reset all state. */
65
+ clear: () => void;
66
+ /** The currently active ad, or `null`. */
67
+ readonly ad: Ad | null;
68
+ /** Whether the impression has been fired for the current ad. */
69
+ readonly impressionFired: boolean;
70
+ }
71
+ /**
72
+ * Wire Gravity ad tracking onto your own OpenTUI renderables.
73
+ *
74
+ * Handles impression firing (via `fetch()`), click-to-open-browser,
75
+ * mouse hover cursor changes, and input focus management.
76
+ * You build the layout however you want.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * import { gravityAdTracking } from '@gravity-ai/api/opentui';
81
+ *
82
+ * const myPanel = new BoxRenderable(renderer, { ... });
83
+ * const myTitle = new TextRenderable(renderer, { ... });
84
+ * const myCta = new TextRenderable(renderer, { ... });
85
+ * myPanel.add(myTitle);
86
+ * myPanel.add(myCta);
87
+ *
88
+ * const tracking = gravityAdTracking({
89
+ * renderer,
90
+ * input,
91
+ * panel: myPanel,
92
+ * clickTargets: [myTitle, myCta],
93
+ * });
94
+ *
95
+ * // When you receive an ad:
96
+ * tracking.setAd(ads[0]);
97
+ *
98
+ * // To hide:
99
+ * tracking.clear();
100
+ * ```
101
+ */
102
+ declare function gravityAdTracking(options: GravityAdTrackingOptions): GravityAdTracking;
103
+ interface GravityAdCardStyleProps {
104
+ borderColor?: string;
105
+ backgroundColor?: string;
106
+ }
107
+ interface GravityAdCardOptions {
108
+ /** OpenTUI renderer instance. */
109
+ renderer: any;
110
+ /** OpenTUI `InputRenderable` — focus returns here when hover ends. */
111
+ input: any;
112
+ /**
113
+ * Layout variant.
114
+ * - `'card'` (default): bordered card with title, body, CTA, and "Ad" label.
115
+ * - `'minimal'`: no border or background — just text + tracking.
116
+ */
117
+ variant?: 'card' | 'minimal';
118
+ /** Called when an impression pixel fires. */
119
+ onImpression?: (ad: Ad) => void;
120
+ /** Called when the user clicks the ad (before the browser opens). */
121
+ onClick?: (ad: Ad) => void;
122
+ /** Style overrides for the outer panel (border, background). */
123
+ panel?: GravityAdCardStyleProps;
124
+ /** Style overrides for the ad body text. */
125
+ text?: {
126
+ fg?: string;
127
+ };
128
+ /** Style overrides for the CTA text. */
129
+ cta?: {
130
+ fg?: string;
131
+ };
132
+ /** Style overrides for the "Ad" label. */
133
+ label?: {
134
+ fg?: string;
135
+ };
136
+ /**
137
+ * Hover state overrides. The default ships with a visible hover
138
+ * affordance (brighter border + lighter background) because it
139
+ * directly impacts click-through rate.
140
+ */
141
+ hoverPanel?: GravityAdCardStyleProps;
142
+ }
143
+ interface GravityAdCard {
144
+ /** The root renderable — add this to your render tree. */
145
+ panel: any;
146
+ /** Populate the card with an ad and activate tracking. Pass `null` to hide. */
147
+ showAd: (ad: Ad | null) => void;
148
+ /** Hide the card and reset all state. */
149
+ clear: () => void;
150
+ /** Direct access to inner renderables for post-creation mutation. */
151
+ elements: {
152
+ text: any;
153
+ cta: any;
154
+ label: any;
155
+ };
156
+ /** The underlying tracking instance. */
157
+ tracking: GravityAdTracking;
158
+ }
159
+ /**
160
+ * Create a ready-to-use Gravity ad card for OpenTUI.
161
+ *
162
+ * Handles layout creation, content population, height calculation,
163
+ * impression firing, click-to-open-browser, and hover affordance.
164
+ * Override any visual property via the options or mutate the returned
165
+ * `elements` directly — no lock-in.
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * import { createGravityAdCard } from '@gravity-ai/api/opentui';
170
+ *
171
+ * const adCard = createGravityAdCard({ renderer, input });
172
+ * root.add(adCard.panel);
173
+ *
174
+ * // When you receive an ad:
175
+ * adCard.showAd(ads[0]);
176
+ *
177
+ * // To hide:
178
+ * adCard.clear();
179
+ * ```
180
+ */
181
+ declare function createGravityAdCard(options: GravityAdCardOptions): GravityAdCard;
182
+
183
+ export { type GravityAdCard, type GravityAdCardOptions, type GravityAdCardStyleProps, type GravityAdTracking, type GravityAdTrackingOptions, createGravityAdCard, gravityAdTracking };
@@ -0,0 +1,183 @@
1
+ import { d as Ad } from './types-DYbti_CZ.js';
2
+
3
+ /**
4
+ * @gravity-ai/api/opentui — Gravity ad rendering + tracking for OpenTUI terminals
5
+ *
6
+ * Two levels of abstraction:
7
+ *
8
+ * 1. `createGravityAdCard()` — batteries-included ad card. Creates the layout,
9
+ * populates content, handles height, wires tracking. One call to integrate.
10
+ *
11
+ * ```ts
12
+ * import { createGravityAdCard } from '@gravity-ai/api/opentui';
13
+ *
14
+ * const adCard = createGravityAdCard({ renderer, input });
15
+ * root.add(adCard.panel);
16
+ * adCard.showAd(ads[0]);
17
+ * ```
18
+ *
19
+ * 2. `gravityAdTracking()` — low-level tracking primitive. You build the layout,
20
+ * the SDK wires impression firing, click-to-open-browser, and hover/click.
21
+ *
22
+ * ```ts
23
+ * import { gravityAdTracking } from '@gravity-ai/api/opentui';
24
+ *
25
+ * const tracking = gravityAdTracking({ renderer, input, panel, clickTargets: [text] });
26
+ * tracking.setAd(ads[0]);
27
+ * ```
28
+ *
29
+ * Requires `@opentui/core` as a peer dependency.
30
+ */
31
+
32
+ interface GravityAdTrackingOptions {
33
+ /** OpenTUI renderer instance. */
34
+ renderer: any;
35
+ /** OpenTUI `InputRenderable` — focus returns here when hover ends. */
36
+ input: any;
37
+ /**
38
+ * The root renderable that represents the ad.
39
+ * `visible` is toggled by `setAd()` / `clear()`.
40
+ */
41
+ panel: any;
42
+ /**
43
+ * All renderables that should respond to mouse hover/click.
44
+ * Typically every child in the ad card so the entire surface is interactive.
45
+ * The panel itself is included automatically — no need to list it here.
46
+ */
47
+ clickTargets?: any[];
48
+ /** Called when an impression pixel fires. */
49
+ onImpression?: (ad: Ad) => void;
50
+ /** Called when the user clicks the ad (before the browser opens). */
51
+ onClick?: (ad: Ad) => void;
52
+ /** Custom hover-on handler. Called instead of the default cursor/pointer logic. */
53
+ onHoverIn?: (ad: Ad) => void;
54
+ /** Custom hover-off handler. Called instead of the default cursor/pointer logic. */
55
+ onHoverOut?: () => void;
56
+ }
57
+ interface GravityAdTracking {
58
+ /**
59
+ * Set the active ad. Fires the impression pixel, shows the panel,
60
+ * and wires click/hover to the ad's URL.
61
+ * Pass `null` to hide (same as `clear()`).
62
+ */
63
+ setAd: (ad: Ad | null) => void;
64
+ /** Hide the ad and reset all state. */
65
+ clear: () => void;
66
+ /** The currently active ad, or `null`. */
67
+ readonly ad: Ad | null;
68
+ /** Whether the impression has been fired for the current ad. */
69
+ readonly impressionFired: boolean;
70
+ }
71
+ /**
72
+ * Wire Gravity ad tracking onto your own OpenTUI renderables.
73
+ *
74
+ * Handles impression firing (via `fetch()`), click-to-open-browser,
75
+ * mouse hover cursor changes, and input focus management.
76
+ * You build the layout however you want.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * import { gravityAdTracking } from '@gravity-ai/api/opentui';
81
+ *
82
+ * const myPanel = new BoxRenderable(renderer, { ... });
83
+ * const myTitle = new TextRenderable(renderer, { ... });
84
+ * const myCta = new TextRenderable(renderer, { ... });
85
+ * myPanel.add(myTitle);
86
+ * myPanel.add(myCta);
87
+ *
88
+ * const tracking = gravityAdTracking({
89
+ * renderer,
90
+ * input,
91
+ * panel: myPanel,
92
+ * clickTargets: [myTitle, myCta],
93
+ * });
94
+ *
95
+ * // When you receive an ad:
96
+ * tracking.setAd(ads[0]);
97
+ *
98
+ * // To hide:
99
+ * tracking.clear();
100
+ * ```
101
+ */
102
+ declare function gravityAdTracking(options: GravityAdTrackingOptions): GravityAdTracking;
103
+ interface GravityAdCardStyleProps {
104
+ borderColor?: string;
105
+ backgroundColor?: string;
106
+ }
107
+ interface GravityAdCardOptions {
108
+ /** OpenTUI renderer instance. */
109
+ renderer: any;
110
+ /** OpenTUI `InputRenderable` — focus returns here when hover ends. */
111
+ input: any;
112
+ /**
113
+ * Layout variant.
114
+ * - `'card'` (default): bordered card with title, body, CTA, and "Ad" label.
115
+ * - `'minimal'`: no border or background — just text + tracking.
116
+ */
117
+ variant?: 'card' | 'minimal';
118
+ /** Called when an impression pixel fires. */
119
+ onImpression?: (ad: Ad) => void;
120
+ /** Called when the user clicks the ad (before the browser opens). */
121
+ onClick?: (ad: Ad) => void;
122
+ /** Style overrides for the outer panel (border, background). */
123
+ panel?: GravityAdCardStyleProps;
124
+ /** Style overrides for the ad body text. */
125
+ text?: {
126
+ fg?: string;
127
+ };
128
+ /** Style overrides for the CTA text. */
129
+ cta?: {
130
+ fg?: string;
131
+ };
132
+ /** Style overrides for the "Ad" label. */
133
+ label?: {
134
+ fg?: string;
135
+ };
136
+ /**
137
+ * Hover state overrides. The default ships with a visible hover
138
+ * affordance (brighter border + lighter background) because it
139
+ * directly impacts click-through rate.
140
+ */
141
+ hoverPanel?: GravityAdCardStyleProps;
142
+ }
143
+ interface GravityAdCard {
144
+ /** The root renderable — add this to your render tree. */
145
+ panel: any;
146
+ /** Populate the card with an ad and activate tracking. Pass `null` to hide. */
147
+ showAd: (ad: Ad | null) => void;
148
+ /** Hide the card and reset all state. */
149
+ clear: () => void;
150
+ /** Direct access to inner renderables for post-creation mutation. */
151
+ elements: {
152
+ text: any;
153
+ cta: any;
154
+ label: any;
155
+ };
156
+ /** The underlying tracking instance. */
157
+ tracking: GravityAdTracking;
158
+ }
159
+ /**
160
+ * Create a ready-to-use Gravity ad card for OpenTUI.
161
+ *
162
+ * Handles layout creation, content population, height calculation,
163
+ * impression firing, click-to-open-browser, and hover affordance.
164
+ * Override any visual property via the options or mutate the returned
165
+ * `elements` directly — no lock-in.
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * import { createGravityAdCard } from '@gravity-ai/api/opentui';
170
+ *
171
+ * const adCard = createGravityAdCard({ renderer, input });
172
+ * root.add(adCard.panel);
173
+ *
174
+ * // When you receive an ad:
175
+ * adCard.showAd(ads[0]);
176
+ *
177
+ * // To hide:
178
+ * adCard.clear();
179
+ * ```
180
+ */
181
+ declare function createGravityAdCard(options: GravityAdCardOptions): GravityAdCard;
182
+
183
+ export { type GravityAdCard, type GravityAdCardOptions, type GravityAdCardStyleProps, type GravityAdTracking, type GravityAdTrackingOptions, createGravityAdCard, gravityAdTracking };
@@ -0,0 +1,338 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // opentui.ts
21
+ var opentui_exports = {};
22
+ __export(opentui_exports, {
23
+ createGravityAdCard: () => createGravityAdCard,
24
+ gravityAdTracking: () => gravityAdTracking
25
+ });
26
+ module.exports = __toCommonJS(opentui_exports);
27
+ var import_child_process = require("child_process");
28
+ function openUrl(url) {
29
+ if (!url) return;
30
+ try {
31
+ let child;
32
+ if (process.platform === "darwin") {
33
+ child = (0, import_child_process.execFile)("open", [url]);
34
+ } else if (process.platform === "win32") {
35
+ child = (0, import_child_process.execFile)("rundll32", ["url.dll,FileProtocolHandler", url]);
36
+ } else {
37
+ child = (0, import_child_process.execFile)("xdg-open", [url]);
38
+ }
39
+ child.on("error", () => {
40
+ });
41
+ } catch {
42
+ }
43
+ }
44
+ function fireImpression(impUrl) {
45
+ try {
46
+ fetch(impUrl).catch(() => {
47
+ });
48
+ } catch {
49
+ }
50
+ }
51
+ function gravityAdTracking(options) {
52
+ const {
53
+ renderer,
54
+ input,
55
+ panel,
56
+ clickTargets = [],
57
+ onImpression,
58
+ onClick,
59
+ onHoverIn,
60
+ onHoverOut
61
+ } = options;
62
+ let activeAd = null;
63
+ let activeUrl = "";
64
+ let hovered = false;
65
+ let _impressionFired = false;
66
+ function setHover(next) {
67
+ if (!activeUrl) return;
68
+ if (hovered === next) return;
69
+ hovered = next;
70
+ if (next && activeAd) {
71
+ if (onHoverIn) {
72
+ onHoverIn(activeAd);
73
+ } else {
74
+ input.blur();
75
+ renderer.setCursorStyle({ cursor: "pointer", style: "block", blinking: false });
76
+ renderer.setMousePointer("pointer");
77
+ }
78
+ } else {
79
+ if (onHoverOut) {
80
+ onHoverOut();
81
+ } else {
82
+ renderer.setCursorStyle({ cursor: "default", style: "block", blinking: false });
83
+ renderer.setMousePointer("default");
84
+ input.focus();
85
+ }
86
+ }
87
+ renderer.requestRender();
88
+ }
89
+ function handleClick() {
90
+ if (!activeUrl || !activeAd) return;
91
+ onClick?.(activeAd);
92
+ openUrl(activeUrl);
93
+ renderer.requestRender();
94
+ }
95
+ function wireMouse(target) {
96
+ target.onMouseOver = () => setHover(true);
97
+ target.onMouseOut = () => setHover(false);
98
+ target.onMouseMove = () => setHover(true);
99
+ target.onMouseDown = () => handleClick();
100
+ }
101
+ wireMouse(panel);
102
+ for (const target of clickTargets) {
103
+ wireMouse(target);
104
+ }
105
+ function clear() {
106
+ if (hovered) {
107
+ if (onHoverOut) {
108
+ onHoverOut();
109
+ } else {
110
+ renderer.setCursorStyle({ cursor: "default", style: "block", blinking: false });
111
+ renderer.setMousePointer("default");
112
+ input.focus();
113
+ }
114
+ }
115
+ activeAd = null;
116
+ activeUrl = "";
117
+ hovered = false;
118
+ _impressionFired = false;
119
+ panel.visible = false;
120
+ }
121
+ function setAd(ad) {
122
+ if (!ad) {
123
+ clear();
124
+ return;
125
+ }
126
+ if (hovered) {
127
+ if (onHoverOut) {
128
+ onHoverOut();
129
+ } else {
130
+ renderer.setCursorStyle({ cursor: "default", style: "block", blinking: false });
131
+ renderer.setMousePointer("default");
132
+ input.focus();
133
+ }
134
+ }
135
+ activeAd = ad;
136
+ activeUrl = ad.clickUrl || ad.url || "";
137
+ hovered = false;
138
+ _impressionFired = false;
139
+ panel.visible = true;
140
+ if (ad.impUrl) {
141
+ fireImpression(ad.impUrl);
142
+ _impressionFired = true;
143
+ onImpression?.(ad);
144
+ }
145
+ }
146
+ return {
147
+ setAd,
148
+ clear,
149
+ get ad() {
150
+ return activeAd;
151
+ },
152
+ get impressionFired() {
153
+ return _impressionFired;
154
+ }
155
+ };
156
+ }
157
+ var CARD_DEFAULTS = {
158
+ panel: {
159
+ borderStyle: "single",
160
+ borderColor: "#3F3F46",
161
+ backgroundColor: "#09090B"
162
+ },
163
+ hoverPanel: {
164
+ borderColor: "#71717A",
165
+ backgroundColor: "#18181B"
166
+ },
167
+ text: { fg: "#A1A1AA" },
168
+ cta: { fg: "#2563EB" },
169
+ label: { fg: "#71717A" }
170
+ };
171
+ function wrapLineCount(text, width) {
172
+ const value = (text || "").trim();
173
+ if (!value) return 0;
174
+ const segments = value.split("\n");
175
+ let totalLines = 0;
176
+ for (const segment of segments) {
177
+ const trimmed = segment.trim();
178
+ if (!trimmed) {
179
+ totalLines++;
180
+ continue;
181
+ }
182
+ const words = trimmed.split(/\s+/);
183
+ let lines = 1;
184
+ let current = 0;
185
+ for (const word of words) {
186
+ if (current === 0) {
187
+ current = word.length;
188
+ } else if (current + 1 + word.length <= width) {
189
+ current += 1 + word.length;
190
+ } else {
191
+ lines++;
192
+ current = word.length;
193
+ }
194
+ }
195
+ totalLines += lines;
196
+ }
197
+ return totalLines;
198
+ }
199
+ function createGravityAdCard(options) {
200
+ const {
201
+ renderer,
202
+ input,
203
+ variant = "card",
204
+ onImpression,
205
+ onClick
206
+ } = options;
207
+ const panelStyle = { ...CARD_DEFAULTS.panel, ...options.panel };
208
+ const hoverStyle = { ...CARD_DEFAULTS.hoverPanel, ...options.hoverPanel };
209
+ const textStyle = { ...CARD_DEFAULTS.text, ...options.text };
210
+ const ctaStyle = { ...CARD_DEFAULTS.cta, ...options.cta };
211
+ const labelStyle = { ...CARD_DEFAULTS.label, ...options.label };
212
+ let BoxRenderable;
213
+ let TextRenderable;
214
+ try {
215
+ const core = require("@opentui/core");
216
+ BoxRenderable = core.BoxRenderable;
217
+ TextRenderable = core.TextRenderable;
218
+ } catch {
219
+ throw new Error(
220
+ "createGravityAdCard() requires @opentui/core as a peer dependency. Install it with: bun add @opentui/core"
221
+ );
222
+ }
223
+ const isCard = variant === "card";
224
+ const adPanel = new BoxRenderable(renderer, {
225
+ width: "100%",
226
+ visible: false,
227
+ flexDirection: "column",
228
+ ...isCard ? {
229
+ border: true,
230
+ borderStyle: panelStyle.borderStyle,
231
+ borderColor: panelStyle.borderColor,
232
+ backgroundColor: panelStyle.backgroundColor,
233
+ paddingLeft: 2,
234
+ paddingRight: 2
235
+ } : {
236
+ border: false,
237
+ paddingLeft: 1
238
+ }
239
+ });
240
+ const adLabel = new TextRenderable(renderer, {
241
+ position: "absolute",
242
+ top: 0,
243
+ right: isCard ? 2 : 0,
244
+ wrapMode: "none",
245
+ content: "",
246
+ fg: labelStyle.fg
247
+ });
248
+ const adText = new TextRenderable(renderer, {
249
+ width: "100%",
250
+ wrapMode: "word",
251
+ content: "",
252
+ fg: textStyle.fg
253
+ });
254
+ const adCta = new TextRenderable(renderer, {
255
+ wrapMode: "none",
256
+ content: "",
257
+ fg: ctaStyle.fg
258
+ });
259
+ adPanel.add(adLabel);
260
+ adPanel.add(adText);
261
+ adPanel.add(adCta);
262
+ function applyHover(hovered) {
263
+ if (!isCard) return;
264
+ if (hovered) {
265
+ adPanel.borderColor = hoverStyle.borderColor;
266
+ adPanel.backgroundColor = hoverStyle.backgroundColor;
267
+ } else {
268
+ adPanel.borderColor = panelStyle.borderColor;
269
+ adPanel.backgroundColor = panelStyle.backgroundColor;
270
+ }
271
+ }
272
+ const tracking = gravityAdTracking({
273
+ renderer,
274
+ input,
275
+ panel: adPanel,
276
+ clickTargets: [adLabel, adText, adCta],
277
+ onImpression,
278
+ onClick,
279
+ onHoverIn: () => {
280
+ applyHover(true);
281
+ input.blur();
282
+ renderer.setCursorStyle({ cursor: "pointer", style: "block", blinking: false });
283
+ renderer.setMousePointer("pointer");
284
+ },
285
+ onHoverOut: () => {
286
+ applyHover(false);
287
+ renderer.setCursorStyle({ cursor: "default", style: "block", blinking: false });
288
+ renderer.setMousePointer("default");
289
+ input.focus();
290
+ }
291
+ });
292
+ function clear() {
293
+ tracking.clear();
294
+ adLabel.content = "";
295
+ adText.content = "";
296
+ adCta.content = "";
297
+ applyHover(false);
298
+ }
299
+ function showAd(ad) {
300
+ if (!ad) {
301
+ clear();
302
+ return;
303
+ }
304
+ const title = ad.title || ad.brandName || "Sponsored";
305
+ const body = ad.adText || "";
306
+ const cta = ad.cta || "";
307
+ adLabel.content = "Ad";
308
+ adText.content = body ? `${title}
309
+ ${body}` : title;
310
+ adCta.content = cta;
311
+ const contentWidth = Math.max(24, (process.stdout.columns || 80) - 10);
312
+ const titleLines = wrapLineCount(title, contentWidth);
313
+ const bodyLines = wrapLineCount(body, contentWidth);
314
+ const ctaLines = cta ? 1 : 0;
315
+ const borderPad = isCard ? 2 : 0;
316
+ adText.height = titleLines + bodyLines;
317
+ adPanel.height = titleLines + bodyLines + ctaLines + borderPad;
318
+ applyHover(false);
319
+ tracking.setAd(ad);
320
+ renderer.requestRender();
321
+ }
322
+ return {
323
+ panel: adPanel,
324
+ showAd,
325
+ clear,
326
+ elements: {
327
+ text: adText,
328
+ cta: adCta,
329
+ label: adLabel
330
+ },
331
+ tracking
332
+ };
333
+ }
334
+ // Annotate the CommonJS export names for ESM import in node:
335
+ 0 && (module.exports = {
336
+ createGravityAdCard,
337
+ gravityAdTracking
338
+ });