@highfivve/ad-tag 5.5.4

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 (132) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +149 -0
  3. package/lib/ads/a9.js +190 -0
  4. package/lib/ads/adPipeline.js +159 -0
  5. package/lib/ads/adService.js +251 -0
  6. package/lib/ads/adUnitPath.js +37 -0
  7. package/lib/ads/auctions/adRequestThrottling.js +22 -0
  8. package/lib/ads/auctions/biddersDisabling.js +90 -0
  9. package/lib/ads/auctions/frequencyCapping.js +189 -0
  10. package/lib/ads/auctions/interstitialContext.js +92 -0
  11. package/lib/ads/auctions/previousBidCpms.js +33 -0
  12. package/lib/ads/auctions/resume.js +3 -0
  13. package/lib/ads/bridge/bridge.js +62 -0
  14. package/lib/ads/consent.js +63 -0
  15. package/lib/ads/eventService.js +44 -0
  16. package/lib/ads/globalAuctionContext.js +98 -0
  17. package/lib/ads/googleAdManager.js +380 -0
  18. package/lib/ads/keyValues.js +1 -0
  19. package/lib/ads/labelConfigService.js +42 -0
  20. package/lib/ads/modules/ad-reload/adVisibilityService.js +158 -0
  21. package/lib/ads/modules/ad-reload/index.js +163 -0
  22. package/lib/ads/modules/ad-reload/userActivityService.js +70 -0
  23. package/lib/ads/modules/adex/adex-mapping.js +77 -0
  24. package/lib/ads/modules/adex/adexUtiq.js +15 -0
  25. package/lib/ads/modules/adex/index.js +142 -0
  26. package/lib/ads/modules/adex/sendAdvertisingId.js +20 -0
  27. package/lib/ads/modules/blocklist-url/index.js +118 -0
  28. package/lib/ads/modules/cleanup/index.js +93 -0
  29. package/lib/ads/modules/confiant/index.js +47 -0
  30. package/lib/ads/modules/emetriq/index.js +154 -0
  31. package/lib/ads/modules/emetriq/trackInApp.js +34 -0
  32. package/lib/ads/modules/emetriq/trackLoginEvent.js +59 -0
  33. package/lib/ads/modules/generic-skin/index.js +150 -0
  34. package/lib/ads/modules/identitylink/index.js +58 -0
  35. package/lib/ads/modules/interstitial/index.js +38 -0
  36. package/lib/ads/modules/interstitial/interstitialAd.js +111 -0
  37. package/lib/ads/modules/lazy-load/index.js +191 -0
  38. package/lib/ads/modules/lazy-load/selectInfiniteSlot.js +11 -0
  39. package/lib/ads/modules/prebid-first-party-data/index.js +115 -0
  40. package/lib/ads/modules/pubstack/index.js +59 -0
  41. package/lib/ads/modules/sticky-footer-ad/desktopFloorAd.js +63 -0
  42. package/lib/ads/modules/sticky-footer-ad/index.js +43 -0
  43. package/lib/ads/modules/sticky-footer-ad/mobileSticky.js +93 -0
  44. package/lib/ads/modules/sticky-footer-ad-v2/footerStickyAd.js +118 -0
  45. package/lib/ads/modules/sticky-footer-ad-v2/index.js +43 -0
  46. package/lib/ads/modules/sticky-header-ad/fadeOutCallback.js +25 -0
  47. package/lib/ads/modules/sticky-header-ad/index.js +103 -0
  48. package/lib/ads/modules/sticky-header-ad/renderResult.js +24 -0
  49. package/lib/ads/modules/utiq/index.js +79 -0
  50. package/lib/ads/modules/yield-optimization/dynamicFloorPrice.js +86 -0
  51. package/lib/ads/modules/yield-optimization/index.js +57 -0
  52. package/lib/ads/modules/yield-optimization/isYieldOptimizationConfigDynamic.js +6 -0
  53. package/lib/ads/modules/yield-optimization/yieldOptimizationService.js +169 -0
  54. package/lib/ads/modules/zeotap/index.js +111 -0
  55. package/lib/ads/moli.js +645 -0
  56. package/lib/ads/moliGlobal.js +11 -0
  57. package/lib/ads/prebid-outstream.js +13 -0
  58. package/lib/ads/prebid.js +406 -0
  59. package/lib/ads/sizeConfigService.js +49 -0
  60. package/lib/ads/spa.js +32 -0
  61. package/lib/bundle/adReload.js +2 -0
  62. package/lib/bundle/adex.js +2 -0
  63. package/lib/bundle/blocklistUrls.js +2 -0
  64. package/lib/bundle/cleanup.js +2 -0
  65. package/lib/bundle/confiant.js +2 -0
  66. package/lib/bundle/configureFromEndpoint.js +40 -0
  67. package/lib/bundle/emetriq.js +2 -0
  68. package/lib/bundle/identityLink.js +2 -0
  69. package/lib/bundle/init.js +2 -0
  70. package/lib/bundle/interstitialModule.js +2 -0
  71. package/lib/bundle/lazyLoad.js +2 -0
  72. package/lib/bundle/prebidFirstPartyData.js +2 -0
  73. package/lib/bundle/pubstack.js +2 -0
  74. package/lib/bundle/skin.js +2 -0
  75. package/lib/bundle/stickyFooterAd.js +2 -0
  76. package/lib/bundle/stickyFooterAds2.js +2 -0
  77. package/lib/bundle/stickyHeaderAd.js +2 -0
  78. package/lib/bundle/utiq.js +2 -0
  79. package/lib/bundle/yieldOptimization.js +2 -0
  80. package/lib/bundle/zeotap.js +2 -0
  81. package/lib/console/components/adSlotConfig.js +225 -0
  82. package/lib/console/components/consentConfig.js +138 -0
  83. package/lib/console/components/globalConfig.js +634 -0
  84. package/lib/console/components/labelConfigDebug.js +19 -0
  85. package/lib/console/components/sizeConfigDebug.js +34 -0
  86. package/lib/console/components/tag.js +4 -0
  87. package/lib/console/debug.js +38 -0
  88. package/lib/console/util/array.js +1 -0
  89. package/lib/console/util/calculateAdDensity.js +36 -0
  90. package/lib/console/util/debounce.js +12 -0
  91. package/lib/console/util/debugLogger.js +6 -0
  92. package/lib/console/util/extractPositionFromPath.js +8 -0
  93. package/lib/console/util/prebid.js +3 -0
  94. package/lib/console/util/stringUtils.js +23 -0
  95. package/lib/console/util/themingService.js +31 -0
  96. package/lib/console/util/windowResizeService.js +22 -0
  97. package/lib/console/validations/adReloadValidations.js +47 -0
  98. package/lib/console/validations/bucketValidations.js +78 -0
  99. package/lib/console/validations/sizesConfigValidations.js +97 -0
  100. package/lib/gen/packageJson.js +3 -0
  101. package/lib/index.js +3 -0
  102. package/lib/types/apstag.js +1 -0
  103. package/lib/types/dom.js +1 -0
  104. package/lib/types/emetriq.js +1 -0
  105. package/lib/types/googletag.js +1 -0
  106. package/lib/types/identitylink.js +1 -0
  107. package/lib/types/module.js +1 -0
  108. package/lib/types/moliConfig.js +1 -0
  109. package/lib/types/moliRuntime.js +1 -0
  110. package/lib/types/prebidjs.js +45 -0
  111. package/lib/types/supplyChainObject.js +1 -0
  112. package/lib/types/tcfapi.js +48 -0
  113. package/lib/util/addNewInfiniteSlotToConfig.js +11 -0
  114. package/lib/util/arrayUtils.js +9 -0
  115. package/lib/util/assetLoaderService.js +91 -0
  116. package/lib/util/browserStorageKeys.js +7 -0
  117. package/lib/util/debugDelay.js +12 -0
  118. package/lib/util/domready.js +15 -0
  119. package/lib/util/environmentOverride.js +16 -0
  120. package/lib/util/extractAdTagVersion.js +16 -0
  121. package/lib/util/extractTopPrivateDomainFromHostname.js +17 -0
  122. package/lib/util/localStorage.js +26 -0
  123. package/lib/util/logging.js +106 -0
  124. package/lib/util/objectUtils.js +29 -0
  125. package/lib/util/query.js +40 -0
  126. package/lib/util/queryParameters.js +5 -0
  127. package/lib/util/resolveOverrides.js +21 -0
  128. package/lib/util/resolveStoredRequestIdInOrtb2Object.js +12 -0
  129. package/lib/util/sizes.js +3 -0
  130. package/lib/util/test-slots.js +150 -0
  131. package/lib/util/uuid.js +10 -0
  132. package/package.json +127 -0
