@maccesar/titools 5.2.0 → 5.2.2

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 (81) hide show
  1. package/CONTRIBUTING.md +82 -0
  2. package/README.md +83 -72
  3. package/agents/ti-pro.md +1 -1
  4. package/commands/ti-audit.md +2 -2
  5. package/docs/examples.md +91 -0
  6. package/docs/knowledge-index.md +57 -0
  7. package/lib/commands/uninstall.js +19 -16
  8. package/lib/commands/update.js +1 -1
  9. package/lib/downloader.js +1 -1
  10. package/lib/utils.js +2 -0
  11. package/package.json +4 -2
  12. package/skills/purgetss/references/multi-density-images.md +1 -1
  13. package/skills/ti-admob-unified/SKILL.md +21 -7
  14. package/skills/ti-admob-unified/assets/example/app.js +229 -25
  15. package/skills/ti-admob-unified/assets/example/lib/ads.js +30 -2
  16. package/skills/ti-admob-unified/assets/example/library-usage.js +33 -1
  17. package/skills/ti-admob-unified/references/api-reference.md +39 -16
  18. package/skills/ti-admob-unified/references/banners.md +9 -9
  19. package/skills/ti-admob-unified/references/contributing.md +14 -9
  20. package/skills/ti-admob-unified/references/dependencies.md +31 -25
  21. package/skills/ti-admob-unified/references/fullscreen.md +43 -28
  22. package/skills/ti-admob-unified/references/game-monetization.md +138 -7
  23. package/skills/ti-admob-unified/references/getting-started.md +75 -31
  24. package/skills/ti-admob-unified/references/index.md +5 -2
  25. package/skills/ti-admob-unified/references/integration.md +8 -6
  26. package/skills/ti-admob-unified/references/library.md +41 -10
  27. package/skills/ti-admob-unified/references/mediation-parity.md +17 -0
  28. package/skills/ti-admob-unified/references/mediation.md +22 -9
  29. package/skills/ti-admob-unified/references/migration.md +11 -7
  30. package/skills/ti-admob-unified/references/module-changelog.md +41 -11
  31. package/skills/ti-admob-unified/references/privacy.md +35 -8
  32. package/skills/ti-admob-unified/references/production.md +67 -0
  33. package/skills/ti-admob-unified/references/rewarded-interstitial.md +101 -0
  34. package/skills/ti-admob-unified/references/roadmap.md +28 -31
  35. package/skills/ti-admob-unified/references/source-notes.md +51 -4
  36. package/skills/ti-admob-unified/references/source-snapshot.json +249 -45
  37. package/skills/ti-admob-unified/references/third-party-notices.md +4 -4
  38. package/skills/ti-game/SKILL.md +23 -6
  39. package/skills/ti-game/references/api.md +34 -30
  40. package/skills/ti-game/references/debugging-performance.md +18 -9
  41. package/skills/ti-game/references/examples.md +103 -20
  42. package/skills/ti-game/references/input.md +101 -0
  43. package/skills/ti-game/references/patterns.md +39 -15
  44. package/skills/ti-game/references/physics.md +80 -52
  45. package/skills/ti-game/references/project-setup.md +118 -56
  46. package/skills/ti-game/references/recipes-action.md +107 -8
  47. package/skills/ti-game/references/recipes-adventure-effects.md +41 -9
  48. package/skills/ti-game/references/roadmap.md +10 -3
  49. package/skills/ti-game/references/source-notes.md +81 -0
  50. package/skills/ti-game/references/tilemaps.md +12 -4
  51. package/skills/ti-synthengine/SKILL.md +81 -95
  52. package/skills/ti-synthengine/assets/example/README.md +84 -0
  53. package/skills/ti-synthengine/assets/example/app.js +1178 -0
  54. package/skills/ti-synthengine/assets/example/lib/sequenceOwner.js +83 -0
  55. package/skills/ti-synthengine/assets/example/lib/sequenceScore.js +25 -0
  56. package/skills/ti-synthengine/references/advanced-examples.md +174 -0
  57. package/skills/ti-synthengine/references/android-sim80-correction-evidence.zip +0 -0
  58. package/skills/ti-synthengine/references/android-sim80-correction.json +162 -0
  59. package/skills/ti-synthengine/references/api.md +434 -380
  60. package/skills/ti-synthengine/references/audio-engine.md +157 -230
  61. package/skills/ti-synthengine/references/bypass-physical-recheck-evidence.zip +0 -0
  62. package/skills/ti-synthengine/references/examples.md +123 -253
  63. package/skills/ti-synthengine/references/frontier-android-evidence.zip +0 -0
  64. package/skills/ti-synthengine/references/frontier-ipad-evidence.zip +0 -0
  65. package/skills/ti-synthengine/references/frontier-physical-validation.json +1918 -0
  66. package/skills/ti-synthengine/references/guide.md +188 -156
  67. package/skills/ti-synthengine/references/performance-review-evidence.zip +0 -0
  68. package/skills/ti-synthengine/references/performance-review.json +1146 -0
  69. package/skills/ti-synthengine/references/physical-validation.json +1457 -0
  70. package/skills/ti-synthengine/references/recipes-interaction.md +549 -0
  71. package/skills/ti-synthengine/references/recipes.md +423 -599
  72. package/skills/ti-synthengine/references/recommendations.md +63 -113
  73. package/skills/ti-synthengine/references/sound-design.md +134 -258
  74. package/skills/ti-synthengine/references/source-notes.md +93 -105
  75. package/skills/ti-synthengine/references/source-snapshot.json +379 -32
  76. package/skills/ti-synthengine/references/stats-performance.md +64 -20
  77. package/skills/ti-synthengine/references/studio-validation.json +6202 -0
  78. package/skills/ti-synthengine/references/troubleshooting.md +109 -121
  79. package/skills/ti-synthengine/references/unified-bypass-performance.json +22425 -0
  80. package/skills/ti-synthengine/references/unified-validation.json +314 -0
  81. package/AGENTS-VERCEL-RESEARCH.md +0 -175
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  const Admob = require('ti.admob.unified')
10
- const ads = require('lib/ads')
10
+ const ads = require('lib/ads') // Classic; Alloy app/lib/ads.js: require('ads')
11
11
 
12
12
  const win = Ti.UI.createWindow({ layout: 'composite', backgroundColor: '#ffffff' })
13
13
  const content = Ti.UI.createScrollView({ top: 0, left: 0, right: 0, bottom: 0 })
