@simula/ads 1.2.0 → 1.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.
- package/README.md +51 -306
- package/dist/components/GameCard.d.ts +11 -0
- package/dist/components/GameCard.d.ts.map +1 -0
- package/dist/components/GameGrid.d.ts +12 -0
- package/dist/components/GameGrid.d.ts.map +1 -0
- package/dist/components/GameIframe.d.ts +9 -0
- package/dist/components/GameIframe.d.ts.map +1 -0
- package/dist/components/MiniGameMenu.d.ts +4 -0
- package/dist/components/MiniGameMenu.d.ts.map +1 -0
- package/dist/components/inChatAd/InChatAdSlot.d.ts +4 -0
- package/dist/components/inChatAd/InChatAdSlot.d.ts.map +1 -0
- package/dist/components/miniGame/GameCard.d.ts +11 -0
- package/dist/components/miniGame/GameCard.d.ts.map +1 -0
- package/dist/components/miniGame/GameGrid.d.ts +12 -0
- package/dist/components/miniGame/GameGrid.d.ts.map +1 -0
- package/dist/components/miniGame/GameIframe.d.ts +9 -0
- package/dist/components/miniGame/GameIframe.d.ts.map +1 -0
- package/dist/components/miniGame/MiniGameMenu.d.ts +4 -0
- package/dist/components/miniGame/MiniGameMenu.d.ts.map +1 -0
- package/dist/components/miniGame/mockGames.d.ts +3 -0
- package/dist/components/miniGame/mockGames.d.ts.map +1 -0
- package/dist/components/mockGames.d.ts +3 -0
- package/dist/components/mockGames.d.ts.map +1 -0
- package/dist/components/sponsoredSuggestions/SponsoredSuggestions.d.ts +4 -0
- package/dist/components/sponsoredSuggestions/SponsoredSuggestions.d.ts.map +1 -0
- package/dist/index.d.ts +120 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2089 -205
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2042 -162
- package/dist/index.mjs.map +1 -1
- package/dist/types/SimulaProvider.d.ts +5 -0
- package/dist/types/SimulaProvider.d.ts.map +1 -0
- package/dist/types/components/inChatAd/InChatAdSlot.d.ts +4 -0
- package/dist/types/components/inChatAd/InChatAdSlot.d.ts.map +1 -0
- package/dist/types/components/miniGame/GameCard.d.ts +12 -0
- package/dist/types/components/miniGame/GameCard.d.ts.map +1 -0
- package/dist/types/components/miniGame/GameGrid.d.ts +13 -0
- package/dist/types/components/miniGame/GameGrid.d.ts.map +1 -0
- package/dist/types/components/miniGame/GameIframe.d.ts +21 -0
- package/dist/types/components/miniGame/GameIframe.d.ts.map +1 -0
- package/dist/types/components/miniGame/MiniGameMenu.d.ts +4 -0
- package/dist/types/components/miniGame/MiniGameMenu.d.ts.map +1 -0
- package/dist/types/components/miniGame/mockGames.d.ts +3 -0
- package/dist/types/components/miniGame/mockGames.d.ts.map +1 -0
- package/dist/types/components/nativeBanner/NativeBanner.d.ts +4 -0
- package/dist/types/components/nativeBanner/NativeBanner.d.ts.map +1 -0
- package/dist/types/components/nativeBanner/NativeBannerTest.d.ts +4 -0
- package/dist/types/components/nativeBanner/NativeBannerTest.d.ts.map +1 -0
- package/dist/types/components/nativeBanner/RadialLinesSpinner.d.ts +7 -0
- package/dist/types/components/nativeBanner/RadialLinesSpinner.d.ts.map +1 -0
- package/dist/types/components/nativeBanner/index.d.ts +3 -0
- package/dist/types/components/nativeBanner/index.d.ts.map +1 -0
- package/dist/types/components/sponsoredSuggestions/SponsoredSuggestions.d.ts +4 -0
- package/dist/types/components/sponsoredSuggestions/SponsoredSuggestions.d.ts.map +1 -0
- package/dist/types/hooks/useAssetLoadDetection.d.ts +14 -0
- package/dist/types/hooks/useAssetLoadDetection.d.ts.map +1 -0
- package/dist/types/hooks/useBotDetection.d.ts +3 -0
- package/dist/types/hooks/useBotDetection.d.ts.map +1 -0
- package/dist/types/hooks/useDebounce.d.ts +2 -0
- package/dist/types/hooks/useDebounce.d.ts.map +1 -0
- package/dist/types/hooks/useOMIDViewability.d.ts +24 -0
- package/dist/types/hooks/useOMIDViewability.d.ts.map +1 -0
- package/dist/types/hooks/useViewability.d.ts +6 -0
- package/dist/types/hooks/useViewability.d.ts.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types.d.ts +189 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils/api.d.ts +62 -0
- package/dist/types/utils/api.d.ts.map +1 -0
- package/dist/types/utils/colorThemes.d.ts +21 -0
- package/dist/types/utils/colorThemes.d.ts.map +1 -0
- package/dist/types/utils/styling.d.ts +4 -0
- package/dist/types/utils/styling.d.ts.map +1 -0
- package/dist/types/utils/validation.d.ts +27 -0
- package/dist/types/utils/validation.d.ts.map +1 -0
- package/dist/types.d.ts +50 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/api.d.ts +2 -2
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/styling.d.ts +4 -3
- package/dist/utils/styling.d.ts.map +1 -1
- package/dist/utils/validation.d.ts +2 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
# Simula Ad SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Overview
|
|
4
4
|
|
|
5
|
-
Simula
|
|
5
|
+
The Simula Ad SDK enables React developers to monetize conversational AI applications with contextually relevant, non-intrusive ads. The SDK provides in-chat ad placements and native banner ads that integrate naturally with chat interfaces.
|
|
6
|
+
|
|
7
|
+
### Key Features
|
|
8
|
+
|
|
9
|
+
- **Contextual Targeting** - AI-powered ad matching based on conversation content
|
|
10
|
+
- **In-Chat Ad Slots** - Ad placements that blend seamlessly into chat UIs
|
|
11
|
+
- **Native Banner Ads** - Flexible ad placements for feeds and content surfaces
|
|
12
|
+
- **MRC-Compliant Viewability** - Industry-standard impression tracking
|
|
13
|
+
- **Built-in A/B Testing** - Optimize ad performance automatically
|
|
6
14
|
|
|
7
15
|
---
|
|
8
16
|
|
|
9
|
-
##
|
|
17
|
+
## Installation
|
|
10
18
|
|
|
11
19
|
```bash
|
|
12
20
|
npm install @simula/ads
|
|
@@ -14,343 +22,80 @@ npm install @simula/ads
|
|
|
14
22
|
|
|
15
23
|
---
|
|
16
24
|
|
|
17
|
-
##
|
|
25
|
+
## Quick Start
|
|
18
26
|
|
|
19
|
-
|
|
27
|
+
### 1. Provider Setup
|
|
20
28
|
|
|
21
|
-
|
|
22
|
-
2. **Insert** `<InChatAdSlot />` where you want ads
|
|
29
|
+
Wrap your chat/conversation component with `SimulaProvider` to initialize the SDK:
|
|
23
30
|
|
|
24
31
|
```tsx
|
|
25
|
-
import { SimulaProvider
|
|
26
|
-
|
|
27
|
-
function App() {
|
|
28
|
-
return (
|
|
29
|
-
<div>
|
|
30
|
-
<Header />
|
|
31
|
-
<ChatInterface /> {/* SimulaProvider wraps individual conversations */}
|
|
32
|
-
</div>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
32
|
+
import { SimulaProvider } from "@simula/ads";
|
|
35
33
|
|
|
36
34
|
function ChatInterface() {
|
|
37
|
-
const [messages, setMessages] = useState([]);
|
|
38
|
-
|
|
39
35
|
return (
|
|
40
|
-
<SimulaProvider
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<InChatAdSlot
|
|
47
|
-
messages={messages.slice(0, i + 1)}
|
|
48
|
-
theme={{ mode: "light", accent: "blue" }}
|
|
49
|
-
/>
|
|
50
|
-
)}
|
|
51
|
-
</div>
|
|
52
|
-
))}
|
|
53
|
-
</div>
|
|
54
|
-
</SimulaProvider>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## 🧩 Components
|
|
62
|
-
|
|
63
|
-
### `SimulaProvider`
|
|
64
|
-
|
|
65
|
-
Initializes the SDK and manages session state.
|
|
66
|
-
|
|
67
|
-
| Prop | Type | Required | Default | Description |
|
|
68
|
-
| --------------- | ----------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
69
|
-
| `apiKey` | `string` | ✅ | — | Your Simula API key from the [dashboard](https://simula.ad) |
|
|
70
|
-
| `children` | `ReactNode` | ✅ | — | Your app components |
|
|
71
|
-
| `devMode` | `boolean` | ❌ | `false` | Enables development mode |
|
|
72
|
-
| `primaryUserID` | `string` | ❌ | — | Publisher-provided user identifier. **Recommended** for consistent tracking across devices and sessions. |
|
|
73
|
-
|
|
74
|
-
```tsx
|
|
75
|
-
// Wrap individual chat/conversation components
|
|
76
|
-
function ChatInterface({ conversationId }) {
|
|
77
|
-
const [messages, setMessages] = useState([]);
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<SimulaProvider apiKey="SIMULA_xxx">
|
|
36
|
+
<SimulaProvider
|
|
37
|
+
apiKey="SIMULA_xxx"
|
|
38
|
+
primaryUserID="user-123" // Optional: User ID for better ad targeting
|
|
39
|
+
hasPrivacyConsent={true} // Optional: Privacy consent flag
|
|
40
|
+
devMode={false} // Optional: Enable dev mode for testing
|
|
41
|
+
>
|
|
81
42
|
{/* Your chat UI */}
|
|
82
43
|
</SimulaProvider>
|
|
83
44
|
);
|
|
84
45
|
}
|
|
85
|
-
|
|
86
|
-
// For authenticated apps with user tracking (recommended)
|
|
87
|
-
function ChatInterface({ conversationId, userId }) {
|
|
88
|
-
const [messages, setMessages] = useState([]);
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<SimulaProvider apiKey="SIMULA_xxx" primaryUserID={userId}>
|
|
92
|
-
{/* Your chat UI */}
|
|
93
|
-
</SimulaProvider>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
> **Provider Best Practices**
|
|
99
|
-
>
|
|
100
|
-
> * **Wrap individual conversations** – Place `SimulaProvider` around each chat or character component so that each conversation is treated as a separate session. This provides better ad targeting based on conversation context.
|
|
101
|
-
>
|
|
102
|
-
> * **Provide `primaryUserID`** – Use your user's ID to enable cross-device tracking and cookie-independent identification. This approach delivers:
|
|
103
|
-
> * **Higher CPMs** – Better user attribution leads to more valuable ad placements
|
|
104
|
-
> * **Frequency capping** – Prevents oversending ads to the same user
|
|
105
|
-
> * **Better ad experience** – Optimized targeting based on consistent user history
|
|
106
|
-
> * **Accurate analytics** – Reliable performance metrics across devices and sessions
|
|
107
|
-
>
|
|
108
|
-
> * **One provider per conversation** – Don't nest multiple `SimulaProvider` instances. Each conversation/chat component should have its own provider at the top level.
|
|
109
|
-
>
|
|
110
|
-
> For anonymous users, you can still use `SimulaProvider` without `primaryUserID`, but tracking will rely on cookies.
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
### `InChatAdSlot`
|
|
115
|
-
|
|
116
|
-
Displays an ad based on conversation context.
|
|
117
|
-
|
|
118
|
-
| Prop | Type | Required | Default | Description |
|
|
119
|
-
| -------------- | ---------------------- | -------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
120
|
-
| `messages` | `Message[]` | ✅ | — | Array of `{ role, content }`; pass recent conversation (e.g. last 6 turns). |
|
|
121
|
-
| `trigger` | `Promise<any>` | ❌ | Fires immediately on viewability | Promise to await before fetching the ad (e.g. LLM call). |
|
|
122
|
-
| `theme` | `SimulaTheme` | ❌ | `{ mode: 'auto', width: 'auto', accent: ['neutral','image'], font: 'sans-serif', cornerRadius: 8 }` | Customize ad appearance (see Theme Options). Arrays trigger A/B testing. |
|
|
123
|
-
| `charDesc` | `string` | ❌ | `undefined` | Character description for additional context to improve ad targeting. |
|
|
124
|
-
| `debounceMs` | `number` | ❌ | `0` | Delay in milliseconds before fetching. |
|
|
125
|
-
| `onImpression` | `(ad: AdData) => void` | ❌ | `undefined` | Callback when ad is viewable (50% visible for ≥1s). |
|
|
126
|
-
| `onClick` | `(ad: AdData) => void` | ❌ | `undefined` | Callback when ad is clicked. |
|
|
127
|
-
| `onError` | `(err: Error) => void` | ❌ | `undefined` | Callback when ad fails or no-fill occurs. |
|
|
128
|
-
|
|
129
|
-
**Behavior:**
|
|
130
|
-
|
|
131
|
-
* Fetches **once** per slot (static)
|
|
132
|
-
* Triggers on **viewport visibility** (50% visible)
|
|
133
|
-
* Includes built-in **bot protection**
|
|
134
|
-
* Tracks impressions **MRC-compliantly**
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## 🎨 Theme Options
|
|
139
|
-
|
|
140
|
-
```ts
|
|
141
|
-
interface SimulaTheme {
|
|
142
|
-
mode?: "light" | "dark" | "auto"; // default: "auto"
|
|
143
|
-
accent?: AccentOption | AccentOption[]; // default: ["neutral", "image"] (A/B tested)
|
|
144
|
-
font?: FontOption | FontOption[]; // default: "sans-serif"
|
|
145
|
-
width?: number | string; // default: "auto" (min 320px)
|
|
146
|
-
cornerRadius?: number; // default: 8
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**Modes:** `light` | `dark` | `auto`
|
|
151
|
-
**Accents:**
|
|
152
|
-
`blue`, `red`, `green`, `yellow`, `purple`, `pink`, `orange`, `neutral`, `gray`, `tan`, `transparent`, `image`
|
|
153
|
-
**Fonts:** `sans-serif`, `serif`, `monospace`
|
|
154
|
-
|
|
155
|
-
> **Height:** fixed at **265px**
|
|
156
|
-
> **Width:** min **320px**, accepts px/%, or `auto`
|
|
157
|
-
|
|
158
|
-
> **A/B Testing:**
|
|
159
|
-
> When you pass an **array** (e.g., `accent: ['blue', 'green', 'purple']`), Simula will **automatically A/B test** across the provided options—colors or fonts—and **optimize over time for the best-performing variant**.
|
|
160
|
-
>
|
|
161
|
-
> **💡 We strongly encourage adding the `"image"` option for accent** (e.g., `accent: ['blue', 'image']`)
|
|
162
|
-
|
|
163
|
-
```tsx
|
|
164
|
-
// Default mode (auto)
|
|
165
|
-
<InChatAdSlot messages={messages} />
|
|
166
|
-
|
|
167
|
-
// Light mode
|
|
168
|
-
<InChatAdSlot messages={messages} theme={{ mode: "light", accent: "blue" }} />
|
|
169
|
-
|
|
170
|
-
// Dark mode with custom width
|
|
171
|
-
<InChatAdSlot
|
|
172
|
-
messages={messages}
|
|
173
|
-
theme={{ mode: "dark", accent: "purple", width: 600, cornerRadius: 12 }}
|
|
174
|
-
/>
|
|
175
|
-
|
|
176
|
-
// A/B testing (recommended: include "image" for best performance)
|
|
177
|
-
<InChatAdSlot
|
|
178
|
-
messages={messages}
|
|
179
|
-
theme={{
|
|
180
|
-
accent: ["blue", "green", "image"], // A/B test colors - include "image" for best CPM
|
|
181
|
-
font: ["sans-serif", "serif"], // A/B test fonts
|
|
182
|
-
width: "100%"
|
|
183
|
-
}}
|
|
184
|
-
/>
|
|
185
46
|
```
|
|
186
47
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
## 💬 Integration Example
|
|
48
|
+
### 2. Component Integration
|
|
190
49
|
|
|
191
|
-
|
|
50
|
+
Add components where you want ads to appear:
|
|
192
51
|
|
|
52
|
+
**In-Chat Ads:**
|
|
193
53
|
```tsx
|
|
194
|
-
import {
|
|
195
|
-
import { SimulaProvider, InChatAdSlot } from "@simula/ads";
|
|
196
|
-
import OpenAI from "openai";
|
|
197
|
-
|
|
198
|
-
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
54
|
+
import { InChatAdSlot } from "@simula/ads";
|
|
199
55
|
|
|
200
|
-
export default function App() {
|
|
201
|
-
return (
|
|
202
|
-
<div>
|
|
203
|
-
<Header />
|
|
204
|
-
<ChatApp /> {/* Each conversation has its own SimulaProvider */}
|
|
205
|
-
</div>
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
function ChatApp() {
|
|
210
|
-
const [messages, setMessages] = useState([]);
|
|
211
|
-
const [input, setInput] = useState("");
|
|
212
|
-
const [loading, setLoading] = useState(false);
|
|
213
|
-
|
|
214
|
-
async function sendMessage() {
|
|
215
|
-
if (!input.trim()) return;
|
|
216
|
-
|
|
217
|
-
const userMessage = { role: "user", content: input.trim() };
|
|
218
|
-
const newMessages = [...messages, userMessage];
|
|
219
|
-
setMessages(newMessages);
|
|
220
|
-
setInput("");
|
|
221
|
-
setLoading(true);
|
|
222
|
-
|
|
223
|
-
try {
|
|
224
|
-
const llmPromise = client.chat.completions.create({
|
|
225
|
-
model: "gpt-4o-mini",
|
|
226
|
-
messages: newMessages,
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
const res = await llmPromise;
|
|
230
|
-
const reply = res.choices[0].message;
|
|
231
|
-
|
|
232
|
-
setMessages((prev) => [...prev, { ...reply, llmPromise }]);
|
|
233
|
-
} finally {
|
|
234
|
-
setLoading(false);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return (
|
|
239
|
-
<SimulaProvider apiKey="SIMULA_xxx">
|
|
240
|
-
<div className="chat">
|
|
241
|
-
{messages.map((msg, i) => (
|
|
242
|
-
<div key={i}>
|
|
243
|
-
<p><strong>{msg.role}:</strong> {msg.content}</p>
|
|
244
|
-
|
|
245
|
-
{msg.role === "assistant" && (
|
|
246
|
-
<InChatAdSlot
|
|
247
|
-
key={`adslot-${i}`} // ✅ Required if rendering in a list
|
|
248
|
-
trigger={msg.llmPromise} // default: fires immediately if not provided
|
|
249
|
-
messages={messages.slice(0, i + 1)}
|
|
250
|
-
theme={{ mode: "light", accent: "blue", width: "auto" }}
|
|
251
|
-
/>
|
|
252
|
-
)}
|
|
253
|
-
</div>
|
|
254
|
-
))}
|
|
255
|
-
|
|
256
|
-
<input
|
|
257
|
-
value={input}
|
|
258
|
-
onChange={(e) => setInput(e.target.value)}
|
|
259
|
-
onKeyDown={(e) => e.key === "Enter" && sendMessage()}
|
|
260
|
-
/>
|
|
261
|
-
<button onClick={sendMessage} disabled={loading}>Send</button>
|
|
262
|
-
</div>
|
|
263
|
-
</SimulaProvider>
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
> **Tips:**
|
|
269
|
-
>
|
|
270
|
-
> * **Wrap `SimulaProvider` around the chat component** – This treats each conversation as a separate session for better ad targeting.
|
|
271
|
-
> * Use `key` prop when `<InChatAdSlot />` is rendered inside a list or dynamic loop.
|
|
272
|
-
> * The `trigger` prop waits for the LLM response before fetching ads. If omitted, the ad fetches immediately when viewable.
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## 🔑 Features
|
|
277
|
-
|
|
278
|
-
* **Contextual Targeting** – AI-powered ad matching to conversation content
|
|
279
|
-
* **Bot Protection** – via [@fingerprintjs/botd](https://github.com/fingerprintjs/botd)
|
|
280
|
-
* **MRC-Compliant Viewability** – 50% visible for ≥1s
|
|
281
|
-
* **Responsive** – Flexible widths with enforced minimums
|
|
282
|
-
* **Static Fetch** – Each slot fetches once and stays fixed
|
|
283
|
-
* **Session Management** – Automatic
|
|
284
|
-
* **Robust Error Handling** – Graceful degradation & callbacks
|
|
285
|
-
* **TypeScript Support** – Built-in type definitions
|
|
286
|
-
* **Built-in A/B Testing** – Test multiple colors or fonts by passing arrays and let Simula optimize performance over time
|
|
287
|
-
|
|
288
|
-
---
|
|
289
|
-
|
|
290
|
-
## ⚙️ Advanced Usage
|
|
291
|
-
|
|
292
|
-
### Event Handlers
|
|
293
|
-
|
|
294
|
-
```tsx
|
|
295
56
|
<InChatAdSlot
|
|
296
|
-
messages={messages}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
onError={(err) => console.error("Ad error:", err)}
|
|
57
|
+
messages={messages.slice(0, i + 1)}
|
|
58
|
+
theme={{ mode: "light", accent: "blue" }}
|
|
59
|
+
onImpression={(ad) => console.log("Impression:", ad.id)}
|
|
60
|
+
onError={(err) => console.error("Ad error:", err)}
|
|
300
61
|
/>
|
|
301
62
|
```
|
|
302
63
|
|
|
303
|
-
|
|
304
|
-
|
|
64
|
+
**Native Banner Ads:**
|
|
305
65
|
```tsx
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
66
|
+
import { NativeBanner } from "@simula/ads";
|
|
67
|
+
|
|
68
|
+
<NativeBanner
|
|
69
|
+
slot="feed"
|
|
70
|
+
position={index}
|
|
71
|
+
context={{
|
|
72
|
+
searchTerm: "cooking recipes",
|
|
73
|
+
tags: ["food", "cooking"],
|
|
74
|
+
}}
|
|
75
|
+
width="100%"
|
|
76
|
+
onImpression={(ad) => console.log("Impression:", ad.id)}
|
|
77
|
+
onError={(err) => console.error("Error:", err)}
|
|
309
78
|
/>
|
|
310
79
|
```
|
|
311
80
|
|
|
312
81
|
---
|
|
313
82
|
|
|
314
|
-
##
|
|
315
|
-
|
|
316
|
-
```ts
|
|
317
|
-
import type {
|
|
318
|
-
SimulaTheme,
|
|
319
|
-
Message,
|
|
320
|
-
AdData,
|
|
321
|
-
InChatAdSlotProps,
|
|
322
|
-
SimulaProviderProps
|
|
323
|
-
} from "@simula/ads";
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
---
|
|
83
|
+
## Documentation
|
|
327
84
|
|
|
328
|
-
|
|
85
|
+
For complete API reference, integration guides, and examples:
|
|
329
86
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
* Support: **[admin@simula.ad](mailto:admin@simula.ad)**
|
|
87
|
+
- **[InChatAdSlot Documentation](https://simula-ad.notion.site/?pvs=73)**
|
|
88
|
+
- **[NativeBanner Documentation](https://simula-ad.notion.site/Komiko-Simula-Integration-2cbaf70f6f0d80338ddcd2efbbe5d3d7?source=copy_link)**
|
|
333
89
|
|
|
334
90
|
---
|
|
335
91
|
|
|
336
|
-
##
|
|
92
|
+
## Support
|
|
337
93
|
|
|
338
|
-
|
|
94
|
+
- **Website:** [simula.ad](https://simula.ad)
|
|
95
|
+
- **Email:** [admin@simula.ad](mailto:admin@simula.ad)
|
|
339
96
|
|
|
340
97
|
---
|
|
341
98
|
|
|
342
|
-
##
|
|
99
|
+
## License
|
|
343
100
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
Visual examples of all available ad formats across mobile and desktop:
|
|
347
|
-
|
|
348
|
-
| Format | Mobile | Desktop |
|
|
349
|
-
|--------|--------|---------|
|
|
350
|
-
| **tips** | <img src="./assets/tips_mobile.png" width="200" alt="Tips format on mobile" /> | <img src="./assets/tips_desktop.png" width="400" alt="Tips format on desktop" /> |
|
|
351
|
-
| **interactive** | <img src="./assets/interactive_mobile.png" width="200" alt="Interactive format on mobile" /> | <img src="./assets/interactive_desktop.png" width="400" alt="Interactive format on desktop" /> |
|
|
352
|
-
| **suggestions** | <img src="./assets/suggestions_mobile.png" width="200" alt="Suggestions format on mobile" /> | <img src="./assets/suggestions_desktop.png" width="400" alt="Suggestions format on desktop" /> |
|
|
353
|
-
| **text** | <img src="./assets/text_mobile.png" width="200" alt="Text format on mobile" /> | <img src="./assets/text_desktop.png" width="400" alt="Text format on desktop" /> |
|
|
354
|
-
| **highlight** | <img src="./assets/highlight_mobile.png" width="200" alt="Highlight format on mobile" /> | <img src="./assets/highlight_desktop.png" width="400" alt="Highlight format on desktop" /> |
|
|
355
|
-
| **visual_banner** | <img src="./assets/visual_banner_mobile.png" width="200" alt="Visual banner format on mobile" /> | <img src="./assets/visual_banner_desktop.png" width="400" alt="Visual banner format on desktop" /> |
|
|
356
|
-
|
|
|
101
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GameData, MiniGameTheme } from '../types';
|
|
3
|
+
interface GameCardProps {
|
|
4
|
+
game: GameData;
|
|
5
|
+
charID: string;
|
|
6
|
+
theme: MiniGameTheme;
|
|
7
|
+
onGameSelect: (gameId: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare const GameCard: React.FC<GameCardProps>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=GameCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameCard.d.ts","sourceRoot":"","sources":["../../src/components/GameCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEnD,UAAU,aAAa;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA+N5C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GameData, MiniGameTheme } from '../types';
|
|
3
|
+
interface GameGridProps {
|
|
4
|
+
games: GameData[];
|
|
5
|
+
maxGamesToShow: 3 | 6 | 9;
|
|
6
|
+
charID: string;
|
|
7
|
+
theme: MiniGameTheme;
|
|
8
|
+
onGameSelect: (gameId: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const GameGrid: React.FC<GameGridProps>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=GameGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameGrid.d.ts","sourceRoot":"","sources":["../../src/components/GameGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGnD,UAAU,aAAa;IACrB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,cAAc,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA0K5C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameIframe.d.ts","sourceRoot":"","sources":["../../src/components/GameIframe.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAsHhD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MiniGameMenu.d.ts","sourceRoot":"","sources":["../../src/components/MiniGameMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAiB,MAAM,UAAU,CAAC;AAc5D,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqVpD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InChatAdSlot.d.ts","sourceRoot":"","sources":["../../../src/components/inChatAd/InChatAdSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AASjF,OAAO,EAAE,iBAAiB,EAAU,MAAM,aAAa,CAAC;AAexD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqXpD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GameData, MiniGameTheme } from '../../types';
|
|
3
|
+
interface GameCardProps {
|
|
4
|
+
game: GameData;
|
|
5
|
+
charID: string;
|
|
6
|
+
theme: MiniGameTheme;
|
|
7
|
+
onGameSelect: (gameId: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare const GameCard: React.FC<GameCardProps>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=GameCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameCard.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/GameCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtD,UAAU,aAAa;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA+N5C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { GameData, MiniGameTheme } from '../../types';
|
|
3
|
+
interface GameGridProps {
|
|
4
|
+
games: GameData[];
|
|
5
|
+
maxGamesToShow: 3 | 6 | 9;
|
|
6
|
+
charID: string;
|
|
7
|
+
theme: MiniGameTheme;
|
|
8
|
+
onGameSelect: (gameId: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const GameGrid: React.FC<GameGridProps>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=GameGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameGrid.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/GameGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGtD,UAAU,aAAa;IACrB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,cAAc,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA0K5C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GameIframe.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/GameIframe.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAsHhD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MiniGameMenu.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/MiniGameMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAiB,MAAM,aAAa,CAAC;AAc/D,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqVpD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockGames.d.ts","sourceRoot":"","sources":["../../../src/components/miniGame/mockGames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,eAAO,MAAM,SAAS,EAAE,QAAQ,EAuD/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockGames.d.ts","sourceRoot":"","sources":["../../src/components/mockGames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,eAAO,MAAM,SAAS,EAAE,QAAQ,EAuD/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SponsoredSuggestions.d.ts","sourceRoot":"","sources":["../../../src/components/sponsoredSuggestions/SponsoredSuggestions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAA2B,MAAM,aAAa,CAAC;AAYjF,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAkJpE,CAAC"}
|