@ait-kit/sdk 0.2.0 → 0.4.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.
Files changed (68) hide show
  1. package/README.md +178 -9
  2. package/dist/index.d.ts +9 -5
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/platform-loader.d.ts +16 -0
  5. package/dist/platform-loader.d.ts.map +1 -0
  6. package/dist/platform-loader.js +35 -0
  7. package/dist/promotion/adapter.d.ts +3 -0
  8. package/dist/promotion/adapter.d.ts.map +1 -0
  9. package/dist/promotion/adapter.js +128 -0
  10. package/dist/promotion/platform-contract.d.ts +37 -0
  11. package/dist/promotion/platform-contract.d.ts.map +1 -0
  12. package/dist/promotion/platform-contract.js +1 -0
  13. package/dist/review/adapter.d.ts +3 -0
  14. package/dist/review/adapter.d.ts.map +1 -0
  15. package/dist/review/adapter.js +33 -0
  16. package/dist/review/platform-contract.d.ts +21 -0
  17. package/dist/review/platform-contract.d.ts.map +1 -0
  18. package/dist/review/platform-contract.js +1 -0
  19. package/dist/rn/ads.d.ts.map +1 -1
  20. package/dist/rn/ads.js +120 -119
  21. package/dist/rn/framework-loader.d.ts.map +1 -1
  22. package/dist/rn/framework-loader.js +6 -17
  23. package/dist/rn/iap.d.ts.map +1 -1
  24. package/dist/rn/iap.js +9 -28
  25. package/dist/rn/identity.d.ts.map +1 -1
  26. package/dist/rn/identity.js +11 -22
  27. package/dist/rn/index.d.ts +2 -0
  28. package/dist/rn/index.d.ts.map +1 -1
  29. package/dist/rn/index.js +2 -0
  30. package/dist/rn/notify-share.d.ts +3 -3
  31. package/dist/rn/notify-share.d.ts.map +1 -1
  32. package/dist/rn/notify-share.js +16 -33
  33. package/dist/rn/official-module.d.ts +83 -0
  34. package/dist/rn/official-module.d.ts.map +1 -0
  35. package/dist/rn/official-module.js +106 -0
  36. package/dist/rn/platform-loader.d.ts +4 -0
  37. package/dist/rn/platform-loader.d.ts.map +1 -0
  38. package/dist/rn/platform-loader.js +5 -0
  39. package/dist/rn/promotion.d.ts +9 -0
  40. package/dist/rn/promotion.d.ts.map +1 -0
  41. package/dist/rn/promotion.js +11 -0
  42. package/dist/rn/review.d.ts +7 -0
  43. package/dist/rn/review.d.ts.map +1 -0
  44. package/dist/rn/review.js +10 -0
  45. package/dist/rn/storage.d.ts.map +1 -1
  46. package/dist/rn/storage.js +4 -22
  47. package/dist/share/platform-contract.d.ts +4 -4
  48. package/dist/share/platform-contract.js +5 -5
  49. package/dist/web/framework-loader.d.ts.map +1 -1
  50. package/dist/web/framework-loader.js +7 -23
  51. package/dist/web/identity.d.ts.map +1 -1
  52. package/dist/web/identity.js +12 -33
  53. package/dist/web/index.d.ts +2 -0
  54. package/dist/web/index.d.ts.map +1 -1
  55. package/dist/web/index.js +4 -5
  56. package/dist/web/notify-share.d.ts +3 -2
  57. package/dist/web/notify-share.d.ts.map +1 -1
  58. package/dist/web/notify-share.js +11 -33
  59. package/dist/web/platform-loader.d.ts +4 -0
  60. package/dist/web/platform-loader.d.ts.map +1 -0
  61. package/dist/web/platform-loader.js +5 -0
  62. package/dist/web/promotion.d.ts +9 -0
  63. package/dist/web/promotion.d.ts.map +1 -0
  64. package/dist/web/promotion.js +10 -0
  65. package/dist/web/review.d.ts +7 -0
  66. package/dist/web/review.d.ts.map +1 -0
  67. package/dist/web/review.js +9 -0
  68. package/package.json +3 -3
package/dist/rn/ads.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { resolvePlatformLoader } from "../platform-loader.js";
1
2
  // Relative import: the package ships per-file output (no bundling), so
2
3
  // the /rn entry and the root entry share one SdkError constructor and
3
4
  // `instanceof` holds for consumers importing either entry.
@@ -6,6 +7,37 @@ import { runEventFlow } from "../event-flow.js";
6
7
  import { createDefaultFrameworkLoader } from "./framework-loader.js";