@@ -48,6 +48,12 @@ const rewarded = ads.createRewarded({
48
48
  onRewarded: event => grantReward(event.rewardAmount, event.rewardType)
49
49
  })
50
50
 
51
+ const rewardedInterstitial = ads.createRewardedInterstitial({
52
+ window: win,
53
+ adUnitId: Admob.TEST_REWARDED_INTERSTITIAL,
54
+ onRewarded: event => grantReward(event.rewardAmount, event.rewardType)
55
+ })
56
+
51
57
  const appOpen = ads.createAppOpen({
52
58
  window: win,
53
59
  adUnitId: Admob.TEST_APP_OPEN,
@@ -66,6 +72,23 @@ function onRewardAccepted() {
66
72
  rewarded.show()
67
73
  }
68
74
 
75
+ // In production, rewardDescription must describe the reward configured for
76
+ // this placement. Only onRewarded above credits the actual SDK-earned reward.
77
+ function onRewardedTransition(rewardDescription) {
78
+ if (!rewardedInterstitial.isLoaded()) return
79
+ const intro = Ti.UI.createAlertDialog({
80
+ title: 'Rewarded interstitial',
81
+ message: `Complete the ad to earn ${rewardDescription}. You can skip it.`,
82
+ buttonNames: ['Watch ad', 'Skip'], cancel: 1
83
+ })
84
+ function onChoice(event) {
85
+ intro.removeEventListener('click', onChoice)
86
+ if (event.index === 0) rewardedInterstitial.show()
87
+ }
88
+ intro.addEventListener('click', onChoice)
89
+ intro.show()
90
+ }
91
+
69
92
  function onApplicationResumed() {
70
93
  appOpen.show()
71
94
  }
@@ -82,8 +105,13 @@ win.addEventListener('close', event => {
82
105
  })
83
106
  win.open()
84
107
 
108
+ // Start in the active foreground. Enable requestTrackingAuthorization only for
109
+ // a real tracking use case with a localized NSUserTrackingUsageDescription.
110
+ // Keep it false when an AdMob UMP IDFA message already handles ATT.
111
+ Ti.API.info('Current ATT state: ' + JSON.stringify(Admob.getTrackingAuthorizationStatus()))
85
112
  ads.start({
86
113
  consent: { tagForUnderAgeOfConsent: false },
114
+ requestTrackingAuthorization: false,
87
115
  initialization: {}
88
116
  }).then(result => {
89
117
  if (!result.initialized) {
@@ -92,7 +120,10 @@ ads.start({
92
120
 
93
121
  interstitial.load()
94
122
  rewarded.load()
123
+ rewardedInterstitial.load()
95
124
  appOpen.load()
125
+ }).catch(error => {
126
+ Ti.API.warn(`[ads] Startup failed: ${error.message || error}`)
96
127
  })
97
128
 
98
129
  // References kept here to make the intended call sites explicit in this
@@ -100,5 +131,6 @@ ads.start({
100
131
  void createAdaptiveBanner
101
132
  void onNaturalBreak
102
133
  void onRewardAccepted
134
+ void onRewardedTransition
103
135
  void onApplicationResumed
104
136
  void openChildWindow
@@ -1,4 +1,4 @@
1
- > Source snapshot: official ti.admob.unified 1.0.0 documentation at commit `5b4cbf9` (copied 2026-10-11). Relative links rebased for this skill.
1
+ > Source snapshot: official ti.admob.unified 1.0.0 documentation at release source commit `034843299b2984253988e0ffccb9f6a1c91682c9` (copied 2026-10-24). Relative links rebased for this skill.
2
2
 
3
3
  # API reference
4
4
 
@@ -34,6 +34,7 @@ const Admob = require('ti.admob.unified')
34
34
  | `isPrivacyOptionsRequired()` | iOS, Android | Supported |
35
35
  | `presentPrivacyOptions(config)` | iOS, Android | Supported |
36
36
  | `resetConsent()` | iOS, Android | Testing only |
37
+ | `getTrackingAuthorizationStatus()` | iOS, Android | Read-only ATT snapshot |
37
38
  | `requestTrackingAuthorization()` | iOS, Android | Portable |
38
39
  | `openAdInspector()` | iOS, Android | Development diagnostic |
39
40
  | `createBanner(config)` | iOS, Android | Supported |
@@ -41,6 +42,7 @@ const Admob = require('ti.admob.unified')
41
42
  | `createAdaptiveBanner(config)` | iOS, Android | Supported |
42
43
  | `createInterstitial(config)` | iOS, Android | Supported |
43
44
  | `createRewarded(config)` | iOS, Android | Supported |
45
+ | `createRewardedInterstitial(config)` | iOS, Android | Supported |
44
46
  | `createAppOpen(config)` | iOS, Android | Supported |
45
47
  | `setTestDevice(deviceId)` | iOS, Android | Compatibility utility |
46
48
  | `isTestDevice()` | iOS, Android | Supported |
@@ -50,11 +52,11 @@ const Admob = require('ti.admob.unified')
50
52
  | `canShowPersonalizedAds()` | iOS, Android | Deprecated; always `false` |
51
53
  | `isGDPR()` | iOS, Android | Deprecated diagnostic |
52
54
 
53
- The four legacy mediation entries are described under [Mediation diagnostics and compatibility](#mediation-diagnostics).
55
+ See [Mediation diagnostics](#mediation-diagnostics) for adapter status and the [migration guide](migration.md#generic-mediation-diagnostics) for removed pre-release helpers.
54
56
 
55
57
  ### `initialize(config)`
56
58
 
57
- Configures global request settings and initializes Google Mobile Ads.
59
+ Sets global request options and initializes Google Mobile Ads.
58
60
 
59
61
  ```js
60
62
  Admob.initialize({
@@ -64,12 +66,14 @@ Admob.initialize({
64
66
  })
65
67
  ```
66
68
 
69
+ On Android, native request configuration and SDK initialization run on a worker thread; completion is delivered on the UI thread. The call returns before adapter initialization finishes. Wait for `module_initialized` before loading ads.
70
+
67
71
  Accepted properties:
68
72
 
69
73
  | Property | Type | Description |
70
74
  | ------------------------------ | -------- | ------------------------------------------------------------------------------ |
71
75
  | `testDeviceIds` | String[] | Google Mobile Ads test-device identifiers. |
72
- | `ageRestrictedTreatment` | String | `CHILD`, `TEEN`, or `UNSPECIFIED` constant value. |
76
+ | `ageRestrictedTreatment` | String | `child`, `teen`, or `unspecified` constant value. |
73
77
  | `maxAdContentRating` | String | `G`, `PG`, `T`, or `MA` constant value. |
74
78
  | `tagForChildDirectedTreatment` | Boolean | Deprecated compatibility input. |
75
79
  | `tagForUnderAgeOfConsent` | Boolean | Deprecated initialization input, separate from the UMP property. |
@@ -95,7 +99,7 @@ Use the exception only when adapters are installed but the application deliberat
95
99
  Admob.initialize({ disableMediation: true })
96
100
  ```
97
101
 
98
- This calls Google’s global initialization switch on [Android](https://developers.google.com/admob/android/reference/com/google/android/gms/ads/MobileAds) and [iOS](https://developers.google.com/admob/ios/api/reference/Classes/GADMobileAds), before SDK startup. It skips adapter initialization globally; it does not remove dependencies, validate credentials, select individual networks or provide an ad-source allowlist. Do not set it in an app that intends to serve mediated ads. The first accepted initialization configuration wins; repeating `initialize()` cannot toggle mediation later in the session.
102
+ This calls Google's global initialization switch on [Android](https://developers.google.com/admob/android/reference/com/google/android/gms/ads/MobileAds) and [iOS](https://developers.google.com/admob/ios/api/reference/Classes/GADMobileAds), before SDK startup. It skips adapter initialization globally; it does not remove dependencies, validate credentials, select individual networks or provide an ad-source allowlist. Do not set it in an app that intends to serve mediated ads. The first accepted initialization configuration wins; repeating `initialize()` cannot toggle mediation later in the session.
99
103
 
100
104
  `applicationId` and `debugGeography` are not accepted here.
101
105
 
@@ -145,6 +149,19 @@ Returns `void` and resets UMP test state and the module's cached consent operati
145
149
 
146
150
  Use only during controlled consent testing. For a production privacy entry point, call `presentPrivacyOptions()`.
147
151
 
152
+ ### `getTrackingAuthorizationStatus()`
153
+
154
+ Returns `{ status: Number, authorized: Boolean, applicable: Boolean }` synchronously. On iOS it reads the current system ATT status on every call: `0` not determined, `1` restricted, `2` denied, `3` authorized. Only status `3` sets `authorized: true`; `applicable` is always `true` on supported iOS versions.
155
+
156
+ This query never presents a prompt, emits an event, or initializes an SDK. Re-query after returning from Settings to read a changed permission.
157
+
158
+ On Android it returns `{ status: 3, authorized: true, applicable: false }`. This portable ATT convention does not grant general tracking permission or replace platform privacy requirements or UMP eligibility.
159
+
160
+ ```js
161
+ const tracking = Admob.getTrackingAuthorizationStatus()
162
+ Ti.API.info(`ATT applies: ${tracking.applicable}; status: ${tracking.status}`)
163
+ ```
164
+
148
165
  ### `requestTrackingAuthorization()`
149
166
 
150
167
  Completes the portable tracking-authorization step and emits `tracking_authorization_completed`. On iOS it requests or retrieves App Tracking Transparency authorization. On Android it completes immediately with `applicable: false`, so consumers do not need a platform condition.
@@ -207,11 +224,15 @@ Returns an interstitial proxy with `load()`, `show()`, `isLoaded()`, and termina
207
224
 
208
225
  Returns a rewarded proxy with `load()`, `show()`, `isLoaded()`, and terminal `destroy()`. Grant rewards only from the `rewarded` event.
209
226
 
227
+ ### `createRewardedInterstitial(config)`
228
+
229
+ Returns a rewarded interstitial proxy with the same methods and configuration as Rewarded, using `adType: 'rewarded_interstitial'`. Explain the reward and offer a skip option before showing it. See [Rewarded interstitial ads](rewarded-interstitial.md).
230
+
210
231
  ### `createAppOpen(config)`
211
232
 
212
233
  Returns an app open proxy with `load()`, `show()`, `isLoaded()`, and terminal `destroy()`. An app open ad expires four hours after loading completes: past that point `isLoaded()` reports `false` and `show()` emits `failed_to_show` with code `1`. See [The four hour window](fullscreen.md#the-four-hour-window).
213
234
 
214
- See [Fullscreen ads](fullscreen.md) for the three factories.
235
+ See [Fullscreen ads](fullscreen.md) for the four factories.
215
236
 
216
237
  ### `setTestDevice(deviceId)`
217
238
 
@@ -259,7 +280,7 @@ The standard and adaptive proxies expose the same methods:
259
280
  | `destroyAdViewAndCancelRequest()` | `void` | Compatibility alias of `destroy()`. |
260
281
  | `destoyAdViewAndCancelRequest()` | `void` | Deprecated misspelled alias. |
261
282
 
262
- The host lifecycle, meaning the Android activity and the iOS application entering the background, pauses banners on its own as a cause independent from these calls. Neither cause resumes the other's pause. See [Who pauses a banner](banners.md#who-pauses-a-banner).
283
+ The host lifecycle also pauses banners: the Android activity pauses, or the iOS application enters the background. That pause is independent of these calls. Neither cause resumes the other's pause. See [Who pauses a banner](banners.md#who-pauses-a-banner).
263
284
 
264
285
  An Android activity recreation caused by a configuration change is non-terminal. The module preserves the proxy, releases the stale native view without emitting `destroyed`, and reloads after Titanium creates the replacement view.
265
286
 
@@ -298,6 +319,8 @@ Banner events:
298
319
  | `AD_CLOSED` | `closed` | Ad overlay closed. |
299
320
  | `AD_DESTROYED` | `destroyed` | Emitted once per proxy. |
300
321
 
322
+ Both banner types include Boolean `isCollapsible` in `loaded`, reporting the SDK's classification of the received ad. It does not report whether the ad is currently expanded or visibly rendered.
323
+
301
324
  Common payload:
302
325
 
303
326
  ```js
@@ -326,7 +349,7 @@ All seven keys are present on both platforms. `density` converts points to pixel
326
349
 
327
350
  ## Fullscreen proxy
328
351
 
329
- Interstitial, rewarded and app open proxies expose:
352
+ Interstitial, rewarded, rewarded interstitial and app open proxies expose:
330
353
 
331
354
  | Method | Return | Description |
332
355
  | ------------ | ------- | ---------------------------------------------------------------------------------------- |
@@ -339,7 +362,7 @@ Loads are serialized: calls while loading, loaded, or showing are ignored. Commo
339
362
 
340
363
  ### Fullscreen creation properties
341
364
 
342
- All three factories accept:
365
+ All four factories accept:
343
366
 
344
367
  | Property | Type | Default | Notes |
345
368
  | -------------- | -------- | ------- | ------------------------------------------------------ |
@@ -355,7 +378,7 @@ See [Fullscreen events](fullscreen.md#events).
355
378
 
356
379
  ## Fullscreen configuration changes
357
380
 
358
- The five configuration properties `adUnitId` (String), `autoReload` (Boolean), `keywords` (String[]), `requestAgent` (String) and `extras` (Object) are readable and writable on both platforms. Changes affect the next load and do not replace an already loaded ad. `autoReload` defaults to `false`; targeting is omitted when unset. Extras retain String, Boolean and numeric primitive values. Internal load/presentation state and native SDK delegate methods are not application APIs.
381
+ The five configuration properties `adUnitId` (String), `autoReload` (Boolean), `keywords` (String[]), `requestAgent` (String) and `extras` (Object) are readable and writable on both platforms. Changes to the four request options affect the next load and do not replace an already loaded ad. `autoReload` defaults to `false` and is read live when the shown ad closes; changing it while an ad is loaded or presented changes whether that close starts a reload. It never automatically presents the replacement or retries a failure. Targeting is omitted when unset. Extras retain String, Boolean and numeric primitive values. Internal load/presentation state and native SDK delegate methods are not application APIs.
359
382
 
360
383
  ## Module events
361
384
 
@@ -437,7 +460,7 @@ On iOS, status values are `0` not determined, `1` restricted, `2` denied, and `3
437
460
  | `AD_TYPE_BANNER` | `"banner"` | Implemented |
438
461
  | `AD_TYPE_INTERSTITIAL` | `"interstitial"` | Implemented |
439
462
  | `AD_TYPE_REWARDED` | `"rewarded"` | Implemented |
440
- | `AD_TYPE_REWARDED_INTERSTITIAL` | `"rewarded_interstitial"` | No factory |
463
+ | `AD_TYPE_REWARDED_INTERSTITIAL` | `"rewarded_interstitial"` | Implemented |
441
464
  | `AD_TYPE_APP_OPEN` | `"app_open"` | Implemented |
442
465
  | `AD_TYPE_NATIVE` | `"native"` | No factory |
443
466
 
@@ -472,7 +495,7 @@ The module exports no `COLLAPSIBLE_TOP` or `COLLAPSIBLE_BOTTOM` constant. Pass G
472
495
  | `AD_SHOWED_FULLSCREEN_CONTENT` | `"showed_fullscreen_content"` |
473
496
  | `AD_DESTROYED` | `"destroyed"` |
474
497
 
475
- All three fullscreen proxy types (interstitial, rewarded and app open) emit `AD_SHOWED_FULLSCREEN_CONTENT` and `AD_OPENED` on iOS and Android.
498
+ All four fullscreen proxy types (interstitial, rewarded, rewarded interstitial and app open) emit `AD_SHOWED_FULLSCREEN_CONTENT` and `AD_OPENED` on iOS and Android.
476
499
 
477
500
  ### Consent status
478
501
 
@@ -538,13 +561,13 @@ The constant names are portable; their string values are platform-specific:
538
561
  | `TEST_INTERSTITIAL` | `ca-app-pub-3940256099942544/4411468910` | `ca-app-pub-3940256099942544/1033173712` | Interstitial | `createInterstitial()` |
539
562
  | `TEST_INTERSTITIAL_VIDEO` | `ca-app-pub-3940256099942544/5135589807` | `ca-app-pub-3940256099942544/8691691433` | Interstitial, video creative | `createInterstitial()` |
540
563
  | `TEST_REWARDED` | `ca-app-pub-3940256099942544/1712485313` | `ca-app-pub-3940256099942544/5224354917` | Rewarded | `createRewarded()` |
541
- | `TEST_REWARDED_INTERSTITIAL` | `ca-app-pub-3940256099942544/6978759866` | `ca-app-pub-3940256099942544/5354046379` | Rewarded interstitial | None. Reserved |
564
+ | `TEST_REWARDED_INTERSTITIAL` | `ca-app-pub-3940256099942544/6978759866` | `ca-app-pub-3940256099942544/5354046379` | Rewarded interstitial | `createRewardedInterstitial()` |
542
565
  | `TEST_NATIVE` | `ca-app-pub-3940256099942544/3986624511` | `ca-app-pub-3940256099942544/2247696110` | Native | None. Reserved |
543
566
  | `TEST_APP_OPEN` | `ca-app-pub-3940256099942544/5575463023` | `ca-app-pub-3940256099942544/9257395921` | App open | `createAppOpen()` |
544
567
 
545
568
  Use the constant in shared code so it selects the platform value.
546
569
 
547
- The reserved constants allow code targeting future releases to compile, although no current factory accepts them. See [Reserved and unavailable APIs](#reserved-and-unavailable-apis).
570
+ `TEST_NATIVE` remains reserved; no current factory accepts it. See [Reserved and unavailable APIs](#reserved-and-unavailable-apis).
548
571
 
549
572
  ## Mediation diagnostics
550
573
 
@@ -565,7 +588,7 @@ The reserved constants allow code targeting future releases to compile, although
565
588
 
566
589
  The method reads Google's current public initialization status without starting SDKs or ad requests. During initialization the map can be empty or partial. An absent entry does not prove that a complement is missing. This is not an installed-module inventory, account check, credential check or guarantee of provider delivery. `ready` does not guarantee an ad.
567
590
 
568
- Query after the unchanged `module_initialized` event:
591
+ Query after `module_initialized`:
569
592
 
570
593
  ```js
571
594
  Admob.addEventListener('module_initialized', event => {
@@ -577,8 +600,8 @@ Use UMP, `canRequestAds()` and each selected provider's current privacy requirem
577
600
 
578
601
  ## Reserved and unavailable APIs
579
602
 
580
- - There is no `createRewardedInterstitial`.
581
603
  - There is no `createNative`.
604
+ - There is no server-side verification configuration (`userId` / `customData`), paid-event / impression-level revenue callback, or public response-info API. Arbitrary `extras` do not add these features. Use `rewarded` for client-side rewards and Ad Inspector for request diagnostics.
582
605
 
583
606
 
584
607
  ## Consent compatibility payloads
@@ -1,10 +1,10 @@
1
- > Source snapshot: official ti.admob.unified 1.0.0 documentation at commit `5b4cbf9` (copied 2026-10-11). Relative links rebased for this skill.
1
+ > Source snapshot: official ti.admob.unified 1.0.0 documentation at release source commit `034843299b2984253988e0ffccb9f6a1c91682c9` (copied 2026-10-24). Relative links rebased for this skill.
2
2
 
3
3
  # Banner ads
4
4
 
5
5
  Standard and adaptive banners share one public lifecycle and event contract on iOS and Android.
6
6
 
7
- Both factories return a Titanium `TiViewProxy`, so their creation dictionaries also accept normal Titanium view/layout properties such as `width`, `height`, `top`, `bottom`, `left`, and `right`. The tables below list the AdMob-specific properties.
7
+ Both factories return a Titanium `TiViewProxy`, so their creation dictionaries also accept normal Titanium view/layout properties such as `width`, `height`, `top`, `bottom`, `left`, and `right`. The tables list the AdMob-specific properties.
8
8
 
9
9
  <!-- TOC-START -->
10
10
  ## Contents
@@ -47,7 +47,7 @@ bannerHost.add(banner)
47
47
  banner.load()
48
48
  ```
49
49
 
50
- The proxy must be in the Titanium view hierarchy before `load()` so its native view can measure the real container width.
50
+ Run these raw API snippets after `module_initialized` succeeds and `canRequestAds()` is true. The proxy must be in the Titanium view hierarchy before `load()` so its native view can measure the real container width. For iOS anchored placements, use the layout-ready pattern under [Full lifecycle example](#full-lifecycle-example), or the [integration library](library.md#banners), rather than calling `load()` immediately after `add()`.
51
51
 
52
52
  ### Creation properties
53
53
 
@@ -169,7 +169,7 @@ function onLoaded(event) {
169
169
 
170
170
  function onFailed(event) {
171
171
  Ti.API.warn(`Banner failed: ${event.error} (${event.code})`)
172
- setBannerHeight(0)
172
+ // Keep the reserved slot stable while a later user action retries.
173
173
  }
174
174
 
175
175
  function onDestroyed() {
@@ -295,7 +295,7 @@ Returns `true` only while the current proxy owns a successfully loaded ad.
295
295
 
296
296
  Terminal and safe to repeat. It releases the native ad, detaches native delegates/listeners and lifecycle registrations, and emits `destroyed` once.
297
297
 
298
- Never reuse a destroyed banner. Create a new proxy for a new placement or a new width/orientation request.
298
+ Never reuse a destroyed banner. Create a new proxy for a new placement. For a width or orientation change, wait for the host's final positive layout and request the new size; the integration library exposes `rebuild()` for that boundary.
299
299
 
300
300
  ### Compatibility aliases
301
301
 
@@ -347,7 +347,7 @@ An adaptive `loaded` event guarantees:
347
347
  }
348
348
  ```
349
349
 
350
- Android additionally reports diagnostic size fields:
350
+ Both platforms also report these size fields:
351
351
 
352
352
  ```js
353
353
  {
@@ -416,17 +416,17 @@ Portable fixed sizes, with the device each one was designed for and the height i
416
416
  | `FULLBANNER` | 468×60 | Tablet |
417
417
  | `LEADERBOARD` | 728×90 | Tablet |
418
418
 
419
- These device categories come from Google's `GADAdSize.h`. A phone is 360–430 dp wide, so a 468 dp `FULLBANNER` cannot fit at full size regardless of the host height. Use `BANNER` for the fixed phone size, or `customAdSize` with the screen width or an adaptive banner for a full-width strip.
419
+ These device categories come from Google's `GADAdSize.h`. In a portrait placement 360 to 430 dp wide, a 468 dp `FULLBANNER` cannot fit at full size regardless of the host height. Use `BANNER` for the fixed phone size, or `customAdSize` with the screen width or an adaptive banner for a full-width strip.
420
420
 
421
421
  Give the host the requested height. A `FULLBANNER` in a 50 dp box will be clipped.
422
422
 
423
423
  Unknown values, including `smart_banner`, fall back to `BANNER`. Google removed smart banners on Android and deprecated them on iOS. The shared fallback avoids selecting a fixed 320×50 banner on one platform and a full-width strip on the other. For full width, use `customAdSize` or `createAdaptiveBanner()` to let Google choose the height.
424
424
 
425
- Changing `adSize` on an existing iOS native banner is not supported. Destroy and recreate the proxy.
425
+ Assign the new `adSize` or `customAdSize`, then call `load()` to apply it on both platforms. The module replaces the native view when needed while retaining the proxy.
426
426
 
427
427
  ## Refresh behavior
428
428
 
429
- Do not add a JavaScript renewal timer. Google Mobile Ads respects the banner refresh rate configured for the ad unit in AdMob. The application requests the initial load and lets the SDK/ad-unit configuration own later refreshes.
429
+ Do not add a JavaScript renewal timer. Google Mobile Ads respects the banner refresh rate configured for the ad unit in AdMob. The application requests the first load. The SDK and ad-unit configuration control later refreshes.
430
430
 
431
431
  TiAdMobUnified manages the native banner proxy and its lifecycle without a periodic reload or recreation loop. Google documents that Android automatic refresh requires a visible banner. Set or disable the refresh interval in AdMob, and use screen-level `pause()`/`resume()` when navigation hides or reveals the placement.
432
432
 
@@ -1,8 +1,8 @@
1
- > Source snapshot: official ti.admob.unified 1.0.0 documentation at commit `5b4cbf9` (copied 2026-10-11). Relative links rebased for this skill.
1
+ > Source snapshot: official ti.admob.unified 1.0.0 documentation at release source commit `034843299b2984253988e0ffccb9f6a1c91682c9` (copied 2026-10-24). Relative links rebased for this skill.
2
2
 
3
3
  # Contributing to ti.admob.unified
4
4
 
5
- Changes to this native bridge must keep the JavaScript contract consistent with native behavior on both platforms, including cleanup. Tests and documentation must describe that same behavior.
5
+ Keep the JavaScript contract consistent with native behavior on both platforms, including cleanup. Tests and documentation must agree with the implementation.
6
6
 
7
7
  ## Before opening an issue
8
8
 
@@ -21,9 +21,9 @@ For layout issues, include the Titanium proxy, host, and parent dimensions plus
21
21
 
22
22
  ## Development baseline
23
23
 
24
- - Titanium SDK `13.2.0.GA` or later (build toolchain: `13.4.1.GA`)
24
+ - Titanium SDK `13.4.1.GA` or later (build toolchain: `13.4.1.GA`)
25
25
  - iOS `15.0+`
26
- - Android API `24+`, the floor the Titanium `13.2.0.GA` module template sets
26
+ - Android API `24+`, required by the pinned Google Mobile Ads SDK
27
27
  - Node.js with the built-in `node:test` runner
28
28
 
29
29
  Dependency versions are pinned in [DEPENDENCIES.md](dependencies.md).
@@ -32,12 +32,15 @@ Dependency versions are pinned in [DEPENDENCIES.md](dependencies.md).
32
32
 
33
33
  Create a focused branch and keep unrelated local changes intact. Before editing a native dependency, establish a recoverable Git baseline and record the upstream source and checksum.
34
34
 
35
- This repository holds the core at its root and five dependency-only complements in `mediation/<network>/`. Each has iOS and Android projects at version `1.0.0`. Scripts discover complement folders and derive archive identity/version from manifests. See [Adding a network](#adding-a-network). Applications call only the core. Both script helpers accept a module directory or `--all`.
35
+ The repository root contains the core. Five dependency-only complements live in `mediation/<network>/`. Each has iOS and Android projects at version `1.0.0`. Scripts discover complement folders and derive archive identity/version from manifests. See [Adding a network](#adding-a-network). Applications call only the core. Both script helpers accept a module directory or `--all`.
36
36
 
37
37
  Run the static checks from the repository root:
38
38
 
39
39
  ```sh
40
40
  npm test
41
+ python3 tests/native/android.py
42
+ python3 tests/native/initialization.py
43
+ python3 tests/native/run.py
41
44
  ./scripts/verify-artifacts.sh
42
45
  ./scripts/verify-artifacts.sh --all
43
46
  node --check example/app.js
@@ -70,11 +73,11 @@ Complements package existing official Google mediation adapters; writing a new n
70
73
 
71
74
  ## Platform notes
72
75
 
73
- The native implementations share one JavaScript contract. The notes below describe their source files and platform differences.
76
+ Both native implementations expose the same JavaScript contract. These notes cover their source files and platform differences.
74
77
 
75
78
  ### iOS
76
79
 
77
- Sources in `ios/Classes/` comprise five proxy pairs and the module:
80
+ The sources in `ios/Classes/` contain six proxy pairs and the module:
78
81
 
79
82
  | Source | Responsibility |
80
83
  | --------------------------------------- | --------------------------------------------------------- |
@@ -83,6 +86,7 @@ Sources in `ios/Classes/` comprise five proxy pairs and the module:
83
86
  | `TiAdmobUnifiedAdaptiveBannerAdProxy.*` | Anchored and inline adaptive banner proxy and native view |
84
87
  | `TiAdmobUnifiedInterstitialAdProxy.*` | Interstitial proxy |
85
88
  | `TiAdmobUnifiedRewardedAdProxy.*` | Rewarded proxy |
89
+ | `TiAdmobUnifiedRewardedInterstitialAdProxy.*` | Rewarded interstitial proxy |
86
90
  | `TiAdmobUnifiedAppOpenAdProxy.*` | App open proxy and the four hour validity window |
87
91
 
88
92
  Build from the repository root:
@@ -114,6 +118,7 @@ Sources live in `android/src/ti/admob/unified/`. The banner types split proxy an
114
118
  | `TiAdmobUnifiedAdaptiveBannerAdProxy.java` / `…AdView.java` | Adaptive banner proxy and native container |
115
119
  | `TiAdmobUnifiedInterstitialAdProxy.java` | Interstitial proxy |
116
120
  | `TiAdmobUnifiedRewardedAdProxy.java` | Rewarded proxy |
121
+ | `TiAdmobUnifiedRewardedInterstitialAdProxy.java` | Rewarded interstitial proxy |
117
122
  | `TiAdmobUnifiedAppOpenAdProxy.java` | App open proxy and the four hour validity window |
118
123
 
119
124
  Maven coordinates are declared in `android/build.gradle`. Build from the module root:
@@ -141,7 +146,7 @@ Do not add a public method or constant on one platform without checking and docu
141
146
  For a new or changed method, property, event, payload key, or constant:
142
147
 
143
148
  1. Define the portable JavaScript contract first.
144
- 2. Implement it on iOS and Android, or document the platform limitation explicitly.
149
+ 2. Implement the same JavaScript API on iOS and Android. Document native SDK limitations without adding a public method on only one platform.
145
150
  3. Preserve existing supported use cases.
146
151
  4. Make cleanup and repeated lifecycle calls deterministic.
147
152
  5. Add contract tests for both native sources.
@@ -223,6 +228,6 @@ Contributions are licensed under the [MIT License](module-license.txt).
223
228
 
224
229
  ### Native wrapper behavior harness
225
230
 
226
- Run `python3 tests/native/android.py` with a JDK, and `python3 tests/native/run.py` on macOS. The Java harness checks percentage validation, the TCF preference store and consent reset ordering. It compiles the current Objective-C method bodies against controlled Foundation-based SDK stand-ins and checks volume validation, load-error mapping, consent retry/reset ordering and delayed reward callbacks. It does not replace a Titanium consumer build, native bridge checks or Google ad presentation tests. `npm test` separately exercises the JavaScript library and example, alongside static contract checks.
231
+ Run `python3 tests/native/android.py` with a JDK, and `python3 tests/native/run.py` on macOS. The Java harness checks percentage validation, the TCF preference store and consent reset ordering. The Objective-C harness compiles the current method bodies against controlled Foundation-based SDK stand-ins and checks volume validation, load-error mapping, consent retry/reset ordering and delayed reward callbacks. It does not replace a Titanium consumer build, native bridge checks or Google ad presentation tests. `npm test` separately exercises the JavaScript library and example, alongside static contract checks.
227
232
 
228
233
  After individual platform builds, run `python3 scripts/prepare-package-docs.py` before `python3 scripts/verify-packages.py`. Titanium renders guides as HTML without rewriting their Markdown links. The preparation step fixes links between generated guides and includes the linked Markdown sources for offline use. `scripts/build-all.sh` runs both steps automatically.
@@ -1,19 +1,23 @@
1
- > Source snapshot: official ti.admob.unified 1.0.0 documentation at commit `5b4cbf9` (copied 2026-10-11). Relative links rebased for this skill.
1
+ > Source snapshot: official ti.admob.unified 1.0.0 documentation at release source commit `034843299b2984253988e0ffccb9f6a1c91682c9` (copied 2026-10-24). Relative links rebased for this skill.
2
2
 
3
3
  # Dependency inventory
4
4
 
5
- The core and five optional complements use the published versions verified on September 23, 2026. Each module has its own iOS Podfile, lockfile and framework checksum inventory. Android pins live in each module’s `android/build.gradle`.
5
+ The core and five optional complements use the published SDK and adapter pairs verified on October 23, 2026. Each module has its own iOS Podfile, lockfile and framework checksum inventory. Android pins live in each module's `android/build.gradle`.
6
+
7
+ The latest published Google adapters determine the network SDK versions. Meta iOS SDK `6.22.1` and InMobi Android SDK `11.5.1` are available independently, but their current Google adapters pin `6.22.0` and `11.5.0` respectively; those tested pairs are retained. Do not replace a network SDK independently of its adapter. InMobi Android adapter `11.5.0.1` is available as an AAR and POM in Google's Maven repository, although its documentation heading still says "In progress".
8
+
9
+ Google currently lists GMA iOS `13.x` and Android `25.x` as supported. Check both the [iOS sunset schedule](https://developers.google.com/admob/ios/deprecation) and [Android sunset schedule](https://developers.google.com/admob/android/deprecation), plus SDK/provider advisories, before distributing an app update. A supported major version and a store-specific SDK warning are separate checks; review any warning against the final app's resolved dependencies.
6
10
 
7
11
  ## iOS vendored XCFrameworks: `ti.admob.unified`
8
12
 
9
13
  | Component | Framework | Version |
10
14
  | ----------------------- | ----------------------------------- | -------: |
11
- | Google Mobile Ads | `GoogleMobileAds.xcframework` | `13.10.0` |
15
+ | Google Mobile Ads | `GoogleMobileAds.xcframework` | `13.11.0` |
12
16
  | User Messaging Platform | `UserMessagingPlatform.xcframework` | `3.1.0` |
13
17
 
14
18
  ## iOS per-network complements
15
19
 
16
- The eleven frameworks are stored without duplication under `mediation/<network>/ios/platform/`: AppLovin (2), Meta (2), InMobi (2), Unity (3), Liftoff (2). Unity Ads 4.20.1 no longer requires IronSourceAdQualitySDK. No ironSource advertising adapter or SDK is distributed.
20
+ The eleven frameworks are stored without duplication under `mediation/<network>/ios/platform/`: AppLovin (2), Meta (2), InMobi (2), Unity (3), Liftoff (2). Unity Ads 4.21.0 no longer requires IronSourceAdQualitySDK. No ironSource advertising adapter or SDK is distributed.
17
21
 
18
22
  | Component | Framework | Version |
19
23
  | ------------------------- | ------------------------------------ | -----------: |
@@ -21,15 +25,15 @@ The eleven frameworks are stored without duplication under `mediation/<network>/
21
25
  | AppLovin SDK | `AppLovinSDK.xcframework` | `13.6.4` |
22
26
  | Meta adapter | `MetaAdapter.xcframework` | `6.22.0.0` |
23
27
  | Meta Audience Network SDK | `FBAudienceNetwork.xcframework` | `6.22.0` |
24
- | InMobi adapter | `InMobiAdapter.xcframework` | `11.4.1.0` |
25
- | InMobi SDK | `InMobiSDK.xcframework` | `11.4.1` |
26
- | Unity adapter | `UnityAdapter.xcframework` | `4.20.1.0` |
27
- | Unity Ads SDK | `UnityAds.xcframework` | `4.20.1` |
28
- | Unity support library | `UnityCoherenceLib.xcframework` | `0.1.0` |
29
- | Liftoff Monetize adapter | `LiftoffMonetizeAdapter.xcframework` | `7.7.7.0` |
30
- | Vungle Ads SDK | `VungleAdsSDK.xcframework` | `7.7.7` |
28
+ | InMobi adapter | `InMobiAdapter.xcframework` | `11.5.0.0` |
29
+ | InMobi SDK | `InMobiSDK.xcframework` | `11.5.0` |
30
+ | Unity adapter | `UnityAdapter.xcframework` | `4.21.0.0` |
31
+ | Unity Ads SDK | `UnityAds.xcframework` | `4.21.0` |
32
+ | Unity support library | `UnityCoherenceLib.xcframework` | `0.2.0` |
33
+ | Liftoff Monetize adapter | `LiftoffMonetizeAdapter.xcframework` | `7.7.8.0` |
34
+ | Vungle Ads SDK | `VungleAdsSDK.xcframework` | `7.7.8` |
31
35
 
32
- The version column is the pinned CocoaPods version; lockfiles record the resolved adapter and SDK pair. Meta now uses SDK 6.22.0 on both platforms. Liftoff uses SDK 7.7.7 on iOS and 7.7.8 on Android. The version contract test retains this remaining difference and checks the matching networks.
36
+ The version column is the pinned CocoaPods version; lockfiles record the resolved adapter and SDK pair. Meta now uses SDK 6.22.0 on both platforms. Liftoff uses SDK 7.7.8 on iOS and 7.7.9 on Android. The version contract test records this difference and checks the networks whose versions match.
33
37
 
34
38
  The official CocoaPods specifications resolve the adapter and matching network SDK pairs. Each module has its own `ios/install_frameworks.sh`: it downloads that module's exact Podfile versions, stages its framework set, verifies its tree hashes, and restores the previous platform directory if validation fails. Run `ios/install_frameworks.sh` for the two core frameworks and `mediation/<network>/ios/install_frameworks.sh` for one complement. Complement installers use `pod install --deployment` to preserve the locked resolution.
35
39
 
@@ -48,7 +52,7 @@ Declared in `android/build.gradle`.
48
52
  | ------------------------------------------------ | ------: |
49
53
  | `com.google.android.gms:play-services-ads` | 25.5.0 |
50
54
  | `com.google.android.ump:user-messaging-platform` | 4.0.0 |
51
- | `com.google.guava:guava` | 33.7.1-android |
55
+ | `com.google.guava:guava` | 33.7.2-android |
52
56
 
53
57
  ## Android per-network complements
54
58
 
@@ -57,12 +61,14 @@ Declared separately in `mediation/<network>/android/build.gradle`; `meta` uses t
57
61
  | Coordinate | Version |
58
62
  | ----------------------------------- | -------: |
59
63
  | `com.google.ads.mediation:facebook` | 6.22.0.1 |
60
- | `com.google.ads.mediation:inmobi` | 11.4.1.2 |
61
- | `com.google.ads.mediation:unity` | 4.20.1.0 |
64
+ | `com.google.ads.mediation:inmobi` | 11.5.0.1 |
65
+ | `com.google.ads.mediation:unity` | 4.21.0.0 |
62
66
  | `com.google.ads.mediation:applovin` | 13.6.4.2 |
63
- | `com.google.ads.mediation:vungle` | 7.7.8.1 |
67
+ | `com.google.ads.mediation:vungle` | 7.7.9.0 |
68
+
69
+ Each complement declares its adapter coordinate. Unity also explicitly declares `com.unity3d.ads:unity-ads:4.21.0`: Google's adapter POM does not bring the Unity SDK transitively. Both entries must reach the packaged POM and consumer graph. See Google's [Unity Android integration guide](https://developers.google.com/admob/android/mediation/unity).
64
70
 
65
- Each complement declares one adapter coordinate. InMobi and Liftoff also pin OkHttp 4.12.0. This replaces InMobi’s 3.14.9 and lifts Liftoff’s Okio dependency above the affected 3.0.0 release while retaining the okhttp3 API. Generated POMs propagate these versions and the matching network SDK into the consuming application. The core POM declares GMA, UMP and a patched Guava utility dependency. Guava replaces the older transitive version; it adds no ad network. Inspect all six POMs and resolved consumer dependency graphs before release.
71
+ InMobi, Liftoff and Unity also pin `com.squareup.okhttp3:okhttp:5.4.0` and `com.squareup.okio:okio:3.18.2`. OkHttp 5.4.0 requires compile SDK 36, provided by the declared minimum Titanium 13.4.1.GA. OkHttp 5.5.x requires compile SDK 37 and remains incompatible with this stable Titanium toolchain. Okio fixes base64 compatibility with callers compiled against pre-3.18 releases. These utility dependencies add no ad networks. The core pins Guava `33.7.2-android` for its deserialization allocation fix. Unity Ads 4.21.0 requests OkHttp 3.12.13 and Okio 1.15.0 without these overrides; both matched advisories during the isolated-consumer scan. Generated POMs propagate the reviewed versions into consumer applications.
66
72
 
67
73
  ## Update policy
68
74
 
@@ -70,16 +76,16 @@ All six modules remain at version `1.0.0`. Dependency updates require rebuilding
70
76
 
71
77
  ## Transitive security review
72
78
 
73
- The September 23, 2026 refresh checks resolved dependencies for all eight Android consumer combinations. Updating the ad adapters alone still selected older utility libraries, so the distributed POMs include these corrections:
79
+ The October 23 refresh updates the direct utility overrides as well as the ad SDKs:
74
80
 
75
- | Dependency | Previous resolution | Updated resolution | Where the pin lives |
81
+ | Dependency | Previous pin | Current pin | Modules |
76
82
  | --- | --- | --- | --- |
77
- | Guava | `31.1-android` in core and several combinations | `33.7.1-android` | Core Android module |
78
- | OkHttp | `3.14.9` with InMobi; `4.10.0` with Liftoff | `4.12.0` | InMobi and Liftoff Android complements |
79
- | Okio / Okio-jvm | `3.0.0` with Liftoff | At least `3.6.0`, through OkHttp; InMobi selects `3.7.0` | Resolved transitively |
83
+ | Guava | `33.7.1-android` | `33.7.2-android` | Core |
84
+ | OkHttp | `4.12.0` | `5.4.0` | InMobi, Liftoff, Unity |
85
+ | Okio | Transitive, including `3.6.0` / `3.7.0` | `3.18.2` | InMobi, Liftoff, Unity |
80
86
 
81
- Guava's Android variant requires API 24, matching this module's existing floor. [Guava release notes](https://github.com/google/guava/releases/tag/v33.7.1) identify the published Android artifact. [OkHttp 4's compatibility guide](https://lysine.dev/okhttp/changelogs/upgrading_to_okhttp_4/) documents binary compatibility with the okhttp3 API; its [4.x changelog](https://lysine.dev/okhttp/changelogs/changelog_4x/) records the hostname-verification fix and Okio update. These are utility dependencies, not additional ad networks.
87
+ Guava's [33.7.2 release](https://github.com/google/guava/releases/tag/v33.7.2) documents the allocation fix. OkHttp's [changelog](https://lysine.dev/okhttp/changelogs/changelog/) documents later releases, but 5.4.0 is the latest compatible pin because of the Android AAR compile-SDK requirements above. The 5.5.1 certificate-blocklist change is not included in this compatible pin; runtime OS support and compile-SDK requirements are separate constraints. The [Okio changelog](https://lysine.dev/okio/changelog/) describes the 3.18.2 compatibility correction.
82
88
 
83
- The earlier matches were `GHSA-5mg8-w23w-74h3`, `GHSA-7g45-4rm6-3mm3` (Guava), `GHSA-3cqm-mf7h-prrj` (OkHttp) and `GHSA-w33c-445m-f8w7` (Okio). The final [OSV querybatch](https://google.github.io/osv.dev/api/) scan covered 149 distinct Maven name/version pairs across all eight consumer combinations and returned no matches on September 23, 2026. A version scan does not establish provider delivery or prove that every internal SDK path is safe.
89
+ The October 23 [OSV querybatch](https://google.github.io/osv.dev/api/) scan covered 151 distinct resolved Maven name/version pairs across eight configurations: core, each complement, AppLovin + Unity, and all networks. No matches remained after the Unity utility overrides. The earlier September scan describes the old matrix. Dependency scanning and successful linking do not establish provider ad delivery.
84
90
 
85
- Unity `4.20.1.0` includes the adapter consent-forwarding update. Provider-side verification is described in the [mediation guide](mediation.md#unity-consent-with-the-pinned-adapter).
91
+ Unity `4.21.0.0` includes the adapter consent-forwarding update. Provider-side verification is described in the [mediation guide](mediation.md#unity-consent-with-the-pinned-adapter).