@@ -0,0 +1,634 @@
1
+ import React, { Component, Fragment } from 'react';
2
+ import { AdSlotConfig } from './adSlotConfig';
3
+ import { Tag, TagLabel } from './tag';
4
+ import { classList } from '../util/stringUtils';
5
+ import { ConsentConfig } from './consentConfig';
6
+ import { LabelConfigDebug } from './labelConfigDebug';
7
+ import { extractPrebidAdSlotConfigs } from '../util/prebid';
8
+ import { checkAdReloadConfig } from '../validations/adReloadValidations';
9
+ import { checkSizesConfig } from '../validations/sizesConfigValidations';
10
+ import { checkBucketConfig, checkSkinConfig } from '../validations/bucketValidations';
11
+ import { getActiveEnvironmentOverride, resetEnvironmentOverrides, setEnvironmentOverrideInStorage } from '../../util/environmentOverride';
12
+ import { getDebugDelayFromLocalStorage, setDebugDelayToLocalStorage } from 'ad-tag/util/debugDelay';
13
+ import { removeTestSlotSizeFromLocalStorage } from 'ad-tag/util/test-slots';
14
+ import styles from './../debug.pcss';
15
+ import { resolveOverrides } from 'ad-tag/util/resolveOverrides';
16
+ import { QueryParameters } from 'ad-tag/util/queryParameters';
17
+ import { BrowserStorageKeys } from 'ad-tag/util/browserStorageKeys';
18
+ import { calculateAdDensity } from 'ad-tag/console/util/calculateAdDensity';
19
+ import { extractPositionFromPath } from 'ad-tag/console/util/extractPositionFromPath';
20
+ import { getBrowserStorageValue, removeBrowserStorageValue, setBrowserStorageValue } from 'ad-tag/util/localStorage';
21
+ const debugSidebarSelector = 'moli-debug-sidebar';
22
+ export class GlobalConfig extends Component {
23
+ constructor(props) {
24
+ super(props);
25
+ this.listener = () => {
26
+ this.setState({ browserResized: true });
27
+ };
28
+ this.componentWillUnmount = () => {
29
+ this.props.windowResizeService.unregister(this);
30
+ };
31
+ this.resetEnvironmentOverrides = () => {
32
+ resetEnvironmentOverrides(window);
33
+ };
34
+ this.overrideEnvironmentToTest = () => {
35
+ setEnvironmentOverrideInStorage('test', localStorage);
36
+ window.location.reload();
37
+ };
38
+ this.overrideConfigVersion = (version) => {
39
+ window.localStorage.setItem(BrowserStorageKeys.moliVersion, version);
40
+ window.location.reload();
41
+ };
42
+ this.clearConfigVersionOverride = () => {
43
+ window.localStorage.removeItem(BrowserStorageKeys.moliVersion);
44
+ };
45
+ this.unwrapConfig = (moduleConfig, subEntry = false) => {
46
+ return (React.createElement(Fragment, null, Object.keys(moduleConfig).map((key, index) => {
47
+ const configValue = moduleConfig[key];
48
+ const configValueType = typeof configValue === 'object'
49
+ ? Array.isArray(configValue)
50
+ ? 'array'
51
+ : 'object'
52
+ : 'other';
53
+ return (React.createElement("div", { key: index, className: classList('MoliDebug-tagContainer', [
54
+ subEntry,
55
+ 'MoliDebug-tagContainer--subEntry'
56
+ ]) },
57
+ React.createElement(TagLabel, null, key),
58
+ configValueType === 'array' &&
59
+ (configValue.length === 0 ? (React.createElement("i", null, "No values")) : (configValue.map((value, index) => typeof value === 'object' ? (this.unwrapConfig(value, true)) : (React.createElement(Tag, { variant: "green", key: index }, value !== undefined ? value.toString() : 'undefined'))))),
60
+ configValueType === 'object' && this.unwrapConfig(configValue, true),
61
+ configValueType === 'other' && configValue !== undefined && (React.createElement(Tag, { variant: "green" }, configValue.toString()))));
62
+ })));
63
+ };
64
+ this.setTheme = (theme) => this.setState({ theme }, () => this.props.themingService.applyTheme(theme));
65
+ this.keyValues = (keyValues) => {
66
+ const properties = Object.keys(keyValues);
67
+ return properties.length > 0 ? (React.createElement("table", { className: "MoliDebug-keyValueTable" },
68
+ React.createElement("thead", null,
69
+ React.createElement("tr", null,
70
+ React.createElement("th", null, "Key"),
71
+ React.createElement("th", null, "Value"))),
72
+ React.createElement("tbody", null, properties.map((key) => {
73
+ const value = keyValues[key];
74
+ return (React.createElement("tr", { key: key },
75
+ React.createElement("td", null, key),
76
+ React.createElement("td", null, Array.isArray(value)
77
+ ? value.map(this.standardTagFromString)
78
+ : this.standardTagFromString(value))));
79
+ })))) : (React.createElement("span", null, "No key/values config present."));
80
+ };
81
+ this.labels = (labels) => {
82
+ return (React.createElement("div", { className: "MoliDebug-tagContainer" },
83
+ labels &&
84
+ labels.map((label, index) => (React.createElement(Tag, { key: index, variant: "blue", spacing: "medium" }, label))),
85
+ (!labels || labels.length === 0) && React.createElement("span", null, "No labels present.")));
86
+ };
87
+ this.filterSetting = (name, filterSetting) => {
88
+ return (React.createElement("div", null,
89
+ React.createElement("strong", null, name),
90
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
91
+ React.createElement(TagLabel, null, "Bidders"),
92
+ filterSetting.bidders === '*'
93
+ ? this.standardTagFromString('all')
94
+ : filterSetting.bidders.map(this.standardTagFromString)),
95
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
96
+ React.createElement(TagLabel, null, "Include/exclude"),
97
+ this.standardTagFromString(filterSetting.filter))));
98
+ };
99
+ this.standardTagFromString = (content) => {
100
+ return React.createElement(Tag, { key: content }, content);
101
+ };
102
+ this.toggleSidebar = () => {
103
+ this.setState({ sidebarHidden: !this.state.sidebarHidden });
104
+ };
105
+ this.collapseToggle = (section) => {
106
+ const toggleValue = (section) => {
107
+ const oldVal = this.state.expandSection[section];
108
+ this.setState({ expandSection: { ...this.state.expandSection, [section]: !oldVal } });
109
+ };
110
+ return (React.createElement("button", { className: "MoliDebug-adSlot-button", title: `${this.state.expandSection[section] ? 'collapse' : 'expand'} ${section}`, onClick: () => toggleValue(section) }, this.state.expandSection[section] ? '⊖' : '⊕'));
111
+ };
112
+ this.iconForMessageKind = (kind) => {
113
+ return (React.createElement("span", { className: "MoliDebug-configMessage-icon" },
114
+ kind === 'error' && React.createElement("span", null, "\u2757"),
115
+ kind === 'warning' && React.createElement("span", null, "\u26A0"),
116
+ kind === 'empty' && React.createElement("span", null, "\u2714")));
117
+ };
118
+ this.reportMissingConfig = (messages) => {
119
+ messages.push({
120
+ kind: 'error',
121
+ text: 'No moli config found.'
122
+ });
123
+ };
124
+ this.checkForDuplicateOrMissingSlots = (messages, slot) => {
125
+ const count = document.querySelectorAll(`[id='${slot.domId}']`).length;
126
+ if (count > 1) {
127
+ messages.push({
128
+ kind: 'warning',
129
+ text: (React.createElement("span", null,
130
+ count,
131
+ " DOM elements with id ",
132
+ React.createElement("strong", null, slot.domId),
133
+ " found. This may lead to unexpected results."))
134
+ });
135
+ }
136
+ if (count === 0) {
137
+ messages.push({
138
+ kind: 'warning',
139
+ text: (React.createElement("span", null,
140
+ "No DOM element with id ",
141
+ React.createElement("strong", null, slot.domId),
142
+ " found. Slot will not be rendered."))
143
+ });
144
+ }
145
+ };
146
+ this.checkPrebidConfig = (messages, prebid) => {
147
+ if (!prebid.config.consentManagement) {
148
+ messages.push({
149
+ kind: 'error',
150
+ text: 'No prebid consentManagement configuration found.'
151
+ });
152
+ }
153
+ if (!window.pbjs.version) {
154
+ messages.push({
155
+ kind: 'error',
156
+ text: 'No prebid instance available! Either remove the prebid configuration or add prebid to the ad tag'
157
+ });
158
+ }
159
+ };
160
+ this.checkSlotPrebidConfig = (messages, slot) => {
161
+ if (slot.prebid) {
162
+ const labels = this.props.labelConfigService.getSupportedLabels();
163
+ extractPrebidAdSlotConfigs(slot.prebid).forEach(prebidConfig => {
164
+ const mediaTypes = prebidConfig.adUnit.mediaTypes;
165
+ if (!!mediaTypes && !mediaTypes.banner && !mediaTypes.video) {
166
+ messages.push({
167
+ kind: 'error',
168
+ text: `Prebidjs mediaTypes for slot ${slot.domId} | ${slot.adUnitPath} is empty.`
169
+ });
170
+ }
171
+ });
172
+ }
173
+ };
174
+ this.checkGlobalSizeConfigEntry = (messages) => (entry, _) => {
175
+ if (entry.labelsSupported.length === 0) {
176
+ messages.push({
177
+ kind: 'warning',
178
+ text: `No Global LabelSizeConfig entries. We recommend defining labels.`
179
+ });
180
+ }
181
+ };
182
+ this.checkForWrongPrebidCodeEntry = (messages, slot) => {
183
+ if (slot.prebid) {
184
+ const labels = this.props.labelConfigService.getSupportedLabels();
185
+ extractPrebidAdSlotConfigs(slot.prebid).forEach(prebidConfig => {
186
+ const code = prebidConfig.adUnit.code;
187
+ if (code && code !== slot.domId) {
188
+ messages.push({
189
+ kind: 'error',
190
+ text: (React.createElement("span", null,
191
+ "The ",
192
+ React.createElement("code", null, "prebid.adUnit.code"),
193
+ " must match the ",
194
+ React.createElement("code", null, "slot.domID"),
195
+ ' ',
196
+ React.createElement("strong", null,
197
+ "$",
198
+ slot.domId),
199
+ ", but",
200
+ React.createElement("br", null),
201
+ " ",
202
+ React.createElement("strong", null, code),
203
+ " was not ",
204
+ React.createElement("strong", null, slot.domId)))
205
+ });
206
+ }
207
+ });
208
+ }
209
+ };
210
+ this.isSlotRendered = (slot) => !!document.getElementById(slot.domId) && this.props.labelConfigService.filterSlot(slot);
211
+ this.state = {
212
+ sidebarHidden: false,
213
+ expandSection: {
214
+ slots: true,
215
+ moli: true,
216
+ modules: false,
217
+ targeting: false,
218
+ prebid: false,
219
+ a9: false,
220
+ labelSizeConfig: false,
221
+ consent: false,
222
+ yieldOptimization: false,
223
+ supplyChain: false,
224
+ adDensity: false
225
+ },
226
+ messages: [],
227
+ browserResized: false,
228
+ showOnlyRenderedSlots: false,
229
+ theme: props.themingService.currentTheme(),
230
+ adstxtEntry: [],
231
+ adstxtDomain: '',
232
+ adstxtError: '',
233
+ adDensity: {
234
+ totalAdDensity: undefined,
235
+ percentagePerSlot: []
236
+ },
237
+ configVersion: 'not available'
238
+ };
239
+ if (!props.config) {
240
+ this.reportMissingConfig(this.state.messages);
241
+ }
242
+ else {
243
+ props.config.slots.forEach(slot => {
244
+ this.checkForDuplicateOrMissingSlots(this.state.messages, slot);
245
+ this.checkSlotPrebidConfig(this.state.messages, slot);
246
+ this.checkForWrongPrebidCodeEntry(this.state.messages, slot);
247
+ });
248
+ if (props.config.prebid) {
249
+ this.checkPrebidConfig(this.state.messages, props.config.prebid);
250
+ }
251
+ if (props.config.labelSizeConfig) {
252
+ props.config.labelSizeConfig.forEach(this.checkGlobalSizeConfigEntry(this.state.messages));
253
+ }
254
+ if (props.config.buckets) {
255
+ checkBucketConfig(this.state.messages, props.config.buckets, props.config.slots);
256
+ }
257
+ checkSkinConfig(this.state.messages, props.modules, props.config.slots);
258
+ checkAdReloadConfig(this.state.messages, props.modules, props.config.slots, this.props.labelConfigService.getSupportedLabels());
259
+ checkSizesConfig(this.state.messages, props.config.slots, this.props.labelConfigService.getSupportedLabels());
260
+ props.windowResizeService.register(this);
261
+ }
262
+ }
263
+ async fetchAdsTxtEntries(hostname) {
264
+ try {
265
+ if (hostname) {
266
+ const domain = hostname.startsWith('www.') ? hostname : `www.${hostname}`;
267
+ const response = await fetch(`https://${domain}/ads.txt`);
268
+ return await response.text();
269
+ }
270
+ }
271
+ catch (error) {
272
+ console.error(error);
273
+ }
274
+ }
275
+ refreshInterstitial(interstitialSlot) {
276
+ if (interstitialSlot) {
277
+ if (interstitialSlot.behaviour.loaded !== 'infinite') {
278
+ window.moli.refreshAdSlot(interstitialSlot.domId, {
279
+ loaded: interstitialSlot.behaviour.loaded
280
+ });
281
+ this.toggleSidebar();
282
+ }
283
+ else {
284
+ console.error("Interstitial slot's loading behaviour can not be of type 'infinite'.");
285
+ }
286
+ }
287
+ else {
288
+ console.error('Interstitial slot not found in the current config.');
289
+ }
290
+ }
291
+ parseAdsTxtEntries(adstxtEntries) {
292
+ const entriesArray = adstxtEntries.split(/\r?\n/).map(entry => entry.split(',')) ?? [];
293
+ const publisherEntry = entriesArray
294
+ .filter(entry => entry.length > 1)
295
+ .find(entry => entry[0] === 'highfivve.com');
296
+ return publisherEntry;
297
+ }
298
+ async findPublisherEntryInAdsTxt(adsTxtDomain) {
299
+ try {
300
+ const adstxtEntries = await this.fetchAdsTxtEntries(adsTxtDomain);
301
+ if (!adstxtEntries) {
302
+ throw new Error('Failed to fetch ads.txt entries.');
303
+ }
304
+ this.setState({ adstxtError: '' });
305
+ const publisherEntry = this.parseAdsTxtEntries(adstxtEntries);
306
+ return publisherEntry;
307
+ }
308
+ catch (error) {
309
+ if (error instanceof Error) {
310
+ this.setState({ adstxtError: error.message });
311
+ }
312
+ else {
313
+ this.setState({ adstxtError: 'An unknown error occurred.' });
314
+ }
315
+ return ['', 'error'];
316
+ }
317
+ }
318
+ async componentDidMount() {
319
+ const adsTxtDomain = this.props.config?.domain ?? window.location.hostname;
320
+ this.setState({
321
+ adstxtDomain: adsTxtDomain,
322
+ adstxtEntry: (await this.findPublisherEntryInAdsTxt(adsTxtDomain)) ?? [],
323
+ configVersion: this.props.config?.version ?? 'not available'
324
+ });
325
+ }
326
+ render() {
327
+ const { config, runtimeConfig, modules, labelConfigService } = this.props;
328
+ const configLabel = window.moli.configLabel ?? 'not available';
329
+ const currentConfigVersion = window.moli.getConfig()?.version ?? 'not available';
330
+ const isVersionOverridden = resolveOverrides(window, QueryParameters.moliVersion, BrowserStorageKeys.moliVersion).length >
331
+ 0;
332
+ const { sidebarHidden, showOnlyRenderedSlots, expandSection, theme, adstxtEntry, adstxtDomain, adDensity } = this.state;
333
+ const interstitialSlot = window.moli
334
+ .getConfig()
335
+ ?.slots.find(slot => slot.position === 'interstitial');
336
+ const classes = classList('MoliDebug-sidebar', [sidebarHidden, 'is-hidden']);
337
+ const showHideMessage = `${sidebarHidden ? 'Show' : 'Hide'} moli global config panel`;
338
+ const isEnvironmentOverridden = !!getActiveEnvironmentOverride(window);
339
+ const interstitialTestKey = 'test-interstitial';
340
+ const isInterstitialTestEnabled = !!getBrowserStorageValue(interstitialTestKey, localStorage);
341
+ const debugDelay = getDebugDelayFromLocalStorage(window);
342
+ const isDarkTheme = theme === 'dark';
343
+ const switchToDarkTheme = () => this.setTheme('dark');
344
+ const switchToLightTheme = () => this.setTheme('light');
345
+ return (React.createElement("div", { id: "moli-console-global-config" },
346
+ React.createElement("style", null, styles),
347
+ React.createElement("button", { className: "MoliDebug-sidebar-closeHandle", title: showHideMessage, onClick: this.toggleSidebar },
348
+ sidebarHidden && React.createElement("span", null, "\u2B05 "),
349
+ !sidebarHidden && React.createElement("span", null, "\u00D7 "),
350
+ showHideMessage),
351
+ config && (React.createElement("div", { className: classes, "data-ref": debugSidebarSelector },
352
+ React.createElement("div", { className: "MoliDebug-sidebarSection MoliDebug-sidebarSection--moli" },
353
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
354
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
355
+ React.createElement(TagLabel, null, "Config version"),
356
+ React.createElement(Tag, { variant: isVersionOverridden ? 'yellow' : 'blue' }, currentConfigVersion),
357
+ React.createElement("input", { type: "text", value: this.state.configVersion, placeholder: currentConfigVersion, onChange: e => {
358
+ this.setState({ configVersion: e.currentTarget.value });
359
+ } }),
360
+ React.createElement("button", { className: "MoliDebug-button", onClick: () => this.overrideConfigVersion(this.state.configVersion), title: "Reload" }, "load"),
361
+ React.createElement("button", { className: "MoliDebug-button MoliDebug-button--green", onClick: this.clearConfigVersionOverride, title: "Reset" }, "reset")),
362
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
363
+ React.createElement(TagLabel, null, "Config label"),
364
+ React.createElement(Tag, null, configLabel)),
365
+ React.createElement("br", null),
366
+ React.createElement(TagLabel, null, "Appearance"),
367
+ isDarkTheme && (React.createElement("button", { className: "MoliDebug-button", onClick: switchToLightTheme, title: "Switch to light theme" }, "\uD83C\uDF14 dark")),
368
+ !isDarkTheme && (React.createElement("button", { className: "MoliDebug-button", onClick: switchToDarkTheme, title: "Switch to dark theme" }, "\uD83C\uDF1E light"))),
369
+ React.createElement("h4", null,
370
+ this.collapseToggle('moli'),
371
+ "Moli ",
372
+ React.createElement("span", null, window.moli.version)),
373
+ expandSection.moli && (React.createElement("div", null,
374
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
375
+ React.createElement(TagLabel, null, "Overall Mode"),
376
+ runtimeConfig.environment === 'test' ? (React.createElement(Tag, { variant: "yellow" }, "Test")) : (React.createElement(Tag, { variant: "green" }, "Production")),
377
+ isEnvironmentOverridden ? (React.createElement("button", { className: "MoliDebug-button MoliDebug-button--green", onClick: this.resetEnvironmentOverrides }, "\u25C0 Reset override")) : (React.createElement("button", { className: "MoliDebug-button MoliDebug-button--yellow MoliDebug-button--greyText", onClick: this.overrideEnvironmentToTest }, "\u25B6 Override to test"))),
378
+ interstitialSlot && (React.createElement("div", { className: "MoliDebug-tagContainer" },
379
+ React.createElement(TagLabel, null, "Interstitital Test Mode"),
380
+ isInterstitialTestEnabled ? (React.createElement("button", { className: "MoliDebug-button MoliDebug-button--green", onClick: () => {
381
+ removeBrowserStorageValue(interstitialTestKey, localStorage);
382
+ this.refreshInterstitial(interstitialSlot);
383
+ } }, "\u25C0 Reset interstitial test")) : (React.createElement("button", { className: `MoliDebug-button MoliDebug-button--yellow MoliDebug-button--greyText ${!isEnvironmentOverridden ? 'MoliDebug-button--disabled' : ''}`, onClick: () => {
384
+ setBrowserStorageValue(interstitialTestKey, 'true', localStorage);
385
+ this.refreshInterstitial(interstitialSlot);
386
+ }, disabled: !isEnvironmentOverridden }, "\u25B6 Test interstitial")),
387
+ !isEnvironmentOverridden && (React.createElement("p", { className: "MoliDebug-info" }, "\u2757\uFE0FPlease activate the overall test mode before testing the interstitial.")))),
388
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
389
+ React.createElement(TagLabel, null, "Delay loading ads (only in test environment)"),
390
+ React.createElement("input", { type: "number", placeholder: "in milliseconds", value: debugDelay, list: "debug-delay-suggestions", disabled: runtimeConfig.environment !== 'test', onChange: e => setDebugDelayToLocalStorage(window, e.currentTarget.valueAsNumber) }),
391
+ React.createElement("datalist", { id: "debug-delay-suggestions" },
392
+ React.createElement("option", { value: 500 }),
393
+ React.createElement("option", { value: 1000 }),
394
+ React.createElement("option", { value: 2000 }),
395
+ React.createElement("option", { value: 3000 }))),
396
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
397
+ React.createElement("button", { className: "MoliDebug-button MoliDebug-button--blue", onClick: () => {
398
+ config.slots.forEach(removeTestSlotSizeFromLocalStorage);
399
+ window.location.reload();
400
+ } }, "\u25B6 Reset all test slot sizes")),
401
+ modules && (React.createElement(React.Fragment, null,
402
+ React.createElement("h5", null,
403
+ this.collapseToggle('modules'),
404
+ "Moli Modules"),
405
+ expandSection.modules && (React.createElement(React.Fragment, null, Object.entries(modules).map(([module, config], index) => {
406
+ const moduleConfig = config;
407
+ return (React.createElement("div", { key: index },
408
+ React.createElement("div", { className: "MoliDebug-tagContainer MoliDebug-module", "data-module-key": index + 1 },
409
+ React.createElement(Tag, { variant: moduleConfig.enabled ? 'green' : 'grey' }, module)),
410
+ moduleConfig && (React.createElement(Fragment, null,
411
+ React.createElement("h6", null, "Module Config"),
412
+ this.unwrapConfig(moduleConfig))),
413
+ index !== Object.keys(modules).length - 1 && React.createElement("hr", null)));
414
+ })))))))),
415
+ React.createElement("div", { className: "MoliDebug-sidebarSection MoliDebug-sidebarSection--slots" },
416
+ React.createElement("h4", null,
417
+ this.collapseToggle('slots'),
418
+ "Slots"),
419
+ expandSection.slots && (React.createElement("div", null,
420
+ React.createElement("div", { className: "MoliDebug-panel MoliDebug-panel--grey" },
421
+ "Slot sizes are annotated to show the origin of their validation state:",
422
+ React.createElement("ul", null,
423
+ React.createElement("li", null,
424
+ React.createElement("strong", null, "\u24C8"),
425
+ " means that the validation originates from the",
426
+ ' ',
427
+ React.createElement("strong", null, "slot's own sizeConfig"),
428
+ ","),
429
+ React.createElement("li", null,
430
+ React.createElement("strong", null, "\u24BC"),
431
+ " indicates that the validation was done using the",
432
+ ' ',
433
+ React.createElement("strong", null, "global sizeConfig"),
434
+ "."))),
435
+ React.createElement("div", { className: "MoliDebug-panel MoliDebug-panel--grey" },
436
+ React.createElement("label", { className: "MoliDebug-checkBox" },
437
+ React.createElement("input", { type: "checkbox", onChange: e => this.setState({
438
+ showOnlyRenderedSlots: e.target.checked
439
+ }) }),
440
+ "Show only rendered slots")),
441
+ config.slots.map((slot, index) => this.isSlotRendered(slot) || !showOnlyRenderedSlots ? (React.createElement("div", { key: index },
442
+ React.createElement("strong", null, slot.behaviour.loaded),
443
+ " slot with DOM ID",
444
+ ' ',
445
+ React.createElement("strong", null, slot.domId),
446
+ React.createElement(AdSlotConfig, { labelConfigService: labelConfigService, slot: slot }))) : null)))),
447
+ React.createElement("div", { className: "MoliDebug-sidebarSection MoliDebug-sidebarSection--targeting" },
448
+ React.createElement("h4", null,
449
+ this.collapseToggle('targeting'),
450
+ "Targeting"),
451
+ expandSection.targeting && (React.createElement("div", null,
452
+ config.targeting && (React.createElement("div", null,
453
+ React.createElement("h5", null, "Key/value pairs"),
454
+ this.keyValues({
455
+ ...config.targeting.keyValues,
456
+ ...runtimeConfig.keyValues
457
+ }),
458
+ React.createElement("h5", null, "Labels from publisher"),
459
+ this.labels([...runtimeConfig.labels, ...(config.targeting?.labels ?? [])]),
460
+ React.createElement("h5", null, "Labels from label size config"),
461
+ this.labels(labelConfigService
462
+ .getSupportedLabels()
463
+ .filter(l1 => !(config.targeting.labels || []).find(l2 => l2 === l1))))),
464
+ !config.targeting && React.createElement("span", null, "No targeting config present.")))),
465
+ React.createElement("div", { className: "MoliDebug-sidebarSection MoliDebug-sidebarSection--sizeConfig" },
466
+ React.createElement("h4", null,
467
+ this.collapseToggle('labelSizeConfig'),
468
+ "Label Size config"),
469
+ expandSection.labelSizeConfig && (React.createElement("div", null,
470
+ config.labelSizeConfig && config.labelSizeConfig.length > 0 && (React.createElement(LabelConfigDebug, { labelSizeConfig: config.labelSizeConfig })),
471
+ (!config.labelSizeConfig || config.labelSizeConfig.length === 0) && (React.createElement("span", null, "No size config present."))))),
472
+ config.prebid && (React.createElement("div", { className: "MoliDebug-sidebarSection MoliDebug-sidebarSection--prebid" },
473
+ React.createElement("h4", null,
474
+ this.collapseToggle('prebid'),
475
+ "Prebid"),
476
+ expandSection.prebid && (React.createElement("div", null,
477
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
478
+ React.createElement(TagLabel, null, "Version"),
479
+ window.pbjs.version ? (React.createElement(Tag, null, window.pbjs.version.toString())) : (React.createElement(Tag, { variant: "red" }, "Prebid not found"))),
480
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
481
+ React.createElement(TagLabel, null, "Prebid debug"),
482
+ React.createElement(Tag, { variant: config.prebid.config.debug ? 'yellow' : undefined }, config.prebid.config.debug ? 'enabled' : 'disabled')),
483
+ config.prebid.config.enableSendAllBids !== undefined && (React.createElement("div", { className: "MoliDebug-tagContainer" },
484
+ React.createElement(TagLabel, null, "sendAllBids enabled"),
485
+ React.createElement(Tag, null, config.prebid.config.enableSendAllBids.toString()))),
486
+ config.prebid.config.bidderTimeout && (React.createElement("div", { className: "MoliDebug-tagContainer" },
487
+ React.createElement(TagLabel, null, "Bidder timeout"),
488
+ React.createElement(Tag, null, `${config.prebid.config.bidderTimeout.toString()}ms`))),
489
+ config.prebid.config.consentManagement && (React.createElement("div", null,
490
+ React.createElement("h5", null, "Consent management"),
491
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
492
+ React.createElement(TagLabel, null, "allowAuctionWithoutConsent"),
493
+ React.createElement(Tag, null, (!!config.prebid.config.consentManagement.gdpr
494
+ ?.allowAuctionWithoutConsent ?? 'true').toString())),
495
+ config.prebid.config.consentManagement.gdpr?.cmpApi && (React.createElement("div", { className: "MoliDebug-tagContainer" },
496
+ React.createElement(TagLabel, null, "CMP API"),
497
+ React.createElement(Tag, null, config.prebid.config.consentManagement.gdpr?.cmpApi ?? 'iab'))),
498
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
499
+ React.createElement(TagLabel, null, "CMP timeout"),
500
+ React.createElement(Tag, null, `${config.prebid.config.consentManagement.gdpr?.timeout ?? 10000}ms`)))),
501
+ config.prebid.config.userSync && (React.createElement("div", null,
502
+ React.createElement("h5", null, "User sync"),
503
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
504
+ React.createElement(TagLabel, null, "Sync enabled"),
505
+ React.createElement(Tag, null, config.prebid.config.userSync.syncEnabled === undefined
506
+ ? `${window.pbjs
507
+ .getConfig()
508
+ .userSync?.syncEnabled?.toString()} (default from prebid config - no value in moli config)`
509
+ : config.prebid.config.userSync.syncEnabled.toString())),
510
+ config.prebid.config.userSync.syncDelay !== undefined && (React.createElement("div", { className: "MoliDebug-tagContainer" },
511
+ React.createElement(TagLabel, null, "Sync delay"),
512
+ React.createElement(Tag, null, `${config.prebid.config.userSync.syncDelay}ms`))),
513
+ config.prebid.config.userSync.syncsPerBidder !== undefined && (React.createElement("div", { className: "MoliDebug-tagContainer" },
514
+ React.createElement(TagLabel, null, "Syncs per bidder"),
515
+ React.createElement(Tag, null, config.prebid.config.userSync.syncsPerBidder.toString()))),
516
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
517
+ React.createElement(TagLabel, null, "User sync override enabled"),
518
+ React.createElement(Tag, null, (!!config.prebid.config.userSync.enableOverride).toString())),
519
+ config.prebid.config.userSync.filterSettings && (React.createElement("div", null,
520
+ React.createElement("h6", null, "Filter Settings"),
521
+ config.prebid.config.userSync.filterSettings.all &&
522
+ this.filterSetting('All', config.prebid.config.userSync.filterSettings.all),
523
+ config.prebid.config.userSync.filterSettings.iframe &&
524
+ this.filterSetting('iFrame', config.prebid.config.userSync.filterSettings.iframe),
525
+ config.prebid.config.userSync.filterSettings.image &&
526
+ this.filterSetting('Image', config.prebid.config.userSync.filterSettings.image))))),
527
+ React.createElement("h5", null, "Currency"),
528
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
529
+ React.createElement(TagLabel, null, "Ad server currency"),
530
+ React.createElement(Tag, null, config.prebid.config.currency?.adServerCurrency ?? 'EUR (default)')),
531
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
532
+ React.createElement(TagLabel, null, "Granularity multiplier"),
533
+ React.createElement(Tag, null, config.prebid.config.currency?.granularityMultiplier.toString() ??
534
+ 'not set')),
535
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
536
+ React.createElement(TagLabel, null, "Default Rates, USD \u2192 EUR"),
537
+ React.createElement(Tag, null, config.prebid.config.currency?.defaultRates.USD.EUR?.toString() ??
538
+ 'not set')))))),
539
+ config.a9 && (React.createElement("div", { className: "MoliDebug-sidebarSection MoliDebug-sidebarSection--a9" },
540
+ React.createElement("h4", null,
541
+ this.collapseToggle('a9'),
542
+ "A9"),
543
+ expandSection.a9 && (React.createElement("div", null,
544
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
545
+ React.createElement(TagLabel, null, "PubID"),
546
+ React.createElement(Tag, { variant: config.a9.pubID ? 'blue' : 'red' }, config.a9.pubID)),
547
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
548
+ React.createElement(TagLabel, null, "Timeout"),
549
+ React.createElement(Tag, { variant: config.a9.timeout ? 'blue' : 'red' },
550
+ config.a9.timeout.toFixed(0),
551
+ "ms")),
552
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
553
+ React.createElement(TagLabel, null, "CMP timeout"),
554
+ React.createElement(Tag, { variant: config.a9.cmpTimeout ? 'blue' : 'red' },
555
+ config.a9.cmpTimeout.toFixed(0),
556
+ "ms")))))),
557
+ React.createElement("div", { className: "MoliDebug-sidebarSection MoliDebug-sidebarSection--consent" },
558
+ React.createElement("h4", null,
559
+ this.collapseToggle('consent'),
560
+ "Consent"),
561
+ expandSection.consent && (React.createElement("div", null,
562
+ React.createElement(ConsentConfig, null)))),
563
+ React.createElement("div", { className: "MoliDebug-sidebarSection MoliDebug-sidebarSection--supplyChain" },
564
+ React.createElement("h4", null,
565
+ this.collapseToggle('supplyChain'),
566
+ "Supply Chain"),
567
+ expandSection.supplyChain && (React.createElement(React.Fragment, null,
568
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
569
+ React.createElement(TagLabel, null, "Seller ID (ads.txt)"),
570
+ React.createElement(Tag, { variant: adstxtEntry[1] === config?.schain.supplyChainStartNode.sid ? 'green' : 'red' }, adstxtEntry[1])),
571
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
572
+ React.createElement(TagLabel, null, "Status"),
573
+ React.createElement(Tag, { variant: adstxtEntry[2] ? 'blue' : 'red' }, adstxtEntry[2])),
574
+ React.createElement("p", { className: "MoliDebug-info" }, config?.schain.supplyChainStartNode.sid === adstxtEntry[1]
575
+ ? `✅ Seller ids in ad tag config and ads.txt of domain ${adstxtDomain} are matching!`
576
+ : `❗️Seller ids in ad tag config (${config?.schain.supplyChainStartNode.sid}) and ads.txt of current domain (${adstxtDomain}, ${adstxtEntry[1]}) are different!`),
577
+ this.state.adstxtError !== '' && (React.createElement("p", { className: "MoliDebug-panel MoliDebug-panel--red" }, `${this.state.adstxtError} If you use this console locally or on the demo page, try to enable CORS by using a CORS unblocking browser extension.`)),
578
+ React.createElement("form", { className: "MoliDebug-formContainer MoliDebug-panel MoliDebug-panel--blue", onSubmit: async (event) => {
579
+ event.preventDefault();
580
+ const newAdsTxtDomain = event.target[0].value;
581
+ this.setState({
582
+ adstxtDomain: newAdsTxtDomain,
583
+ adstxtEntry: (await this.findPublisherEntryInAdsTxt(newAdsTxtDomain)) ?? []
584
+ });
585
+ } },
586
+ React.createElement("label", { htmlFor: "newDomain" }, "Use different ads.txt domain for seller id comparison:"),
587
+ React.createElement("div", null,
588
+ React.createElement("input", { type: "text", placeholder: "Enter new domain", name: "newDomain", id: "newDomain" }),
589
+ React.createElement("button", { className: "MoliDebug-button", type: "submit" }, "Go!")))))),
590
+ React.createElement("div", { className: "MoliDebug-sidebarSection MoliDebug-sidebarSection--supplyChain" },
591
+ React.createElement("h4", null,
592
+ this.collapseToggle('adDensity'),
593
+ "Ad Density"),
594
+ expandSection.adDensity && (React.createElement(React.Fragment, null,
595
+ React.createElement("form", { className: "MoliDebug-formContainer MoliDebug-panel MoliDebug-panel--blue", onSubmit: async (event) => {
596
+ event.preventDefault();
597
+ const contentSelector = event.target[0].value;
598
+ const { totalAdDensity, adAreaPerSlot } = calculateAdDensity(contentSelector, undefined);
599
+ const percentagePerSlot = adAreaPerSlot.map(adArea => {
600
+ if (!adArea || !adDensity.totalAdDensity) {
601
+ return {
602
+ adSlotId: adArea?.adSlot ? adArea.adSlot : 'unknown',
603
+ percentage: '0.00'
604
+ };
605
+ }
606
+ return {
607
+ adSlotId: adArea.adSlot,
608
+ percentage: ((adArea.adArea / adDensity.totalAdDensity) * 100).toFixed(2)
609
+ };
610
+ });
611
+ this.setState({
612
+ adDensity: { totalAdDensity, percentagePerSlot }
613
+ });
614
+ } },
615
+ React.createElement("label", { htmlFor: "adDensitySelector" }, "Calculate ad density of the content element"),
616
+ React.createElement("div", null,
617
+ React.createElement("input", { type: "text", placeholder: "Enter CSS selector", name: "adDensitySelector", id: "adDensitySelector" }),
618
+ React.createElement("button", { className: "MoliDebug-button", type: "submit" }, "Go!"))),
619
+ React.createElement("div", { className: "MoliDebug-tagContainer" },
620
+ React.createElement(TagLabel, null, "Ad Density"),
621
+ React.createElement(Tag, { variant: 'green' }, adDensity.totalAdDensity)),
622
+ adDensity.percentagePerSlot.length > 0 && (React.createElement(React.Fragment, null,
623
+ React.createElement("hr", null),
624
+ React.createElement("h4", null, "Percentage of ad slot area on total ad area"),
625
+ adDensity.percentagePerSlot.map(percentage => {
626
+ return (React.createElement("div", { className: "MoliDebug-tagContainer", key: percentage.adSlotId },
627
+ React.createElement(TagLabel, null, extractPositionFromPath(percentage.adSlotId)),
628
+ React.createElement(Tag, { variant: 'green' },
629
+ percentage.percentage,
630
+ "%")));
631
+ }),
632
+ React.createElement("hr", null))))))))));
633
+ }
634
+ }