7
8
  const DEFAULT_SHOW_TIMEOUT_MS = 60_000;
8
9
  const DEFAULT_LOAD_TIMEOUT_MS = 30_000;
10
+ function createAdDeadline(timeoutMs, now = monotonicNow) {
11
+ if (!(timeoutMs > 0)) {
12
+ return { remainingMs: () => undefined, race: (promise) => promise };
13
+ }
14
+ const startedAt = now();
15
+ return {
16
+ remainingMs: () => timeoutMs - (now() - startedAt),
17
+ race: (promise) => new Promise((resolve, reject) => {
18
+ const timer = setTimeout(() => resolve(undefined), timeoutMs);
19
+ // Attaching handlers also sinks a settlement that happens after the
20
+ // deadline already won; the no-op reject/resolve after settling is
21
+ // ignored by promise semantics.
22
+ promise.then((value) => {
23
+ clearTimeout(timer);
24
+ resolve(value);
25
+ }, (error) => {
26
+ clearTimeout(timer);
27
+ reject(error);
28
+ });
29
+ })
30
+ };
31
+ }
32
+ /**
33
+ * Monotonic elapsed time: a system wall-clock correction while the loader
34
+ * is pending must not shrink or stretch the remaining budget.
35
+ */
36
+ function monotonicNow() {
37
+ return typeof performance !== "undefined" && typeof performance.now === "function"
38
+ ? performance.now()
39
+ : Date.now();
40
+ }
9
41
  /**
10
42
  * React Native ad adapter over `@apps-in-toss/framework`. Load state is
11
43
  * tracked per ad type + ad unit, in-flight duplicate loads share one
@@ -28,73 +60,28 @@ export function createReactNativeAds(options = {}) {
28
60
  if (existing) {
29
61
  return existing.kind === "loaded" ? Promise.resolve() : existing.promise;
30
62
  }
31
- const request = (async () => {
32
- // The deadline covers framework acquisition as well as the provider
33
- // load flow, and a timed-out task must not register with the provider
34
- // afterwards: a retried load would otherwise race a late registration.
35
- let cancelled = false;
36
- const task = (async () => {
37
- const framework = await loadFramework();
38
- if (cancelled) {
39
- throw new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out");
40
- }
41
- if (typeof framework.loadFullScreenAd.isSupported === "function" &&
42
- !framework.loadFullScreenAd.isSupported()) {
43
- throw new SdkError("UNSUPPORTED", "full-screen ads are not supported on this app version");
63
+ // Slot updates run inside this promise's settlement — before the
64
+ // caller's await/catch continuation — so a caller that immediately
65
+ // retries after a failure starts a fresh registration, and a caller
66
+ // that immediately shows after a success finds the slot loaded. The
67
+ // identity check keeps a stale task from touching a newer task's slot.
68
+ const promise = new Promise((resolve, reject) => {
69
+ runLoad(adGroupId).then(() => {
70
+ const current = slots.get(id);
71
+ if (current?.kind === "loading" && current.promise === promise) {
72
+ slots.set(id, { kind: "loaded" });
44
73
  }
45
- const outcome = await runEventFlow({
46
- register: (emit) => framework.loadFullScreenAd({
47
- options: { adGroupId },
48
- onEvent: emit,
49
- onError: (error) => emit({ type: "sdkError", error })
50
- }),
51
- reduce: (event) => event.type === "loaded"
52
- ? { done: true, result: undefined }
53
- : { done: true, result: loadFailure(event.error) },
54
- onTimeout: () => new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out"),
55
- timeoutMs: loadTimeoutMs
56
- });
57
- if (outcome instanceof SdkError) {
58
- throw outcome;
59
- }
60
- })();
61
- // If the deadline wins, the orphaned task rejects into this sink.
62
- task.catch(() => { });
63
- let timer;
64
- const deadline = new Promise((_, reject) => {
65
- if (loadTimeoutMs > 0) {
66
- timer = setTimeout(() => {
67
- cancelled = true;
68
- reject(new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out"));
69
- }, loadTimeoutMs);
74
+ resolve();
75
+ }, (error) => {
76
+ const current = slots.get(id);
77
+ if (current?.kind === "loading" && current.promise === promise) {
78
+ slots.delete(id);
70
79
  }
80
+ reject(error);
71
81
  });
72
- try {
73
- return await Promise.race([task, deadline]);
74
- }
75
- finally {
76
- if (timer !== undefined)
77
- clearTimeout(timer);
78
- }
79
- })();
80
- slots.set(id, { kind: "loading", promise: request });
81
- request
82
- .then(() => {
83
- // Promote only when this exact request still owns the slot: a
84
- // timed-out task resolving late must not mark a newer retry loaded.
85
- const current = slots.get(id);
86
- if (current?.kind === "loading" && current.promise === request) {
87
- slots.set(id, { kind: "loaded" });
88
- }
89
- })
90
- .catch(() => {
91
- // A failed load frees the slot so the next attempt retries.
92
- const current = slots.get(id);
93
- if (current?.kind === "loading" && current.promise === request) {
94
- slots.delete(id);
95
- }
96
82
  });
97
- return request;
83
+ slots.set(id, { kind: "loading", promise });
84
+ return promise;
98
85
  };
99
86
  const show = (adGroupId) => {
100
87
  const id = adKey("fullscreen", adGroupId);
@@ -111,65 +98,85 @@ export function createReactNativeAds(options = {}) {
111
98
  slots.delete(id);
112
99
  showing.add(id);
113
100
  return (async () => {
114
- // The deadline covers framework acquisition as well as the show flow:
115
- // a stalled loader must release the showing slot instead of wedging
116
- // the ad group forever, and a late-resolving loader must not register
117
- // a show the deadline already ended.
118
- let reward;
119
- let cancelled = false;
120
101
  const timedOut = () => ({ status: "failed", reason: "ad show flow timed out" });
121
102
  try {
122
- let timer;
123
- const deadline = new Promise((resolve) => {
124
- if (showTimeoutMs > 0) {
125
- timer = setTimeout(() => {
126
- cancelled = true;
127
- resolve(timedOut());
128
- }, showTimeoutMs);
129
- }
130
- });
131
- const task = (async () => {
132
- const framework = await loadFramework();
133
- if (cancelled) {
134
- return timedOut();
135
- }
136
- if (typeof framework.showFullScreenAd.isSupported === "function" &&
137
- !framework.showFullScreenAd.isSupported()) {
138
- throw new SdkError("UNSUPPORTED", "full-screen ads are not supported on this app version");
139
- }
140
- return await runEventFlow({
141
- register: (emit) => framework.showFullScreenAd({
142
- options: { adGroupId },
143
- onEvent: emit,
144
- onError: (error) => emit({ type: "sdkError", error })
145
- }),
146
- reduce: (event) => {
147
- if (event.type === "sdkError") {
148
- const message = errorMessage(event.error);
149
- return {
150
- done: true,
151
- result: { status: "failed", reason: `full-screen ad show failed: ${message}` }
152
- };
153
- }
154
- return reduceShowEvent(event, () => reward, (value) => (reward = value));
155
- },
156
- onTimeout: timedOut,
157
- timeoutMs: showTimeoutMs
158
- });
159
- })();
160
- try {
161
- return await Promise.race([task, deadline]);
103
+ // The whole show shares one budget: the loader races it, the event
104
+ // flow gets what remains, and the flow's own deadline produces the
105
+ // timeout result — its subscription cleanup completes before this
106
+ // promise settles, so `showing` is only released after the
107
+ // subscription is gone.
108
+ const deadline = createAdDeadline(showTimeoutMs);
109
+ const framework = await deadline.race(loadFramework());
110
+ if (!framework) {
111
+ return timedOut();
162
112
  }
163
- finally {
164
- if (timer !== undefined)
165
- clearTimeout(timer);
113
+ if (typeof framework.showFullScreenAd.isSupported === "function" &&
114
+ !framework.showFullScreenAd.isSupported()) {
115
+ throw new SdkError("UNSUPPORTED", "full-screen ads are not supported on this app version");
116
+ }
117
+ const remaining = deadline.remainingMs();
118
+ if (remaining !== undefined && remaining <= 0) {
119
+ return timedOut();
166
120
  }
121
+ let reward;
122
+ return await runEventFlow({
123
+ register: (emit) => framework.showFullScreenAd({
124
+ options: { adGroupId },
125
+ onEvent: emit,
126
+ onError: (error) => emit({ type: "sdkError", error })
127
+ }),
128
+ reduce: (event) => {
129
+ if (event.type === "sdkError") {
130
+ const message = errorMessage(event.error);
131
+ return {
132
+ done: true,
133
+ result: { status: "failed", reason: `full-screen ad show failed: ${message}` }
134
+ };
135
+ }
136
+ return reduceShowEvent(event, () => reward, (value) => (reward = value));
137
+ },
138
+ onTimeout: timedOut,
139
+ timeoutMs: remaining ?? 0
140
+ });
167
141
  }
168
142
  finally {
169
143
  showing.delete(id);
170
144
  }
171
145
  })();
172
146
  };
147
+ async function runLoad(adGroupId) {
148
+ // One deadline covers framework acquisition AND the provider flow. A
149
+ // loader that wins the race only just — or too late — leaves no budget
150
+ // for the provider registration, which is then skipped entirely.
151
+ const deadline = createAdDeadline(loadTimeoutMs);
152
+ const framework = await deadline.race(loadFramework());
153
+ if (!framework) {
154
+ throw new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out");
155
+ }
156
+ if (typeof framework.loadFullScreenAd.isSupported === "function" &&
157
+ !framework.loadFullScreenAd.isSupported()) {
158
+ throw new SdkError("UNSUPPORTED", "full-screen ads are not supported on this app version");
159
+ }
160
+ const remaining = deadline.remainingMs();
161
+ if (remaining !== undefined && remaining <= 0) {
162
+ throw new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out");
163
+ }
164
+ const outcome = await runEventFlow({
165
+ register: (emit) => framework.loadFullScreenAd({
166
+ options: { adGroupId },
167
+ onEvent: emit,
168
+ onError: (error) => emit({ type: "sdkError", error })
169
+ }),
170
+ reduce: (event) => event.type === "loaded"
171
+ ? { done: true, result: undefined }
172
+ : { done: true, result: loadFailure(event.error) },
173
+ onTimeout: () => new SdkError("AD_LOAD_TIMEOUT", "full-screen ad load timed out"),
174
+ timeoutMs: remaining ?? 0
175
+ });
176
+ if (outcome instanceof SdkError) {
177
+ throw outcome;
178
+ }
179
+ }
173
180
  async function loadFramework() {
174
181
  const result = await loader();
175
182
  if (!result.available) {
@@ -216,11 +223,5 @@ function errorMessage(error) {
216
223
  return error instanceof Error ? error.message : String(error);
217
224
  }
218
225
  function normalizeLoader(framework) {
219
- if (!framework) {
220
- return createDefaultFrameworkLoader();
221
- }
222
- if (typeof framework === "function") {
223
- return framework;
224
- }
225
- return async () => ({ available: true, module: framework });
226
+ return resolvePlatformLoader(framework, createDefaultFrameworkLoader);
226
227
  }
@@ -1 +1 @@
1
- {"version":3,"file":"framework-loader.d.ts","sourceRoot":"","sources":["../../src/rn/framework-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,GAChD;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAkB9D"}
1
+ {"version":3,"file":"framework-loader.d.ts","sourceRoot":"","sources":["../../src/rn/framework-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,GAChD;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAO9D"}
@@ -1,3 +1,4 @@
1
+ import { createRnPlatformLoader } from "./platform-loader.js";
1
2
  /**
2
3
  * Default lazy loader: imports `@apps-in-toss/framework` only when an ad
3
4
  * operation needs it. A failed import is never cached, so a later call
@@ -5,22 +6,10 @@
5
6
  * successful loads are cached.
6
7
  */
7
8
  export function createDefaultFrameworkLoader() {
8
- let cached;
9
- return async () => {
10
- if (cached) {
11
- return { available: true, module: cached };
9
+ return createRnPlatformLoader((module) => {
10
+ if (typeof module.loadFullScreenAd !== "function" || typeof module.showFullScreenAd !== "function") {
11
+ return { available: false, reason: "@apps-in-toss/framework does not expose the Ads APIs" };
12
12
  }
13
- try {
14
- const module = (await import("@apps-in-toss/framework"));
15
- if (typeof module.loadFullScreenAd !== "function" || typeof module.showFullScreenAd !== "function") {
16
- return { available: false, reason: "@apps-in-toss/framework does not expose the Ads APIs" };
17
- }
18
- cached = module;
19
- return { available: true, module: cached };
20
- }
21
- catch (error) {
22
- const message = error instanceof Error ? error.message : String(error);
23
- return { available: false, reason: `failed to import @apps-in-toss/framework: ${message}` };
24
- }
25
- };
13
+ return { available: true, module: module };
14
+ });
26
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"iap.d.ts","sourceRoot":"","sources":["../../src/rn/iap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrG,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE5F;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IAC9E;;;;OAIG;IACH,SAAS,CAAC,EAAE,qBAAqB,GAAG,iBAAiB,CAAC;CACvD;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACrE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,0CAOlE"}
1
+ {"version":3,"file":"iap.d.ts","sourceRoot":"","sources":["../../src/rn/iap.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrG,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE5F;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IAC9E;;;;OAIG;IACH,SAAS,CAAC,EAAE,qBAAqB,GAAG,iBAAiB,CAAC;CACvD;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACrE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,0CAGlE"}
package/dist/rn/iap.js CHANGED
@@ -1,35 +1,16 @@
1
+ import { resolvePlatformLoader } from "../platform-loader.js";
2
+ import { createRnPlatformLoader } from "./platform-loader.js";
1
3
  import { createIapAdapter } from "../iap/adapter.js";
2
4
  export function createReactNativeIap(options) {
3
- const loader = !options.framework
4
- ? createDefaultRnIapLoader()
5
- : typeof options.framework === "function"
6
- ? options.framework
7
- : async () => ({ available: true, module: options.framework });
5
+ const loader = resolvePlatformLoader(options.framework, createDefaultRnIapLoader);
8
6
  return createIapAdapter({ ...options, loader });
9
7
  }
10
8
  function createDefaultRnIapLoader() {
11
- let cached;
12
- return async () => {
13
- if (cached) {
14
- return { available: true, module: cached };
9
+ return createRnPlatformLoader((framework) => {
10
+ const iap = framework.IAP;
11
+ if (typeof iap !== "object" || iap === null) {
12
+ return { available: false, reason: "@apps-in-toss/framework does not expose an IAP domain" };
15
13
  }
16
- try {
17
- const framework = (await import("@apps-in-toss/framework"));
18
- const iap = framework.IAP;
19
- if (typeof iap !== "object" || iap === null) {
20
- return {
21
- available: false,
22
- reason: "@apps-in-toss/framework does not expose an IAP domain"
23
- };
24
- }
25
- // Per-operation capability is validated at each call site: an
26
- // installed version may expose some IAP functions but not others.
27
- cached = iap;
28
- return { available: true, module: cached };
29
- }
30
- catch (error) {
31
- const message = error instanceof Error ? error.message : String(error);
32
- return { available: false, reason: `failed to import @apps-in-toss/framework: ${message}` };
33
- }
34
- };
14
+ return { available: true, module: iap };
15
+ });
35
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rn/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EAGzB,MAAM,kCAAkC,CAAC;AAE1C,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,mBAAmB,GAAG,sBAAsB,CAAC;CAC1D;AAED,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,KAAK,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,mEAAmE;IACnE,eAAe,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7C;AAED,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,0BAA+B,GAAG,mBAAmB,CAavG;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,0BAA0B,CAAC,WAAW,CAAC,GACjD,sBAAsB,CAQxB"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rn/identity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EAGzB,MAAM,kCAAkC,CAAC;AAG1C,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,mBAAmB,GAAG,sBAAsB,CAAC;CAC1D;AAED,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,KAAK,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,mEAAmE;IACnE,eAAe,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7C;AAED,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,0BAA+B,GAAG,mBAAmB,CAavG;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,0BAA0B,CAAC,WAAW,CAAC,GACjD,sBAAsB,CAExB"}
@@ -1,5 +1,8 @@
1
+ import { resolvePlatformLoader } from "../platform-loader.js";
2
+ import { createRnPlatformLoader } from "./platform-loader.js";
1
3
  import { SdkError } from "../index.js";
2
4
  import { runSdkGetAnonymousKey, runSdkLogin } from "../identity/platform-contract.js";
5
+ import { adaptOfficialRnIdentity } from "./official-module.js";
3
6
  export function createReactNativeIdentity(options = {}) {
4
7
  const loader = normalizeIdentityLoader(options.framework);
5
8
  const load = async () => {
@@ -15,28 +18,14 @@ export function createReactNativeIdentity(options = {}) {
15
18
  };
16
19
  }
17
20
  export function normalizeIdentityLoader(framework) {
18
- if (!framework) {
19
- return createDefaultRnIdentityLoader();
20
- }
21
- if (typeof framework === "function") {
22
- return framework;
23
- }
24
- return async () => ({ available: true, module: framework });
21
+ return resolvePlatformLoader(framework, createDefaultRnIdentityLoader);
25
22
  }
23
+ /**
24
+ * Default loader: imports the official `@apps-in-toss/framework` lazily and
25
+ * converts its flat export surface (`appLogin`, `getAnonymousKey`) to the
26
+ * shared identity contract. A failed import is never cached (a later call
27
+ * retries); successful loads cache the converted module.
28
+ */
26
29
  function createDefaultRnIdentityLoader() {
27
- let cached;
28
- return async () => {
29
- if (cached) {
30
- return { available: true, module: cached };
31
- }
32
- try {
33
- const framework = (await import("@apps-in-toss/framework"));
34
- cached = framework;
35
- return { available: true, module: cached };
36
- }
37
- catch (error) {
38
- const message = error instanceof Error ? error.message : String(error);
39
- return { available: false, reason: `failed to import @apps-in-toss/framework: ${message}` };
40
- }
41
- };
30
+ return createRnPlatformLoader(module => ({ available: true, module: adaptOfficialRnIdentity(module) }));
42
31
  }
@@ -24,4 +24,6 @@ export { createReactNativeStorage, type ReactNativeStorageOptions } from "./stor
24
24
  export { createReactNativeNotification, createReactNativeShare, type ReactNativeNotification, type ReactNativeNotificationOptions, type ReactNativeShare, type ReactNativeShareOptions } from "./notify-share.js";
25
25
  export { createDefaultFrameworkLoader, type FrameworkLoader } from "./framework-loader.js";
26
26
  export type { FullScreenAdShowEvent, FullScreenAdSupport, LoadFullScreenAdParams, ShowFullScreenAdParams } from "./framework-contract.js";
27
+ export { createReactNativeReview, type ReactNativeReviewOptions } from "./review.js";
28
+ export { createReactNativePromotion, type ReactNativePromotionOptions } from "./promotion.js";
27
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rn/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,KAAK,yBAAyB,EAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,4BAA4B,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC3F,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rn/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,KAAK,yBAAyB,EAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,4BAA4B,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC3F,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,uBAAuB,EAAE,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAErF,OAAO,EAAE,0BAA0B,EAAE,KAAK,2BAA2B,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/rn/index.js CHANGED
@@ -22,3 +22,5 @@ export { createReactNativeIdentity } from "./identity.js";
22
22
  export { createReactNativeStorage } from "./storage.js";
23
23
  export { createReactNativeNotification, createReactNativeShare } from "./notify-share.js";
24
24
  export { createDefaultFrameworkLoader } from "./framework-loader.js";
25
+ export { createReactNativeReview } from "./review.js";
26
+ export { createReactNativePromotion } from "./promotion.js";
@@ -30,9 +30,9 @@ export interface ReactNativeShare {
30
30
  /** Creates a share link for an `intoss://` deeplink path. */
31
31
  createLink(path: string, ogImageUrl?: string): Promise<string>;
32
32
  /**
33
- * Opens the native share sheet. Resolving `closed` means the sheet flow
34
- * ended — it does not prove the user shared and never grants reward
35
- * eligibility.
33
+ * Opens the native share sheet. Resolving `completed` means the SDK share
34
+ * call finished — it does not prove the user shared (or even saw the
35
+ * sheet) and never grants reward eligibility.
36
36
  */
37
37
  sendMessage(message: string): Promise<SdkShareUiResult>;
38
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"notify-share.d.ts","sourceRoot":"","sources":["../../src/rn/notify-share.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAE7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAGtB,MAAM,+BAA+B,CAAC;AAQvC,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,SAAS,CAAC,EAAE,uBAAuB,GAAG,0BAA0B,CAAC;IACjE,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACjF;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,8BAAmC,GAC3C,uBAAuB,CAazB;AAMD,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;CACpD;AAED,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACzD;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,uBAA4B,GACpC,gBAAgB,CAyClB;AAMD,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,8BAA8B,CAAC,WAAW,CAAC,GACrD,0BAA0B,CAQ5B;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,uBAAuB,CAAC,WAAW,CAAC,GAC9C,mBAAmB,CAQrB"}
1
+ {"version":3,"file":"notify-share.d.ts","sourceRoot":"","sources":["../../src/rn/notify-share.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAE7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAGtB,MAAM,+BAA+B,CAAC;AASvC,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,SAAS,CAAC,EAAE,uBAAuB,GAAG,0BAA0B,CAAC;IACjE,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACjF;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,8BAAmC,GAC3C,uBAAuB,CAazB;AAMD,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;CACpD;AAED,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACzD;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,uBAA4B,GACpC,gBAAgB,CAyClB;AAMD,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,8BAA8B,CAAC,WAAW,CAAC,GACrD,0BAA0B,CAE5B;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,uBAAuB,CAAC,WAAW,CAAC,GAC9C,mBAAmB,CAErB"}
@@ -1,6 +1,9 @@
1
+ import { resolvePlatformLoader } from "../platform-loader.js";
2
+ import { createRnPlatformLoader } from "./platform-loader.js";
1
3
  import { SdkError } from "../index.js";
2
4
  import { runRequestAgreement } from "../notification/platform-contract.js";
3
5
  import { runShareUi, validateSharePath } from "../share/platform-contract.js";
6
+ import { adaptOfficialRnNotification, adaptOfficialRnShare } from "./official-module.js";
4
7
  const DEFAULT_AGREEMENT_TIMEOUT_MS = 60_000;
5
8
  export function createReactNativeNotification(options = {}) {
6
9
  const loader = normalizeNotificationLoader(options.framework);
@@ -57,42 +60,22 @@ export function createReactNativeShare(options = {}) {
57
60
  // Loaders
58
61
  // ---------------------------------------------------------------------------
59
62
  export function normalizeNotificationLoader(framework) {
60
- if (!framework) {
61
- return createDefaultRnModuleLoader();
62
- }
63
- if (typeof framework === "function") {
64
- return framework;
65
- }
66
- return async () => ({ available: true, module: framework });
63
+ return resolvePlatformLoader(framework, createDefaultRnNotificationLoader);
67
64
  }
68
65
  export function normalizeShareLoader(framework) {
69
- if (!framework) {
70
- return createDefaultRnModuleLoader();
71
- }
72
- if (typeof framework === "function") {
73
- return framework;
74
- }
75
- return async () => ({ available: true, module: framework });
66
+ return resolvePlatformLoader(framework, createDefaultRnShareLoader);
76
67
  }
77
- function createDefaultRnModuleLoader() {
78
- let cached;
79
- return async () => {
80
- if (cached) {
81
- return { available: true, module: cached };
82
- }
83
- try {
84
- const framework = (await import("@apps-in-toss/framework"));
85
- cached = framework;
86
- return { available: true, module: cached };
87
- }
88
- catch (error) {
89
- const message = error instanceof Error ? error.message : String(error);
90
- return {
91
- available: false,
92
- reason: `failed to import @apps-in-toss/framework: ${message}`
93
- };
94
- }
95
- };
68
+ /**
69
+ * Default loaders: import the official `@apps-in-toss/framework` lazily and
70
+ * convert its flat export surface (`requestNotificationAgreement`,
71
+ * `getTossShareLink`, `share`) to the shared contracts. Failed imports are
72
+ * never cached; successful loads cache the converted module.
73
+ */
74
+ function createDefaultRnNotificationLoader() {
75
+ return createRnPlatformLoader(module => ({ available: true, module: adaptOfficialRnNotification(module) }));
76
+ }
77
+ function createDefaultRnShareLoader() {
78
+ return createRnPlatformLoader(module => ({ available: true, module: adaptOfficialRnShare(module) }));
96
79
  }
97
80
  /**
98
81
  * Runs one agreement under a deadline that also covers platform loading:
@@ -0,0 +1,83 @@
1
+ import type { PromotionPlatformSdk, PromotionGrantInput } from "../promotion/platform-contract.js";
2
+ import type { IdentityPlatformSdk } from "../identity/platform-contract.js";
3
+ import type { NotificationAgreementParams, NotificationPlatformSdk } from "../notification/platform-contract.js";
4
+ import type { SharePlatformSdk } from "../share/platform-contract.js";
5
+ /**
6
+ * Internal conversion layer between the official `@apps-in-toss/framework`
7
+ * exports and the shared platform contracts. The official React Native SDK
8
+ * (verified against 2.10.10, re-exported from @apps-in-toss/native-modules)
9
+ * exposes these capabilities as flat module functions, while the shared
10
+ * contracts (which match the web SDK's namespaced API) group them under
11
+ * TossAuth/User/Notification/Share. This module performs that translation;
12
+ * it is never exported from a public subpath.
13
+ *
14
+ * Every member of {@link OfficialRnFrameworkModule} is optional: older
15
+ * app/SDK versions may omit any of them, and each adapter surfaces a
16
+ * missing capability as a clear UNSUPPORTED error for that operation
17
+ * instead of guessing a call shape.
18
+ */
19
+ /** Official `appLogin()` result, preserved verbatim by the identity engine. */
20
+ export interface OfficialAppLoginResult {
21
+ authorizationCode: string;
22
+ referrer: "DEFAULT" | "SANDBOX";
23
+ }
24
+ /**
25
+ * Official `getAnonymousKey()` success shape. The official function may
26
+ * also resolve the `"ERROR"` sentinel (unknown failure) or `undefined`
27
+ * (app below the feature's minimum version); both are handled by the
28
+ * adapter below.
29
+ */
30
+ export interface OfficialAnonymousKeyResult {
31
+ type: "HASH";
32
+ hash: string;
33
+ }
34
+ type OfficialFunction<F> = F & {
35
+ isSupported?: () => boolean;
36
+ };
37
+ /** Structural subset of the official React Native framework module. */
38
+ export interface OfficialRnFrameworkModule {
39
+ grantPromotionReward?: OfficialFunction<(input: {
40
+ params: PromotionGrantInput;
41
+ }) => Promise<{
42
+ key: string;
43
+ } | {
44
+ code: string;
45
+ } | {
46
+ errorCode: string;
47
+ message: string;
48
+ } | "ERROR" | undefined>>;
49
+ requestReview?: OfficialFunction<() => Promise<void>>;
50
+ appLogin?: OfficialFunction<() => Promise<OfficialAppLoginResult>>;
51
+ getAnonymousKey?: OfficialFunction<() => Promise<OfficialAnonymousKeyResult | "ERROR" | undefined>>;
52
+ requestNotificationAgreement?: OfficialFunction<(params: NotificationAgreementParams) => () => void>;
53
+ getTossShareLink?: OfficialFunction<(path: string, ogImageUrl?: string) => Promise<string>>;
54
+ share?: OfficialFunction<(message: {
55
+ message: string;
56
+ }) => Promise<void>>;
57
+ }
58
+ /**
59
+ * Converts the official identity exports (`appLogin`, `getAnonymousKey`) to
60
+ * the shared identity contract. Missing functions stay missing so the
61
+ * shared engine reports UNSUPPORTED per operation.
62
+ */
63
+ export declare function adaptOfficialRnIdentity(module: OfficialRnFrameworkModule): IdentityPlatformSdk;
64
+ /**
65
+ * Converts the official `requestNotificationAgreement` to the shared
66
+ * notification contract. The official params shape matches the internal
67
+ * one exactly, and the returned cleanup function passes through so the
68
+ * event flow owns and invokes it.
69
+ */
70
+ export declare function adaptOfficialRnNotification(module: OfficialRnFrameworkModule): NotificationPlatformSdk;
71
+ /**
72
+ * Converts the official share exports to the shared share contract:
73
+ * `getTossShareLink(path, ogImageUrl?)` takes positional arguments (the
74
+ * internal contract's object form is unpacked here) and `share` receives
75
+ * the `{ message }` object as-is.
76
+ */
77
+ export declare function adaptOfficialRnShare(module: OfficialRnFrameworkModule): SharePlatformSdk;
78
+ /** Translate the official flat review function, preserving both receivers. */
79
+ export declare function adaptOfficialRnReview(module: OfficialRnFrameworkModule): import("../review/platform-contract.js").ReviewPlatformSdk;
80
+ /** Flat RN API uses a params wrapper and undefined for unsupported app versions. */
81
+ export declare function adaptOfficialRnPromotion(module: OfficialRnFrameworkModule): PromotionPlatformSdk;
82
+ export {};
83
+ //# sourceMappingURL=official-module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"official-module.d.ts","sourceRoot":"","sources":["../../src/rn/official-module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAEnG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,KAAK,EACV,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAyB,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAE7F;;;;;;;;;;;;;GAaG;AAEH,+EAA+E;AAC/E,MAAM,WAAW,sBAAsB;IACrC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,KAAK,gBAAgB,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,OAAO,CAAA;CAAE,CAAC;AAE/D,uEAAuE;AACvE,MAAM,WAAW,yBAAyB;IACxC,oBAAoB,CAAC,EAAE,gBAAgB,CAAC,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,mBAAmB,CAAA;KAAE,KAAK,OAAO,CACzF;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,GAAG,SAAS,CAClG,CAAC,CAAC;IACH,aAAa,CAAC,EAAE,gBAAgB,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,QAAQ,CAAC,EAAE,gBAAgB,CAAC,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACnE,eAAe,CAAC,EAAE,gBAAgB,CAChC,MAAM,OAAO,CAAC,0BAA0B,GAAG,OAAO,GAAG,SAAS,CAAC,CAChE,CAAC;IACF,4BAA4B,CAAC,EAAE,gBAAgB,CAC7C,CAAC,MAAM,EAAE,2BAA2B,KAAK,MAAM,IAAI,CACpD,CAAC;IACF,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5F,KAAK,CAAC,EAAE,gBAAgB,CAAC,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CAC3E;AAkBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,yBAAyB,GAAG,mBAAmB,CA6B9F;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,yBAAyB,GAAG,uBAAuB,CAWtG;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,yBAAyB,GAAG,gBAAgB,CAsBxF;AAED,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,gCAAgC,EAAE,iBAAiB,CAKnI;AAED,oFAAoF;AACpF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,yBAAyB,GAAG,oBAAoB,CAUhG"}