@d8a-tech/gd 0.35.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,6 +12,23 @@ Supported interception methods:
12
12
  - navigator.sendBeacon calls
13
13
  - Script tag loads
14
14
 
15
+ ## Duplicate requests and cookies
16
+
17
+ Duplicated requests made with `fetch` also send cookies. This helps features like server-side
18
+ Google Tag Manager debug mode work when your duplicate endpoint needs those cookies.
19
+
20
+ Notes:
21
+ - When the original request uses `navigator.sendBeacon` and `convert_to_get` is `false`, duplicate
22
+ requests will also use `sendBeacon` (which cannot send cookies). Use `convert_to_get: true`
23
+ to send beacon duplicates via `fetch` with cookies included.
24
+ - For cross-origin duplicate endpoints, your server must support credentialed CORS:
25
+ - `Access-Control-Allow-Origin` must be an explicit origin (not `*`).
26
+ - `Access-Control-Allow-Credentials` must be `true`.
27
+ - If credentialed CORS is not allowed by the endpoint, browsers can fail duplicate requests due to
28
+ CORS policy.
29
+ - Only configure trusted destination endpoints you control, because credentialed requests may send
30
+ cookies scoped to that destination origin.
31
+
15
32
  ## Usage
16
33
 
17
34
  Include the built script in your HTML and initialize the duplicator:
package/dist/gd.js CHANGED
@@ -1,8 +1,8 @@
1
- /* ga4-duplicator - built 2026-02-18T23:13:35.593Z */
1
+ /* ga4-duplicator - built 2026-02-20T20:15:46.018Z */
2
2
  "use strict";
3
3
  (() => {
4
4
  // src/version.ts
5
- var version = "v0.35.0" ? "v0.35.0" : devVersionUtc();
5
+ var version = "v0.36.0" ? "v0.36.0" : devVersionUtc();
6
6
 
7
7
  // src/ga4-duplicator.ts
8
8
  window.createGA4Duplicator = function(options) {
@@ -31,7 +31,11 @@
31
31
  const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);
32
32
  const convertToGet = ctx.getConvertToGet(requestUrl);
33
33
  if (upperMethod === "GET") {
34
- originalFetch(duplicateUrl, { method: "GET", keepalive: true }).catch((error) => {
34
+ originalFetch(duplicateUrl, {
35
+ method: "GET",
36
+ keepalive: true,
37
+ credentials: "include"
38
+ }).catch((error) => {
35
39
  if (ctx.debug) console.error("gtm interceptor: error duplicating GET fetch:", error);
36
40
  });
37
41
  } else if (upperMethod === "POST") {
@@ -44,7 +48,8 @@
44
48
  originalFetch(duplicateUrl, {
45
49
  method: "POST",
46
50
  body: dupBody,
47
- keepalive: true
51
+ keepalive: true,
52
+ credentials: "include"
48
53
  }).catch((error) => {
49
54
  if (ctx.debug)
50
55
  console.error(
@@ -61,20 +66,26 @@
61
66
  if (line) {
62
67
  const mergedUrl = ctx.buildDuplicateUrl(requestUrl);
63
68
  const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);
64
- originalFetch(urlWithMergedLine, { method: "GET", keepalive: true }).catch(
65
- (error) => {
66
- if (ctx.debug)
67
- console.error(
68
- "gtm interceptor: error duplicating GET fetch (from convert_to_get):",
69
- error
70
- );
71
- }
72
- );
69
+ originalFetch(urlWithMergedLine, {
70
+ method: "GET",
71
+ keepalive: true,
72
+ credentials: "include"
73
+ }).catch((error) => {
74
+ if (ctx.debug)
75
+ console.error(
76
+ "gtm interceptor: error duplicating GET fetch (from convert_to_get):",
77
+ error
78
+ );
79
+ });
73
80
  sentAny = true;
74
81
  }
75
82
  }
76
83
  if (!sentAny) {
77
- originalFetch(duplicateUrl, { method: "GET", keepalive: true }).catch((error) => {
84
+ originalFetch(duplicateUrl, {
85
+ method: "GET",
86
+ keepalive: true,
87
+ credentials: "include"
88
+ }).catch((error) => {
78
89
  if (ctx.debug)
79
90
  console.error(
80
91
  "gtm interceptor: error duplicating GET fetch (empty body convert_to_get):",
@@ -86,7 +97,8 @@
86
97
  originalFetch(duplicateUrl, {
87
98
  method: "POST",
88
99
  body: dupBody,
89
- keepalive: true
100
+ keepalive: true,
101
+ credentials: "include"
90
102
  }).catch((error) => {
91
103
  if (ctx.debug)
92
104
  console.error("gtm interceptor: error duplicating POST fetch:", error);
@@ -117,7 +129,11 @@
117
129
  const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);
118
130
  const convertToGet = ctx.getConvertToGet(this._requestUrl);
119
131
  if (method === "GET") {
120
- fetch(duplicateUrl, { method: "GET", keepalive: true }).catch((error) => {
132
+ fetch(duplicateUrl, {
133
+ method: "GET",
134
+ keepalive: true,
135
+ credentials: "include"
136
+ }).catch((error) => {
121
137
  if (ctx.debug) console.error("gtm interceptor: error duplicating GET xhr:", error);
122
138
  });
123
139
  } else if (method === "POST") {
@@ -139,7 +155,11 @@
139
155
  if (line) {
140
156
  const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);
141
157
  const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);
142
- fetch(urlWithMergedLine, { method: "GET", keepalive: true }).catch((error) => {
158
+ fetch(urlWithMergedLine, {
159
+ method: "GET",
160
+ keepalive: true,
161
+ credentials: "include"
162
+ }).catch((error) => {
143
163
  if (ctx.debug)
144
164
  console.error(
145
165
  "gtm interceptor: error duplicating GET xhr (from convert_to_get):",
@@ -150,7 +170,11 @@
150
170
  }
151
171
  }
152
172
  if (!sentAny) {
153
- fetch(duplicateUrl, { method: "GET", keepalive: true }).catch((error) => {
173
+ fetch(duplicateUrl, {
174
+ method: "GET",
175
+ keepalive: true,
176
+ credentials: "include"
177
+ }).catch((error) => {
154
178
  if (ctx.debug)
155
179
  console.error(
156
180
  "gtm interceptor: error duplicating GET xhr (empty body convert_to_get):",
@@ -159,12 +183,15 @@
159
183
  });
160
184
  }
161
185
  } else {
162
- fetch(duplicateUrl, { method: "POST", body, keepalive: true }).catch(
163
- (error) => {
164
- if (ctx.debug)
165
- console.error("gtm interceptor: error duplicating POST xhr:", error);
166
- }
167
- );
186
+ fetch(duplicateUrl, {
187
+ method: "POST",
188
+ body,
189
+ keepalive: true,
190
+ credentials: "include"
191
+ }).catch((error) => {
192
+ if (ctx.debug)
193
+ console.error("gtm interceptor: error duplicating POST xhr:", error);
194
+ });
168
195
  }
169
196
  }
170
197
  } catch (dupErr) {
@@ -204,7 +231,11 @@
204
231
  if (line) {
205
232
  const mergedUrl = ctx.buildDuplicateUrl(url);
206
233
  const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);
207
- fetch(urlWithMergedLine, { method: "GET", keepalive: true }).catch((error) => {
234
+ fetch(urlWithMergedLine, {
235
+ method: "GET",
236
+ keepalive: true,
237
+ credentials: "include"
238
+ }).catch((error) => {
208
239
  if (ctx.debug)
209
240
  console.error(
210
241
  "gtm interceptor: error duplicating GET beacon (from convert_to_get):",
@@ -215,7 +246,11 @@
215
246
  }
216
247
  }
217
248
  if (!sentAny) {
218
- fetch(duplicateUrl, { method: "GET", keepalive: true }).catch((error) => {
249
+ fetch(duplicateUrl, {
250
+ method: "GET",
251
+ keepalive: true,
252
+ credentials: "include"
253
+ }).catch((error) => {
219
254
  if (ctx.debug)
220
255
  console.error(
221
256
  "gtm interceptor: error duplicating GET beacon (empty body convert_to_get):",
@@ -248,12 +283,13 @@
248
283
  const duplicateIfGA4Url = (urlString) => {
249
284
  try {
250
285
  if (!ctx.isTargetUrl(urlString)) return;
251
- fetch(ctx.buildDuplicateUrl(urlString), { method: "GET", keepalive: true }).catch(
252
- (error) => {
253
- if (ctx.debug)
254
- console.error("gtm interceptor: error duplicating script GET:", error);
255
- }
256
- );
286
+ fetch(ctx.buildDuplicateUrl(urlString), {
287
+ method: "GET",
288
+ keepalive: true,
289
+ credentials: "include"
290
+ }).catch((error) => {
291
+ if (ctx.debug) console.error("gtm interceptor: error duplicating script GET:", error);
292
+ });
257
293
  } catch (e) {
258
294
  }
259
295
  };
package/dist/gd.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts", "../src/ga4-duplicator.ts"],
4
- "sourcesContent": ["/**\n * Package version identifier.\n * This value is replaced at build time via esbuild define.\n */\ndeclare const __D8A_VERSION__: string;\n\nfunction devVersionUtc(): string {\n const now = new Date();\n const year = String(now.getUTCFullYear()).slice(-2);\n const month = String(now.getUTCMonth() + 1).padStart(2, \"0\");\n return `dev-${year}-${month}`;\n}\n\nexport const version: string =\n typeof __D8A_VERSION__ !== \"undefined\" && __D8A_VERSION__ ? __D8A_VERSION__ : devVersionUtc();\n", "/**\n * GA4 Duplicator - Intercepts GA4 collect calls and sends duplicates to D8A.\n */\n\nimport { version } from \"./version\";\n\ninterface GA4Destination {\n measurement_id: string;\n server_container_url: string;\n convert_to_get?: boolean;\n}\n\ninterface GA4DuplicatorOptions {\n server_container_url?: string;\n destinations?: GA4Destination[];\n debug?: boolean;\n convert_to_get?: boolean;\n}\n\n(window as any).createGA4Duplicator = function (options: GA4DuplicatorOptions) {\n /**\n * Shared logic and configuration for interceptors.\n */\n interface InterceptorContext {\n debug: boolean;\n isTargetUrl(url: string | null | undefined): boolean;\n buildDuplicateUrl(url: string): string;\n getConvertToGet(url: string): boolean;\n }\n\n /**\n * Base interface for monkey-patching implementations.\n */\n interface NetworkInterceptor {\n install(context: InterceptorContext): void;\n }\n\n class FetchInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalFetch = window.fetch;\n window.fetch = function (\n this: any,\n resource: RequestInfo | URL,\n config?: RequestInit,\n ): Promise<Response> {\n const requestUrl =\n typeof resource === \"string\"\n ? resource\n : resource instanceof URL\n ? resource.toString()\n : (resource as any).url;\n const method = (config && config.method) || (resource as any).method || \"GET\";\n\n if (ctx.isTargetUrl(requestUrl)) {\n const upperMethod = (method || \"GET\").toUpperCase();\n\n // If we need the body from a Request, clone BEFORE calling the original fetch\n let prepareBodyPromise: Promise<any> = Promise.resolve(undefined);\n if (upperMethod === \"POST\") {\n if (config && Object.prototype.hasOwnProperty.call(config, \"body\")) {\n prepareBodyPromise = Promise.resolve(config.body);\n } else if (typeof Request !== \"undefined\" && resource instanceof Request) {\n try {\n const clonedReq = resource.clone();\n prepareBodyPromise = clonedReq.blob().catch(() => undefined);\n } catch {\n prepareBodyPromise = Promise.resolve(undefined);\n }\n }\n }\n\n // First send original request to Google Analytics\n const originalPromise = originalFetch.apply(this, arguments as any);\n\n // Then send duplicate\n const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);\n const convertToGet = ctx.getConvertToGet(requestUrl);\n\n if (upperMethod === \"GET\") {\n originalFetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET fetch:\", error);\n });\n } else if (upperMethod === \"POST\") {\n prepareBodyPromise.then((dupBody) => {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof dupBody === \"string\") {\n bodyStr = dupBody;\n } else if (dupBody instanceof Blob) {\n // For blob, we can't easily convert synchronously, so fall back to POST\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):\",\n error,\n );\n });\n return;\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n originalFetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (from convert_to_get):\",\n error,\n );\n },\n );\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n originalFetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST fetch:\", error);\n });\n }\n });\n }\n\n return originalPromise;\n }\n\n return originalFetch.apply(this, arguments as any);\n };\n }\n }\n\n class XhrInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (this: any, method: string, url: string | URL) {\n this._requestMethod = method;\n this._requestUrl = url;\n return originalXHROpen.apply(this, arguments as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: any,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._requestUrl && ctx.isTargetUrl(this._requestUrl)) {\n // First send original request to Google Analytics\n const originalResult = originalXHRSend.apply(this, arguments as any);\n\n // Then send duplicate to our endpoint mimicking method and payload\n try {\n const method = (this._requestMethod || \"GET\").toUpperCase();\n const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const convertToGet = ctx.getConvertToGet(this._requestUrl);\n\n if (method === \"GET\") {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET xhr:\", error);\n });\n } else if (method === \"POST\") {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof body === \"string\") {\n bodyStr = body;\n } else if (body && typeof body === \"object\") {\n // Try to convert Document or other types to string\n try {\n bodyStr = String(body);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n fetch(duplicateUrl, { method: \"POST\", body: body as any, keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST xhr:\", error);\n },\n );\n }\n }\n } catch (dupErr) {\n if (ctx.debug) console.error(\"gtm interceptor: xhr duplication failed:\", dupErr);\n }\n return originalResult;\n }\n return originalXHRSend.apply(this, arguments as any);\n };\n }\n }\n\n class BeaconInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n if (!navigator.sendBeacon) return;\n\n const originalSendBeacon = navigator.sendBeacon;\n navigator.sendBeacon = function (\n this: any,\n url: string | URL,\n data?: BodyInit | null,\n ): boolean {\n if (ctx.isTargetUrl(url as string)) {\n const originalResult = originalSendBeacon.apply(this, arguments as any);\n try {\n const duplicateUrl = ctx.buildDuplicateUrl(url as string);\n const convertToGet = ctx.getConvertToGet(url as string);\n\n if (convertToGet) {\n // Convert sendBeacon POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof data === \"string\") {\n bodyStr = data;\n } else if (data && typeof data === \"object\") {\n try {\n bodyStr = String(data);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(url as string);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original sendBeacon duplication\n originalSendBeacon.call(navigator, duplicateUrl, data);\n }\n } catch (e) {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating sendBeacon:\", e);\n }\n return originalResult;\n }\n return originalSendBeacon.apply(this, arguments as any);\n };\n }\n }\n\n class ScriptInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n try {\n const scriptSrcDescriptor = Object.getOwnPropertyDescriptor(\n HTMLScriptElement.prototype,\n \"src\",\n );\n const originalScriptSrcSetter = scriptSrcDescriptor && scriptSrcDescriptor.set;\n const originalScriptSrcGetter = scriptSrcDescriptor && scriptSrcDescriptor.get;\n const originalScriptSetAttribute = HTMLScriptElement.prototype.setAttribute;\n\n const duplicateIfGA4Url = (urlString: string) => {\n try {\n if (!ctx.isTargetUrl(urlString)) return;\n fetch(ctx.buildDuplicateUrl(urlString), { method: \"GET\", keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating script GET:\", error);\n },\n );\n } catch {\n // Intentionally empty\n }\n };\n\n if (originalScriptSrcSetter && originalScriptSrcGetter) {\n const setter = originalScriptSrcSetter;\n const getter = originalScriptSrcGetter;\n Object.defineProperty(HTMLScriptElement.prototype, \"src\", {\n configurable: true,\n enumerable: true,\n get: function (this: any) {\n return getter.call(this);\n },\n set: function (this: any, value: string) {\n try {\n const last = this.__ga4LastSrcDuplicated;\n if (value && value !== last) {\n duplicateIfGA4Url(String(value));\n this.__ga4LastSrcDuplicated = String(value);\n }\n const self = this;\n const onloadOnce = function () {\n try {\n const finalUrl = self.src;\n if (finalUrl && finalUrl !== self.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrl);\n self.__ga4LastSrcDuplicated = finalUrl;\n }\n } catch {}\n self.removeEventListener(\"load\", onloadOnce);\n };\n this.addEventListener(\"load\", onloadOnce);\n } catch {}\n setter.call(this, value);\n },\n });\n }\n\n HTMLScriptElement.prototype.setAttribute = function (\n this: any,\n name: string,\n value: string,\n ) {\n try {\n if (String(name).toLowerCase() === \"src\") {\n const v = String(value);\n const last = this.__ga4LastSrcDuplicated;\n if (v && v !== last) {\n duplicateIfGA4Url(v);\n this.__ga4LastSrcDuplicated = v;\n }\n const selfAttr = this;\n const onloadOnceAttr = function () {\n try {\n const finalUrlAttr = selfAttr.src;\n if (finalUrlAttr && finalUrlAttr !== selfAttr.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrlAttr);\n selfAttr.__ga4LastSrcDuplicated = finalUrlAttr;\n }\n } catch {}\n selfAttr.removeEventListener(\"load\", onloadOnceAttr);\n };\n this.addEventListener(\"load\", onloadOnceAttr);\n }\n } catch {\n // Intentionally empty\n }\n return originalScriptSetAttribute.apply(this, arguments as any);\n };\n } catch {}\n }\n }\n\n if ((window as any).__ga4DuplicatorInitialized) {\n if (options.debug) console.warn(\"GA4 Duplicator: already initialized.\");\n return;\n }\n\n const destinations: GA4Destination[] = [];\n if (options.destinations && Array.isArray(options.destinations)) {\n for (let i = 0; i < options.destinations.length; i++) {\n const dest = options.destinations[i];\n destinations.push({\n measurement_id: dest.measurement_id,\n server_container_url: dest.server_container_url,\n convert_to_get:\n dest.convert_to_get !== undefined ? dest.convert_to_get : options.convert_to_get,\n });\n }\n }\n\n if (options.server_container_url) {\n destinations.push({\n measurement_id: \"*\",\n server_container_url: options.server_container_url,\n convert_to_get: options.convert_to_get,\n });\n }\n\n if (destinations.length === 0) {\n console.error(\"GA4 Duplicator: either server_container_url or destinations array is required\");\n return;\n }\n\n function normalizePath(p: string): string {\n p = String(p || \"\");\n p = p.replace(/\\/+$/, \"\");\n return p === \"\" ? \"/\" : p;\n }\n\n function matchesId(pattern: string, id: string): boolean {\n if (!pattern || pattern === \"*\") return true;\n try {\n const regexStr = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(\"^\" + regexStr + \"$\", \"i\").test(id);\n } catch {\n return pattern.toLowerCase() === id.toLowerCase();\n }\n }\n\n function ensureBareQueryFlag(url: string, flag: string): string {\n const u = String(url || \"\");\n const f = String(flag || \"\").trim();\n if (!u || !f) return u;\n\n // Keep fragment intact\n const hashIdx = u.indexOf(\"#\");\n const beforeHash = hashIdx >= 0 ? u.slice(0, hashIdx) : u;\n const hash = hashIdx >= 0 ? u.slice(hashIdx) : \"\";\n\n const qIdx = beforeHash.indexOf(\"?\");\n const base = qIdx >= 0 ? beforeHash.slice(0, qIdx) : beforeHash;\n const rawQuery = qIdx >= 0 ? beforeHash.slice(qIdx + 1) : \"\";\n\n const parts = rawQuery\n ? rawQuery\n .split(\"&\")\n .map((p) => p.trim())\n .filter(Boolean)\n : [];\n\n const kept: string[] = [];\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n if (p === f) continue;\n if (p.startsWith(f + \"=\")) continue;\n kept.push(p);\n }\n\n const newQuery = kept.length > 0 ? kept.join(\"&\") + \"&\" + f : f;\n return base + \"?\" + newQuery + hash;\n }\n\n function getMeasurementId(url: string): string {\n try {\n const parsed = new URL(url, location.href);\n return parsed.searchParams.get(\"tid\") || parsed.searchParams.get(\"id\") || \"\";\n } catch {\n const match = url.match(/[?&](?:tid|id)=([^&?#]+)/);\n return match ? decodeURIComponent(match[1]) : \"\";\n }\n }\n\n function getDestinationForId(id: string): GA4Destination | null {\n for (let i = 0; i < destinations.length; i++) {\n if (matchesId(destinations[i].measurement_id, id)) {\n return destinations[i];\n }\n }\n return null;\n }\n\n function mergeBodyLineWithUrl(originalUrl: string, bodyLine: string): string {\n try {\n const url = new URL(originalUrl, location.href);\n const lineParams = new URLSearchParams(bodyLine);\n\n // Line parameters override URL parameters\n for (const [key] of lineParams.entries()) {\n url.searchParams.delete(key);\n }\n for (const [key, value] of lineParams.entries()) {\n url.searchParams.append(key, value);\n }\n\n return ensureBareQueryFlag(url.toString(), \"richsstsse\");\n } catch {\n // Fallback: if URL parsing fails, try string manipulation\n const urlWithoutQuery = originalUrl.split(\"?\")[0];\n const originalParams = originalUrl.match(/\\?(.*)/) ? originalUrl.match(/\\?(.*)/)![1] : \"\";\n const merged = originalParams + (originalParams && bodyLine ? \"&\" : \"\") + bodyLine;\n return ensureBareQueryFlag(urlWithoutQuery + (merged ? \"?\" + merged : \"\"), \"richsstsse\");\n }\n }\n\n function getDuplicateEndpointUrl(dest: GA4Destination): URL {\n const trackingURL = String(dest.server_container_url || \"\").trim();\n const u = new URL(trackingURL, location.href);\n u.search = \"\";\n u.hash = \"\";\n return u;\n }\n\n function isTargetUrl(url: string | null | undefined): boolean {\n if (!url || typeof url !== \"string\") return false;\n try {\n const parsed = new URL(url, location.href);\n\n for (let i = 0; i < destinations.length; i++) {\n const duplicateTarget = getDuplicateEndpointUrl(destinations[i]);\n if (\n parsed.origin === duplicateTarget.origin &&\n normalizePath(parsed.pathname) === normalizePath(duplicateTarget.pathname)\n ) {\n return false;\n }\n }\n\n const params = parsed.searchParams;\n const hasGtm = params.has(\"gtm\");\n const hasTagExp = params.has(\"tag_exp\");\n const measurementId = params.get(\"tid\") || params.get(\"id\") || \"\";\n const isMeasurementIdGA4 = /^G-[A-Z0-9]+$/i.test(measurementId);\n\n return hasGtm && hasTagExp && isMeasurementIdGA4;\n } catch {\n if (typeof url === \"string\") {\n for (let j = 0; j < destinations.length; j++) {\n try {\n const target = getDuplicateEndpointUrl(destinations[j]);\n const targetNoQuery = target.origin + target.pathname;\n if (url.indexOf(targetNoQuery) !== -1) return false;\n } catch {\n // Intentionally empty\n }\n }\n\n const hasGtmFallback = url.indexOf(\"gtm=\") !== -1;\n const hasTagExpFallback = url.indexOf(\"tag_exp=\") !== -1;\n const idMatch = url.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);\n return !!(hasGtmFallback && hasTagExpFallback && idMatch);\n }\n return false;\n }\n }\n\n function buildDuplicateUrl(originalUrl: string): string {\n const id = getMeasurementId(originalUrl);\n const dest = getDestinationForId(id);\n if (!dest) return \"\";\n\n const dst = getDuplicateEndpointUrl(dest);\n try {\n const src = new URL(originalUrl, location.href);\n dst.search = src.search;\n dst.searchParams.set(\"_dtv\", version);\n dst.searchParams.set(\"_dtn\", \"gd\");\n } catch {}\n return ensureBareQueryFlag(dst.toString(), \"richsstsse\");\n }\n\n function getConvertToGet(url: string): boolean {\n const id = getMeasurementId(url);\n const dest = getDestinationForId(id);\n return dest ? !!dest.convert_to_get : false;\n }\n\n const context: InterceptorContext = {\n debug: !!options.debug,\n isTargetUrl,\n buildDuplicateUrl,\n getConvertToGet,\n };\n\n const interceptors: NetworkInterceptor[] = [\n new FetchInterceptor(),\n new XhrInterceptor(),\n new BeaconInterceptor(),\n new ScriptInterceptor(),\n ];\n\n for (let i = 0; i < interceptors.length; i++) {\n try {\n interceptors[i].install(context);\n } catch (e) {\n if (options.debug) console.error(\"GA4 Duplicator: failed to install interceptor\", e);\n }\n }\n\n (window as any).__ga4DuplicatorInitialized = true;\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Package version identifier.\n * This value is replaced at build time via esbuild define.\n */\ndeclare const __D8A_VERSION__: string;\n\nfunction devVersionUtc(): string {\n const now = new Date();\n const year = String(now.getUTCFullYear()).slice(-2);\n const month = String(now.getUTCMonth() + 1).padStart(2, \"0\");\n return `dev-${year}-${month}`;\n}\n\nexport const version: string =\n typeof __D8A_VERSION__ !== \"undefined\" && __D8A_VERSION__ ? __D8A_VERSION__ : devVersionUtc();\n", "/**\n * GA4 Duplicator - Intercepts GA4 collect calls and sends duplicates to D8A.\n */\n\nimport { version } from \"./version\";\n\ninterface GA4Destination {\n measurement_id: string;\n server_container_url: string;\n convert_to_get?: boolean;\n}\n\ninterface GA4DuplicatorOptions {\n server_container_url?: string;\n destinations?: GA4Destination[];\n debug?: boolean;\n convert_to_get?: boolean;\n}\n\n(window as any).createGA4Duplicator = function (options: GA4DuplicatorOptions) {\n /**\n * Shared logic and configuration for interceptors.\n */\n interface InterceptorContext {\n debug: boolean;\n isTargetUrl(url: string | null | undefined): boolean;\n buildDuplicateUrl(url: string): string;\n getConvertToGet(url: string): boolean;\n }\n\n /**\n * Base interface for monkey-patching implementations.\n */\n interface NetworkInterceptor {\n install(context: InterceptorContext): void;\n }\n\n class FetchInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalFetch = window.fetch;\n window.fetch = function (\n this: any,\n resource: RequestInfo | URL,\n config?: RequestInit,\n ): Promise<Response> {\n const requestUrl =\n typeof resource === \"string\"\n ? resource\n : resource instanceof URL\n ? resource.toString()\n : (resource as any).url;\n const method = (config && config.method) || (resource as any).method || \"GET\";\n\n if (ctx.isTargetUrl(requestUrl)) {\n const upperMethod = (method || \"GET\").toUpperCase();\n\n // If we need the body from a Request, clone BEFORE calling the original fetch\n let prepareBodyPromise: Promise<any> = Promise.resolve(undefined);\n if (upperMethod === \"POST\") {\n if (config && Object.prototype.hasOwnProperty.call(config, \"body\")) {\n prepareBodyPromise = Promise.resolve(config.body);\n } else if (typeof Request !== \"undefined\" && resource instanceof Request) {\n try {\n const clonedReq = resource.clone();\n prepareBodyPromise = clonedReq.blob().catch(() => undefined);\n } catch {\n prepareBodyPromise = Promise.resolve(undefined);\n }\n }\n }\n\n // First send original request to Google Analytics\n const originalPromise = originalFetch.apply(this, arguments as any);\n\n // Then send duplicate\n const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);\n const convertToGet = ctx.getConvertToGet(requestUrl);\n\n if (upperMethod === \"GET\") {\n originalFetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET fetch:\", error);\n });\n } else if (upperMethod === \"POST\") {\n prepareBodyPromise.then((dupBody) => {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof dupBody === \"string\") {\n bodyStr = dupBody;\n } else if (dupBody instanceof Blob) {\n // For blob, we can't easily convert synchronously, so fall back to POST\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):\",\n error,\n );\n });\n return;\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n originalFetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n originalFetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST fetch:\", error);\n });\n }\n });\n }\n\n return originalPromise;\n }\n\n return originalFetch.apply(this, arguments as any);\n };\n }\n }\n\n class XhrInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (this: any, method: string, url: string | URL) {\n this._requestMethod = method;\n this._requestUrl = url;\n return originalXHROpen.apply(this, arguments as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: any,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._requestUrl && ctx.isTargetUrl(this._requestUrl)) {\n // First send original request to Google Analytics\n const originalResult = originalXHRSend.apply(this, arguments as any);\n\n // Then send duplicate to our endpoint mimicking method and payload\n try {\n const method = (this._requestMethod || \"GET\").toUpperCase();\n const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const convertToGet = ctx.getConvertToGet(this._requestUrl);\n\n if (method === \"GET\") {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET xhr:\", error);\n });\n } else if (method === \"POST\") {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof body === \"string\") {\n bodyStr = body;\n } else if (body && typeof body === \"object\") {\n // Try to convert Document or other types to string\n try {\n bodyStr = String(body);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n fetch(duplicateUrl, {\n method: \"POST\",\n body: body as any,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST xhr:\", error);\n });\n }\n }\n } catch (dupErr) {\n if (ctx.debug) console.error(\"gtm interceptor: xhr duplication failed:\", dupErr);\n }\n return originalResult;\n }\n return originalXHRSend.apply(this, arguments as any);\n };\n }\n }\n\n class BeaconInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n if (!navigator.sendBeacon) return;\n\n const originalSendBeacon = navigator.sendBeacon;\n navigator.sendBeacon = function (\n this: any,\n url: string | URL,\n data?: BodyInit | null,\n ): boolean {\n if (ctx.isTargetUrl(url as string)) {\n const originalResult = originalSendBeacon.apply(this, arguments as any);\n try {\n const duplicateUrl = ctx.buildDuplicateUrl(url as string);\n const convertToGet = ctx.getConvertToGet(url as string);\n\n if (convertToGet) {\n // Convert sendBeacon POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof data === \"string\") {\n bodyStr = data;\n } else if (data && typeof data === \"object\") {\n try {\n bodyStr = String(data);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(url as string);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original sendBeacon duplication\n originalSendBeacon.call(navigator, duplicateUrl, data);\n }\n } catch (e) {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating sendBeacon:\", e);\n }\n return originalResult;\n }\n return originalSendBeacon.apply(this, arguments as any);\n };\n }\n }\n\n class ScriptInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n try {\n const scriptSrcDescriptor = Object.getOwnPropertyDescriptor(\n HTMLScriptElement.prototype,\n \"src\",\n );\n const originalScriptSrcSetter = scriptSrcDescriptor && scriptSrcDescriptor.set;\n const originalScriptSrcGetter = scriptSrcDescriptor && scriptSrcDescriptor.get;\n const originalScriptSetAttribute = HTMLScriptElement.prototype.setAttribute;\n\n const duplicateIfGA4Url = (urlString: string) => {\n try {\n if (!ctx.isTargetUrl(urlString)) return;\n fetch(ctx.buildDuplicateUrl(urlString), {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating script GET:\", error);\n });\n } catch {\n // Intentionally empty\n }\n };\n\n if (originalScriptSrcSetter && originalScriptSrcGetter) {\n const setter = originalScriptSrcSetter;\n const getter = originalScriptSrcGetter;\n Object.defineProperty(HTMLScriptElement.prototype, \"src\", {\n configurable: true,\n enumerable: true,\n get: function (this: any) {\n return getter.call(this);\n },\n set: function (this: any, value: string) {\n try {\n const last = this.__ga4LastSrcDuplicated;\n if (value && value !== last) {\n duplicateIfGA4Url(String(value));\n this.__ga4LastSrcDuplicated = String(value);\n }\n const self = this;\n const onloadOnce = function () {\n try {\n const finalUrl = self.src;\n if (finalUrl && finalUrl !== self.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrl);\n self.__ga4LastSrcDuplicated = finalUrl;\n }\n } catch {}\n self.removeEventListener(\"load\", onloadOnce);\n };\n this.addEventListener(\"load\", onloadOnce);\n } catch {}\n setter.call(this, value);\n },\n });\n }\n\n HTMLScriptElement.prototype.setAttribute = function (\n this: any,\n name: string,\n value: string,\n ) {\n try {\n if (String(name).toLowerCase() === \"src\") {\n const v = String(value);\n const last = this.__ga4LastSrcDuplicated;\n if (v && v !== last) {\n duplicateIfGA4Url(v);\n this.__ga4LastSrcDuplicated = v;\n }\n const selfAttr = this;\n const onloadOnceAttr = function () {\n try {\n const finalUrlAttr = selfAttr.src;\n if (finalUrlAttr && finalUrlAttr !== selfAttr.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrlAttr);\n selfAttr.__ga4LastSrcDuplicated = finalUrlAttr;\n }\n } catch {}\n selfAttr.removeEventListener(\"load\", onloadOnceAttr);\n };\n this.addEventListener(\"load\", onloadOnceAttr);\n }\n } catch {\n // Intentionally empty\n }\n return originalScriptSetAttribute.apply(this, arguments as any);\n };\n } catch {}\n }\n }\n\n if ((window as any).__ga4DuplicatorInitialized) {\n if (options.debug) console.warn(\"GA4 Duplicator: already initialized.\");\n return;\n }\n\n const destinations: GA4Destination[] = [];\n if (options.destinations && Array.isArray(options.destinations)) {\n for (let i = 0; i < options.destinations.length; i++) {\n const dest = options.destinations[i];\n destinations.push({\n measurement_id: dest.measurement_id,\n server_container_url: dest.server_container_url,\n convert_to_get:\n dest.convert_to_get !== undefined ? dest.convert_to_get : options.convert_to_get,\n });\n }\n }\n\n if (options.server_container_url) {\n destinations.push({\n measurement_id: \"*\",\n server_container_url: options.server_container_url,\n convert_to_get: options.convert_to_get,\n });\n }\n\n if (destinations.length === 0) {\n console.error(\"GA4 Duplicator: either server_container_url or destinations array is required\");\n return;\n }\n\n function normalizePath(p: string): string {\n p = String(p || \"\");\n p = p.replace(/\\/+$/, \"\");\n return p === \"\" ? \"/\" : p;\n }\n\n function matchesId(pattern: string, id: string): boolean {\n if (!pattern || pattern === \"*\") return true;\n try {\n const regexStr = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(\"^\" + regexStr + \"$\", \"i\").test(id);\n } catch {\n return pattern.toLowerCase() === id.toLowerCase();\n }\n }\n\n function ensureBareQueryFlag(url: string, flag: string): string {\n const u = String(url || \"\");\n const f = String(flag || \"\").trim();\n if (!u || !f) return u;\n\n // Keep fragment intact\n const hashIdx = u.indexOf(\"#\");\n const beforeHash = hashIdx >= 0 ? u.slice(0, hashIdx) : u;\n const hash = hashIdx >= 0 ? u.slice(hashIdx) : \"\";\n\n const qIdx = beforeHash.indexOf(\"?\");\n const base = qIdx >= 0 ? beforeHash.slice(0, qIdx) : beforeHash;\n const rawQuery = qIdx >= 0 ? beforeHash.slice(qIdx + 1) : \"\";\n\n const parts = rawQuery\n ? rawQuery\n .split(\"&\")\n .map((p) => p.trim())\n .filter(Boolean)\n : [];\n\n const kept: string[] = [];\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n if (p === f) continue;\n if (p.startsWith(f + \"=\")) continue;\n kept.push(p);\n }\n\n const newQuery = kept.length > 0 ? kept.join(\"&\") + \"&\" + f : f;\n return base + \"?\" + newQuery + hash;\n }\n\n function getMeasurementId(url: string): string {\n try {\n const parsed = new URL(url, location.href);\n return parsed.searchParams.get(\"tid\") || parsed.searchParams.get(\"id\") || \"\";\n } catch {\n const match = url.match(/[?&](?:tid|id)=([^&?#]+)/);\n return match ? decodeURIComponent(match[1]) : \"\";\n }\n }\n\n function getDestinationForId(id: string): GA4Destination | null {\n for (let i = 0; i < destinations.length; i++) {\n if (matchesId(destinations[i].measurement_id, id)) {\n return destinations[i];\n }\n }\n return null;\n }\n\n function mergeBodyLineWithUrl(originalUrl: string, bodyLine: string): string {\n try {\n const url = new URL(originalUrl, location.href);\n const lineParams = new URLSearchParams(bodyLine);\n\n // Line parameters override URL parameters\n for (const [key] of lineParams.entries()) {\n url.searchParams.delete(key);\n }\n for (const [key, value] of lineParams.entries()) {\n url.searchParams.append(key, value);\n }\n\n return ensureBareQueryFlag(url.toString(), \"richsstsse\");\n } catch {\n // Fallback: if URL parsing fails, try string manipulation\n const urlWithoutQuery = originalUrl.split(\"?\")[0];\n const originalParams = originalUrl.match(/\\?(.*)/) ? originalUrl.match(/\\?(.*)/)![1] : \"\";\n const merged = originalParams + (originalParams && bodyLine ? \"&\" : \"\") + bodyLine;\n return ensureBareQueryFlag(urlWithoutQuery + (merged ? \"?\" + merged : \"\"), \"richsstsse\");\n }\n }\n\n function getDuplicateEndpointUrl(dest: GA4Destination): URL {\n const trackingURL = String(dest.server_container_url || \"\").trim();\n const u = new URL(trackingURL, location.href);\n u.search = \"\";\n u.hash = \"\";\n return u;\n }\n\n function isTargetUrl(url: string | null | undefined): boolean {\n if (!url || typeof url !== \"string\") return false;\n try {\n const parsed = new URL(url, location.href);\n\n for (let i = 0; i < destinations.length; i++) {\n const duplicateTarget = getDuplicateEndpointUrl(destinations[i]);\n if (\n parsed.origin === duplicateTarget.origin &&\n normalizePath(parsed.pathname) === normalizePath(duplicateTarget.pathname)\n ) {\n return false;\n }\n }\n\n const params = parsed.searchParams;\n const hasGtm = params.has(\"gtm\");\n const hasTagExp = params.has(\"tag_exp\");\n const measurementId = params.get(\"tid\") || params.get(\"id\") || \"\";\n const isMeasurementIdGA4 = /^G-[A-Z0-9]+$/i.test(measurementId);\n\n return hasGtm && hasTagExp && isMeasurementIdGA4;\n } catch {\n if (typeof url === \"string\") {\n for (let j = 0; j < destinations.length; j++) {\n try {\n const target = getDuplicateEndpointUrl(destinations[j]);\n const targetNoQuery = target.origin + target.pathname;\n if (url.indexOf(targetNoQuery) !== -1) return false;\n } catch {\n // Intentionally empty\n }\n }\n\n const hasGtmFallback = url.indexOf(\"gtm=\") !== -1;\n const hasTagExpFallback = url.indexOf(\"tag_exp=\") !== -1;\n const idMatch = url.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);\n return !!(hasGtmFallback && hasTagExpFallback && idMatch);\n }\n return false;\n }\n }\n\n function buildDuplicateUrl(originalUrl: string): string {\n const id = getMeasurementId(originalUrl);\n const dest = getDestinationForId(id);\n if (!dest) return \"\";\n\n const dst = getDuplicateEndpointUrl(dest);\n try {\n const src = new URL(originalUrl, location.href);\n dst.search = src.search;\n dst.searchParams.set(\"_dtv\", version);\n dst.searchParams.set(\"_dtn\", \"gd\");\n } catch {}\n return ensureBareQueryFlag(dst.toString(), \"richsstsse\");\n }\n\n function getConvertToGet(url: string): boolean {\n const id = getMeasurementId(url);\n const dest = getDestinationForId(id);\n return dest ? !!dest.convert_to_get : false;\n }\n\n const context: InterceptorContext = {\n debug: !!options.debug,\n isTargetUrl,\n buildDuplicateUrl,\n getConvertToGet,\n };\n\n const interceptors: NetworkInterceptor[] = [\n new FetchInterceptor(),\n new XhrInterceptor(),\n new BeaconInterceptor(),\n new ScriptInterceptor(),\n ];\n\n for (let i = 0; i < interceptors.length; i++) {\n try {\n interceptors[i].install(context);\n } catch (e) {\n if (options.debug) console.error(\"GA4 Duplicator: failed to install interceptor\", e);\n }\n }\n\n (window as any).__ga4DuplicatorInitialized = true;\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["e"]
7
7
  }
package/dist/gd.min.js CHANGED
@@ -1,6 +1,6 @@
1
- /* ga4-duplicator - built 2026-02-18T23:13:35.593Z */
2
- "use strict";(()=>{var w="v0.35.0";window.createGA4Duplicator=function(h){class L{install(t){let e=window.fetch;window.fetch=function(i,n){let o=typeof i=="string"?i:i instanceof URL?i.toString():i.url,g=n&&n.method||i.method||"GET";if(t.isTargetUrl(o)){let l=(g||"GET").toUpperCase(),p=Promise.resolve(void 0);if(l==="POST"){if(n&&Object.prototype.hasOwnProperty.call(n,"body"))p=Promise.resolve(n.body);else if(typeof Request!="undefined"&&i instanceof Request)try{p=i.clone().blob().catch(()=>{})}catch(c){p=Promise.resolve(void 0)}}let s=e.apply(this,arguments),d=t.buildDuplicateUrl(o),u=t.getConvertToGet(o);return l==="GET"?e(d,{method:"GET",keepalive:!0}).catch(c=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch:",c)}):l==="POST"&&p.then(c=>{if(u){let a="";if(typeof c=="string")a=c;else if(c instanceof Blob){e(d,{method:"POST",body:c,keepalive:!0}).catch(_=>{t.debug&&console.error("gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):",_)});return}let m=a.split(`
3
- `),y=!1;for(let _=0;_<m.length;_++){let E=m[_].trim();if(E){let M=t.buildDuplicateUrl(o),H=b(M,E);e(H,{method:"GET",keepalive:!0}).catch(N=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch (from convert_to_get):",N)}),y=!0}}y||e(d,{method:"GET",keepalive:!0}).catch(_=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch (empty body convert_to_get):",_)})}else e(d,{method:"POST",body:c,keepalive:!0}).catch(a=>{t.debug&&console.error("gtm interceptor: error duplicating POST fetch:",a)})}),s}return e.apply(this,arguments)}}}class I{install(t){let e=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(n,o){return this._requestMethod=n,this._requestUrl=o,e.apply(this,arguments)},XMLHttpRequest.prototype.send=function(n){if(this._requestUrl&&t.isTargetUrl(this._requestUrl)){let o=i.apply(this,arguments);try{let g=(this._requestMethod||"GET").toUpperCase(),l=t.buildDuplicateUrl(this._requestUrl),p=t.getConvertToGet(this._requestUrl);if(g==="GET")fetch(l,{method:"GET",keepalive:!0}).catch(s=>{t.debug&&console.error("gtm interceptor: error duplicating GET xhr:",s)});else if(g==="POST")if(p){let s="";if(typeof n=="string")s=n;else if(n&&typeof n=="object")try{s=String(n)}catch(c){s=""}let d=s.split(`
4
- `),u=!1;for(let c=0;c<d.length;c++){let a=d[c].trim();if(a){let m=t.buildDuplicateUrl(this._requestUrl),y=b(m,a);fetch(y,{method:"GET",keepalive:!0}).catch(_=>{t.debug&&console.error("gtm interceptor: error duplicating GET xhr (from convert_to_get):",_)}),u=!0}}u||fetch(l,{method:"GET",keepalive:!0}).catch(c=>{t.debug&&console.error("gtm interceptor: error duplicating GET xhr (empty body convert_to_get):",c)})}else fetch(l,{method:"POST",body:n,keepalive:!0}).catch(s=>{t.debug&&console.error("gtm interceptor: error duplicating POST xhr:",s)})}catch(g){t.debug&&console.error("gtm interceptor: xhr duplication failed:",g)}return o}return i.apply(this,arguments)}}}class R{install(t){if(!navigator.sendBeacon)return;let e=navigator.sendBeacon;navigator.sendBeacon=function(i,n){if(t.isTargetUrl(i)){let o=e.apply(this,arguments);try{let g=t.buildDuplicateUrl(i);if(t.getConvertToGet(i)){let p="";if(typeof n=="string")p=n;else if(n&&typeof n=="object")try{p=String(n)}catch(u){p=""}let s=p.split(`
5
- `),d=!1;for(let u=0;u<s.length;u++){let c=s[u].trim();if(c){let a=t.buildDuplicateUrl(i),m=b(a,c);fetch(m,{method:"GET",keepalive:!0}).catch(y=>{t.debug&&console.error("gtm interceptor: error duplicating GET beacon (from convert_to_get):",y)}),d=!0}}d||fetch(g,{method:"GET",keepalive:!0}).catch(u=>{t.debug&&console.error("gtm interceptor: error duplicating GET beacon (empty body convert_to_get):",u)})}else e.call(navigator,g,n)}catch(g){t.debug&&console.error("gtm interceptor: error duplicating sendBeacon:",g)}return o}return e.apply(this,arguments)}}}class A{install(t){try{let e=Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype,"src"),i=e&&e.set,n=e&&e.get,o=HTMLScriptElement.prototype.setAttribute,g=l=>{try{if(!t.isTargetUrl(l))return;fetch(t.buildDuplicateUrl(l),{method:"GET",keepalive:!0}).catch(p=>{t.debug&&console.error("gtm interceptor: error duplicating script GET:",p)})}catch(p){}};if(i&&n){let l=i,p=n;Object.defineProperty(HTMLScriptElement.prototype,"src",{configurable:!0,enumerable:!0,get:function(){return p.call(this)},set:function(s){try{let d=this.__ga4LastSrcDuplicated;s&&s!==d&&(g(String(s)),this.__ga4LastSrcDuplicated=String(s));let u=this,c=function(){try{let a=u.src;a&&a!==u.__ga4LastSrcDuplicated&&(g(a),u.__ga4LastSrcDuplicated=a)}catch(a){}u.removeEventListener("load",c)};this.addEventListener("load",c)}catch(d){}l.call(this,s)}})}HTMLScriptElement.prototype.setAttribute=function(l,p){try{if(String(l).toLowerCase()==="src"){let s=String(p),d=this.__ga4LastSrcDuplicated;s&&s!==d&&(g(s),this.__ga4LastSrcDuplicated=s);let u=this,c=function(){try{let a=u.src;a&&a!==u.__ga4LastSrcDuplicated&&(g(a),u.__ga4LastSrcDuplicated=a)}catch(a){}u.removeEventListener("load",c)};this.addEventListener("load",c)}}catch(s){}return o.apply(this,arguments)}}catch(e){}}}if(window.__ga4DuplicatorInitialized){h.debug&&console.warn("GA4 Duplicator: already initialized.");return}let f=[];if(h.destinations&&Array.isArray(h.destinations))for(let r=0;r<h.destinations.length;r++){let t=h.destinations[r];f.push({measurement_id:t.measurement_id,server_container_url:t.server_container_url,convert_to_get:t.convert_to_get!==void 0?t.convert_to_get:h.convert_to_get})}if(h.server_container_url&&f.push({measurement_id:"*",server_container_url:h.server_container_url,convert_to_get:h.convert_to_get}),f.length===0){console.error("GA4 Duplicator: either server_container_url or destinations array is required");return}function T(r){return r=String(r||""),r=r.replace(/\/+$/,""),r===""?"/":r}function P(r,t){if(!r||r==="*")return!0;try{let e=r.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp("^"+e+"$","i").test(t)}catch(e){return r.toLowerCase()===t.toLowerCase()}}function v(r,t){let e=String(r||""),i=String(t||"").trim();if(!e||!i)return e;let n=e.indexOf("#"),o=n>=0?e.slice(0,n):e,g=n>=0?e.slice(n):"",l=o.indexOf("?"),p=l>=0?o.slice(0,l):o,s=l>=0?o.slice(l+1):"",d=s?s.split("&").map(a=>a.trim()).filter(Boolean):[],u=[];for(let a=0;a<d.length;a++){let m=d[a];m!==i&&(m.startsWith(i+"=")||u.push(m))}let c=u.length>0?u.join("&")+"&"+i:i;return p+"?"+c+g}function G(r){try{let t=new URL(r,location.href);return t.searchParams.get("tid")||t.searchParams.get("id")||""}catch(t){let e=r.match(/[?&](?:tid|id)=([^&?#]+)/);return e?decodeURIComponent(e[1]):""}}function U(r){for(let t=0;t<f.length;t++)if(P(f[t].measurement_id,r))return f[t];return null}function b(r,t){try{let e=new URL(r,location.href),i=new URLSearchParams(t);for(let[n]of i.entries())e.searchParams.delete(n);for(let[n,o]of i.entries())e.searchParams.append(n,o);return v(e.toString(),"richsstsse")}catch(e){let i=r.split("?")[0],n=r.match(/\?(.*)/)?r.match(/\?(.*)/)[1]:"",o=n+(n&&t?"&":"")+t;return v(i+(o?"?"+o:""),"richsstsse")}}function S(r){let t=String(r.server_container_url||"").trim(),e=new URL(t,location.href);return e.search="",e.hash="",e}function O(r){if(!r||typeof r!="string")return!1;try{let t=new URL(r,location.href);for(let l=0;l<f.length;l++){let p=S(f[l]);if(t.origin===p.origin&&T(t.pathname)===T(p.pathname))return!1}let e=t.searchParams,i=e.has("gtm"),n=e.has("tag_exp"),o=e.get("tid")||e.get("id")||"",g=/^G-[A-Z0-9]+$/i.test(o);return i&&n&&g}catch(t){if(typeof r=="string"){for(let o=0;o<f.length;o++)try{let g=S(f[o]),l=g.origin+g.pathname;if(r.indexOf(l)!==-1)return!1}catch(g){}let e=r.indexOf("gtm=")!==-1,i=r.indexOf("tag_exp=")!==-1,n=r.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);return!!(e&&i&&n)}return!1}}function k(r){let t=G(r),e=U(t);if(!e)return"";let i=S(e);try{let n=new URL(r,location.href);i.search=n.search,i.searchParams.set("_dtv",w),i.searchParams.set("_dtn","gd")}catch(n){}return v(i.toString(),"richsstsse")}function q(r){let t=G(r),e=U(t);return e?!!e.convert_to_get:!1}let C={debug:!!h.debug,isTargetUrl:O,buildDuplicateUrl:k,getConvertToGet:q},D=[new L,new I,new R,new A];for(let r=0;r<D.length;r++)try{D[r].install(C)}catch(t){h.debug&&console.error("GA4 Duplicator: failed to install interceptor",t)}window.__ga4DuplicatorInitialized=!0};})();
1
+ /* ga4-duplicator - built 2026-02-20T20:15:46.018Z */
2
+ "use strict";(()=>{var w="v0.36.0";window.createGA4Duplicator=function(h){class L{install(t){let e=window.fetch;window.fetch=function(i,n){let o=typeof i=="string"?i:i instanceof URL?i.toString():i.url,g=n&&n.method||i.method||"GET";if(t.isTargetUrl(o)){let l=(g||"GET").toUpperCase(),d=Promise.resolve(void 0);if(l==="POST"){if(n&&Object.prototype.hasOwnProperty.call(n,"body"))d=Promise.resolve(n.body);else if(typeof Request!="undefined"&&i instanceof Request)try{d=i.clone().blob().catch(()=>{})}catch(c){d=Promise.resolve(void 0)}}let s=e.apply(this,arguments),p=t.buildDuplicateUrl(o),u=t.getConvertToGet(o);return l==="GET"?e(p,{method:"GET",keepalive:!0,credentials:"include"}).catch(c=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch:",c)}):l==="POST"&&d.then(c=>{if(u){let a="";if(typeof c=="string")a=c;else if(c instanceof Blob){e(p,{method:"POST",body:c,keepalive:!0,credentials:"include"}).catch(_=>{t.debug&&console.error("gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):",_)});return}let m=a.split(`
3
+ `),y=!1;for(let _=0;_<m.length;_++){let E=m[_].trim();if(E){let M=t.buildDuplicateUrl(o),H=b(M,E);e(H,{method:"GET",keepalive:!0,credentials:"include"}).catch(N=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch (from convert_to_get):",N)}),y=!0}}y||e(p,{method:"GET",keepalive:!0,credentials:"include"}).catch(_=>{t.debug&&console.error("gtm interceptor: error duplicating GET fetch (empty body convert_to_get):",_)})}else e(p,{method:"POST",body:c,keepalive:!0,credentials:"include"}).catch(a=>{t.debug&&console.error("gtm interceptor: error duplicating POST fetch:",a)})}),s}return e.apply(this,arguments)}}}class I{install(t){let e=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(n,o){return this._requestMethod=n,this._requestUrl=o,e.apply(this,arguments)},XMLHttpRequest.prototype.send=function(n){if(this._requestUrl&&t.isTargetUrl(this._requestUrl)){let o=i.apply(this,arguments);try{let g=(this._requestMethod||"GET").toUpperCase(),l=t.buildDuplicateUrl(this._requestUrl),d=t.getConvertToGet(this._requestUrl);if(g==="GET")fetch(l,{method:"GET",keepalive:!0,credentials:"include"}).catch(s=>{t.debug&&console.error("gtm interceptor: error duplicating GET xhr:",s)});else if(g==="POST")if(d){let s="";if(typeof n=="string")s=n;else if(n&&typeof n=="object")try{s=String(n)}catch(c){s=""}let p=s.split(`
4
+ `),u=!1;for(let c=0;c<p.length;c++){let a=p[c].trim();if(a){let m=t.buildDuplicateUrl(this._requestUrl),y=b(m,a);fetch(y,{method:"GET",keepalive:!0,credentials:"include"}).catch(_=>{t.debug&&console.error("gtm interceptor: error duplicating GET xhr (from convert_to_get):",_)}),u=!0}}u||fetch(l,{method:"GET",keepalive:!0,credentials:"include"}).catch(c=>{t.debug&&console.error("gtm interceptor: error duplicating GET xhr (empty body convert_to_get):",c)})}else fetch(l,{method:"POST",body:n,keepalive:!0,credentials:"include"}).catch(s=>{t.debug&&console.error("gtm interceptor: error duplicating POST xhr:",s)})}catch(g){t.debug&&console.error("gtm interceptor: xhr duplication failed:",g)}return o}return i.apply(this,arguments)}}}class R{install(t){if(!navigator.sendBeacon)return;let e=navigator.sendBeacon;navigator.sendBeacon=function(i,n){if(t.isTargetUrl(i)){let o=e.apply(this,arguments);try{let g=t.buildDuplicateUrl(i);if(t.getConvertToGet(i)){let d="";if(typeof n=="string")d=n;else if(n&&typeof n=="object")try{d=String(n)}catch(u){d=""}let s=d.split(`
5
+ `),p=!1;for(let u=0;u<s.length;u++){let c=s[u].trim();if(c){let a=t.buildDuplicateUrl(i),m=b(a,c);fetch(m,{method:"GET",keepalive:!0,credentials:"include"}).catch(y=>{t.debug&&console.error("gtm interceptor: error duplicating GET beacon (from convert_to_get):",y)}),p=!0}}p||fetch(g,{method:"GET",keepalive:!0,credentials:"include"}).catch(u=>{t.debug&&console.error("gtm interceptor: error duplicating GET beacon (empty body convert_to_get):",u)})}else e.call(navigator,g,n)}catch(g){t.debug&&console.error("gtm interceptor: error duplicating sendBeacon:",g)}return o}return e.apply(this,arguments)}}}class A{install(t){try{let e=Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype,"src"),i=e&&e.set,n=e&&e.get,o=HTMLScriptElement.prototype.setAttribute,g=l=>{try{if(!t.isTargetUrl(l))return;fetch(t.buildDuplicateUrl(l),{method:"GET",keepalive:!0,credentials:"include"}).catch(d=>{t.debug&&console.error("gtm interceptor: error duplicating script GET:",d)})}catch(d){}};if(i&&n){let l=i,d=n;Object.defineProperty(HTMLScriptElement.prototype,"src",{configurable:!0,enumerable:!0,get:function(){return d.call(this)},set:function(s){try{let p=this.__ga4LastSrcDuplicated;s&&s!==p&&(g(String(s)),this.__ga4LastSrcDuplicated=String(s));let u=this,c=function(){try{let a=u.src;a&&a!==u.__ga4LastSrcDuplicated&&(g(a),u.__ga4LastSrcDuplicated=a)}catch(a){}u.removeEventListener("load",c)};this.addEventListener("load",c)}catch(p){}l.call(this,s)}})}HTMLScriptElement.prototype.setAttribute=function(l,d){try{if(String(l).toLowerCase()==="src"){let s=String(d),p=this.__ga4LastSrcDuplicated;s&&s!==p&&(g(s),this.__ga4LastSrcDuplicated=s);let u=this,c=function(){try{let a=u.src;a&&a!==u.__ga4LastSrcDuplicated&&(g(a),u.__ga4LastSrcDuplicated=a)}catch(a){}u.removeEventListener("load",c)};this.addEventListener("load",c)}}catch(s){}return o.apply(this,arguments)}}catch(e){}}}if(window.__ga4DuplicatorInitialized){h.debug&&console.warn("GA4 Duplicator: already initialized.");return}let f=[];if(h.destinations&&Array.isArray(h.destinations))for(let r=0;r<h.destinations.length;r++){let t=h.destinations[r];f.push({measurement_id:t.measurement_id,server_container_url:t.server_container_url,convert_to_get:t.convert_to_get!==void 0?t.convert_to_get:h.convert_to_get})}if(h.server_container_url&&f.push({measurement_id:"*",server_container_url:h.server_container_url,convert_to_get:h.convert_to_get}),f.length===0){console.error("GA4 Duplicator: either server_container_url or destinations array is required");return}function T(r){return r=String(r||""),r=r.replace(/\/+$/,""),r===""?"/":r}function P(r,t){if(!r||r==="*")return!0;try{let e=r.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp("^"+e+"$","i").test(t)}catch(e){return r.toLowerCase()===t.toLowerCase()}}function v(r,t){let e=String(r||""),i=String(t||"").trim();if(!e||!i)return e;let n=e.indexOf("#"),o=n>=0?e.slice(0,n):e,g=n>=0?e.slice(n):"",l=o.indexOf("?"),d=l>=0?o.slice(0,l):o,s=l>=0?o.slice(l+1):"",p=s?s.split("&").map(a=>a.trim()).filter(Boolean):[],u=[];for(let a=0;a<p.length;a++){let m=p[a];m!==i&&(m.startsWith(i+"=")||u.push(m))}let c=u.length>0?u.join("&")+"&"+i:i;return d+"?"+c+g}function G(r){try{let t=new URL(r,location.href);return t.searchParams.get("tid")||t.searchParams.get("id")||""}catch(t){let e=r.match(/[?&](?:tid|id)=([^&?#]+)/);return e?decodeURIComponent(e[1]):""}}function U(r){for(let t=0;t<f.length;t++)if(P(f[t].measurement_id,r))return f[t];return null}function b(r,t){try{let e=new URL(r,location.href),i=new URLSearchParams(t);for(let[n]of i.entries())e.searchParams.delete(n);for(let[n,o]of i.entries())e.searchParams.append(n,o);return v(e.toString(),"richsstsse")}catch(e){let i=r.split("?")[0],n=r.match(/\?(.*)/)?r.match(/\?(.*)/)[1]:"",o=n+(n&&t?"&":"")+t;return v(i+(o?"?"+o:""),"richsstsse")}}function S(r){let t=String(r.server_container_url||"").trim(),e=new URL(t,location.href);return e.search="",e.hash="",e}function O(r){if(!r||typeof r!="string")return!1;try{let t=new URL(r,location.href);for(let l=0;l<f.length;l++){let d=S(f[l]);if(t.origin===d.origin&&T(t.pathname)===T(d.pathname))return!1}let e=t.searchParams,i=e.has("gtm"),n=e.has("tag_exp"),o=e.get("tid")||e.get("id")||"",g=/^G-[A-Z0-9]+$/i.test(o);return i&&n&&g}catch(t){if(typeof r=="string"){for(let o=0;o<f.length;o++)try{let g=S(f[o]),l=g.origin+g.pathname;if(r.indexOf(l)!==-1)return!1}catch(g){}let e=r.indexOf("gtm=")!==-1,i=r.indexOf("tag_exp=")!==-1,n=r.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);return!!(e&&i&&n)}return!1}}function k(r){let t=G(r),e=U(t);if(!e)return"";let i=S(e);try{let n=new URL(r,location.href);i.search=n.search,i.searchParams.set("_dtv",w),i.searchParams.set("_dtn","gd")}catch(n){}return v(i.toString(),"richsstsse")}function q(r){let t=G(r),e=U(t);return e?!!e.convert_to_get:!1}let C={debug:!!h.debug,isTargetUrl:O,buildDuplicateUrl:k,getConvertToGet:q},D=[new L,new I,new R,new A];for(let r=0;r<D.length;r++)try{D[r].install(C)}catch(t){h.debug&&console.error("GA4 Duplicator: failed to install interceptor",t)}window.__ga4DuplicatorInitialized=!0};})();
6
6
  //# sourceMappingURL=gd.min.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts", "../src/ga4-duplicator.ts"],
4
- "sourcesContent": ["/**\n * Package version identifier.\n * This value is replaced at build time via esbuild define.\n */\ndeclare const __D8A_VERSION__: string;\n\nfunction devVersionUtc(): string {\n const now = new Date();\n const year = String(now.getUTCFullYear()).slice(-2);\n const month = String(now.getUTCMonth() + 1).padStart(2, \"0\");\n return `dev-${year}-${month}`;\n}\n\nexport const version: string =\n typeof __D8A_VERSION__ !== \"undefined\" && __D8A_VERSION__ ? __D8A_VERSION__ : devVersionUtc();\n", "/**\n * GA4 Duplicator - Intercepts GA4 collect calls and sends duplicates to D8A.\n */\n\nimport { version } from \"./version\";\n\ninterface GA4Destination {\n measurement_id: string;\n server_container_url: string;\n convert_to_get?: boolean;\n}\n\ninterface GA4DuplicatorOptions {\n server_container_url?: string;\n destinations?: GA4Destination[];\n debug?: boolean;\n convert_to_get?: boolean;\n}\n\n(window as any).createGA4Duplicator = function (options: GA4DuplicatorOptions) {\n /**\n * Shared logic and configuration for interceptors.\n */\n interface InterceptorContext {\n debug: boolean;\n isTargetUrl(url: string | null | undefined): boolean;\n buildDuplicateUrl(url: string): string;\n getConvertToGet(url: string): boolean;\n }\n\n /**\n * Base interface for monkey-patching implementations.\n */\n interface NetworkInterceptor {\n install(context: InterceptorContext): void;\n }\n\n class FetchInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalFetch = window.fetch;\n window.fetch = function (\n this: any,\n resource: RequestInfo | URL,\n config?: RequestInit,\n ): Promise<Response> {\n const requestUrl =\n typeof resource === \"string\"\n ? resource\n : resource instanceof URL\n ? resource.toString()\n : (resource as any).url;\n const method = (config && config.method) || (resource as any).method || \"GET\";\n\n if (ctx.isTargetUrl(requestUrl)) {\n const upperMethod = (method || \"GET\").toUpperCase();\n\n // If we need the body from a Request, clone BEFORE calling the original fetch\n let prepareBodyPromise: Promise<any> = Promise.resolve(undefined);\n if (upperMethod === \"POST\") {\n if (config && Object.prototype.hasOwnProperty.call(config, \"body\")) {\n prepareBodyPromise = Promise.resolve(config.body);\n } else if (typeof Request !== \"undefined\" && resource instanceof Request) {\n try {\n const clonedReq = resource.clone();\n prepareBodyPromise = clonedReq.blob().catch(() => undefined);\n } catch {\n prepareBodyPromise = Promise.resolve(undefined);\n }\n }\n }\n\n // First send original request to Google Analytics\n const originalPromise = originalFetch.apply(this, arguments as any);\n\n // Then send duplicate\n const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);\n const convertToGet = ctx.getConvertToGet(requestUrl);\n\n if (upperMethod === \"GET\") {\n originalFetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET fetch:\", error);\n });\n } else if (upperMethod === \"POST\") {\n prepareBodyPromise.then((dupBody) => {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof dupBody === \"string\") {\n bodyStr = dupBody;\n } else if (dupBody instanceof Blob) {\n // For blob, we can't easily convert synchronously, so fall back to POST\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):\",\n error,\n );\n });\n return;\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n originalFetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (from convert_to_get):\",\n error,\n );\n },\n );\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n originalFetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST fetch:\", error);\n });\n }\n });\n }\n\n return originalPromise;\n }\n\n return originalFetch.apply(this, arguments as any);\n };\n }\n }\n\n class XhrInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (this: any, method: string, url: string | URL) {\n this._requestMethod = method;\n this._requestUrl = url;\n return originalXHROpen.apply(this, arguments as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: any,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._requestUrl && ctx.isTargetUrl(this._requestUrl)) {\n // First send original request to Google Analytics\n const originalResult = originalXHRSend.apply(this, arguments as any);\n\n // Then send duplicate to our endpoint mimicking method and payload\n try {\n const method = (this._requestMethod || \"GET\").toUpperCase();\n const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const convertToGet = ctx.getConvertToGet(this._requestUrl);\n\n if (method === \"GET\") {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET xhr:\", error);\n });\n } else if (method === \"POST\") {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof body === \"string\") {\n bodyStr = body;\n } else if (body && typeof body === \"object\") {\n // Try to convert Document or other types to string\n try {\n bodyStr = String(body);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n fetch(duplicateUrl, { method: \"POST\", body: body as any, keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST xhr:\", error);\n },\n );\n }\n }\n } catch (dupErr) {\n if (ctx.debug) console.error(\"gtm interceptor: xhr duplication failed:\", dupErr);\n }\n return originalResult;\n }\n return originalXHRSend.apply(this, arguments as any);\n };\n }\n }\n\n class BeaconInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n if (!navigator.sendBeacon) return;\n\n const originalSendBeacon = navigator.sendBeacon;\n navigator.sendBeacon = function (\n this: any,\n url: string | URL,\n data?: BodyInit | null,\n ): boolean {\n if (ctx.isTargetUrl(url as string)) {\n const originalResult = originalSendBeacon.apply(this, arguments as any);\n try {\n const duplicateUrl = ctx.buildDuplicateUrl(url as string);\n const convertToGet = ctx.getConvertToGet(url as string);\n\n if (convertToGet) {\n // Convert sendBeacon POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof data === \"string\") {\n bodyStr = data;\n } else if (data && typeof data === \"object\") {\n try {\n bodyStr = String(data);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(url as string);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, { method: \"GET\", keepalive: true }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original sendBeacon duplication\n originalSendBeacon.call(navigator, duplicateUrl, data);\n }\n } catch (e) {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating sendBeacon:\", e);\n }\n return originalResult;\n }\n return originalSendBeacon.apply(this, arguments as any);\n };\n }\n }\n\n class ScriptInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n try {\n const scriptSrcDescriptor = Object.getOwnPropertyDescriptor(\n HTMLScriptElement.prototype,\n \"src\",\n );\n const originalScriptSrcSetter = scriptSrcDescriptor && scriptSrcDescriptor.set;\n const originalScriptSrcGetter = scriptSrcDescriptor && scriptSrcDescriptor.get;\n const originalScriptSetAttribute = HTMLScriptElement.prototype.setAttribute;\n\n const duplicateIfGA4Url = (urlString: string) => {\n try {\n if (!ctx.isTargetUrl(urlString)) return;\n fetch(ctx.buildDuplicateUrl(urlString), { method: \"GET\", keepalive: true }).catch(\n (error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating script GET:\", error);\n },\n );\n } catch {\n // Intentionally empty\n }\n };\n\n if (originalScriptSrcSetter && originalScriptSrcGetter) {\n const setter = originalScriptSrcSetter;\n const getter = originalScriptSrcGetter;\n Object.defineProperty(HTMLScriptElement.prototype, \"src\", {\n configurable: true,\n enumerable: true,\n get: function (this: any) {\n return getter.call(this);\n },\n set: function (this: any, value: string) {\n try {\n const last = this.__ga4LastSrcDuplicated;\n if (value && value !== last) {\n duplicateIfGA4Url(String(value));\n this.__ga4LastSrcDuplicated = String(value);\n }\n const self = this;\n const onloadOnce = function () {\n try {\n const finalUrl = self.src;\n if (finalUrl && finalUrl !== self.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrl);\n self.__ga4LastSrcDuplicated = finalUrl;\n }\n } catch {}\n self.removeEventListener(\"load\", onloadOnce);\n };\n this.addEventListener(\"load\", onloadOnce);\n } catch {}\n setter.call(this, value);\n },\n });\n }\n\n HTMLScriptElement.prototype.setAttribute = function (\n this: any,\n name: string,\n value: string,\n ) {\n try {\n if (String(name).toLowerCase() === \"src\") {\n const v = String(value);\n const last = this.__ga4LastSrcDuplicated;\n if (v && v !== last) {\n duplicateIfGA4Url(v);\n this.__ga4LastSrcDuplicated = v;\n }\n const selfAttr = this;\n const onloadOnceAttr = function () {\n try {\n const finalUrlAttr = selfAttr.src;\n if (finalUrlAttr && finalUrlAttr !== selfAttr.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrlAttr);\n selfAttr.__ga4LastSrcDuplicated = finalUrlAttr;\n }\n } catch {}\n selfAttr.removeEventListener(\"load\", onloadOnceAttr);\n };\n this.addEventListener(\"load\", onloadOnceAttr);\n }\n } catch {\n // Intentionally empty\n }\n return originalScriptSetAttribute.apply(this, arguments as any);\n };\n } catch {}\n }\n }\n\n if ((window as any).__ga4DuplicatorInitialized) {\n if (options.debug) console.warn(\"GA4 Duplicator: already initialized.\");\n return;\n }\n\n const destinations: GA4Destination[] = [];\n if (options.destinations && Array.isArray(options.destinations)) {\n for (let i = 0; i < options.destinations.length; i++) {\n const dest = options.destinations[i];\n destinations.push({\n measurement_id: dest.measurement_id,\n server_container_url: dest.server_container_url,\n convert_to_get:\n dest.convert_to_get !== undefined ? dest.convert_to_get : options.convert_to_get,\n });\n }\n }\n\n if (options.server_container_url) {\n destinations.push({\n measurement_id: \"*\",\n server_container_url: options.server_container_url,\n convert_to_get: options.convert_to_get,\n });\n }\n\n if (destinations.length === 0) {\n console.error(\"GA4 Duplicator: either server_container_url or destinations array is required\");\n return;\n }\n\n function normalizePath(p: string): string {\n p = String(p || \"\");\n p = p.replace(/\\/+$/, \"\");\n return p === \"\" ? \"/\" : p;\n }\n\n function matchesId(pattern: string, id: string): boolean {\n if (!pattern || pattern === \"*\") return true;\n try {\n const regexStr = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(\"^\" + regexStr + \"$\", \"i\").test(id);\n } catch {\n return pattern.toLowerCase() === id.toLowerCase();\n }\n }\n\n function ensureBareQueryFlag(url: string, flag: string): string {\n const u = String(url || \"\");\n const f = String(flag || \"\").trim();\n if (!u || !f) return u;\n\n // Keep fragment intact\n const hashIdx = u.indexOf(\"#\");\n const beforeHash = hashIdx >= 0 ? u.slice(0, hashIdx) : u;\n const hash = hashIdx >= 0 ? u.slice(hashIdx) : \"\";\n\n const qIdx = beforeHash.indexOf(\"?\");\n const base = qIdx >= 0 ? beforeHash.slice(0, qIdx) : beforeHash;\n const rawQuery = qIdx >= 0 ? beforeHash.slice(qIdx + 1) : \"\";\n\n const parts = rawQuery\n ? rawQuery\n .split(\"&\")\n .map((p) => p.trim())\n .filter(Boolean)\n : [];\n\n const kept: string[] = [];\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n if (p === f) continue;\n if (p.startsWith(f + \"=\")) continue;\n kept.push(p);\n }\n\n const newQuery = kept.length > 0 ? kept.join(\"&\") + \"&\" + f : f;\n return base + \"?\" + newQuery + hash;\n }\n\n function getMeasurementId(url: string): string {\n try {\n const parsed = new URL(url, location.href);\n return parsed.searchParams.get(\"tid\") || parsed.searchParams.get(\"id\") || \"\";\n } catch {\n const match = url.match(/[?&](?:tid|id)=([^&?#]+)/);\n return match ? decodeURIComponent(match[1]) : \"\";\n }\n }\n\n function getDestinationForId(id: string): GA4Destination | null {\n for (let i = 0; i < destinations.length; i++) {\n if (matchesId(destinations[i].measurement_id, id)) {\n return destinations[i];\n }\n }\n return null;\n }\n\n function mergeBodyLineWithUrl(originalUrl: string, bodyLine: string): string {\n try {\n const url = new URL(originalUrl, location.href);\n const lineParams = new URLSearchParams(bodyLine);\n\n // Line parameters override URL parameters\n for (const [key] of lineParams.entries()) {\n url.searchParams.delete(key);\n }\n for (const [key, value] of lineParams.entries()) {\n url.searchParams.append(key, value);\n }\n\n return ensureBareQueryFlag(url.toString(), \"richsstsse\");\n } catch {\n // Fallback: if URL parsing fails, try string manipulation\n const urlWithoutQuery = originalUrl.split(\"?\")[0];\n const originalParams = originalUrl.match(/\\?(.*)/) ? originalUrl.match(/\\?(.*)/)![1] : \"\";\n const merged = originalParams + (originalParams && bodyLine ? \"&\" : \"\") + bodyLine;\n return ensureBareQueryFlag(urlWithoutQuery + (merged ? \"?\" + merged : \"\"), \"richsstsse\");\n }\n }\n\n function getDuplicateEndpointUrl(dest: GA4Destination): URL {\n const trackingURL = String(dest.server_container_url || \"\").trim();\n const u = new URL(trackingURL, location.href);\n u.search = \"\";\n u.hash = \"\";\n return u;\n }\n\n function isTargetUrl(url: string | null | undefined): boolean {\n if (!url || typeof url !== \"string\") return false;\n try {\n const parsed = new URL(url, location.href);\n\n for (let i = 0; i < destinations.length; i++) {\n const duplicateTarget = getDuplicateEndpointUrl(destinations[i]);\n if (\n parsed.origin === duplicateTarget.origin &&\n normalizePath(parsed.pathname) === normalizePath(duplicateTarget.pathname)\n ) {\n return false;\n }\n }\n\n const params = parsed.searchParams;\n const hasGtm = params.has(\"gtm\");\n const hasTagExp = params.has(\"tag_exp\");\n const measurementId = params.get(\"tid\") || params.get(\"id\") || \"\";\n const isMeasurementIdGA4 = /^G-[A-Z0-9]+$/i.test(measurementId);\n\n return hasGtm && hasTagExp && isMeasurementIdGA4;\n } catch {\n if (typeof url === \"string\") {\n for (let j = 0; j < destinations.length; j++) {\n try {\n const target = getDuplicateEndpointUrl(destinations[j]);\n const targetNoQuery = target.origin + target.pathname;\n if (url.indexOf(targetNoQuery) !== -1) return false;\n } catch {\n // Intentionally empty\n }\n }\n\n const hasGtmFallback = url.indexOf(\"gtm=\") !== -1;\n const hasTagExpFallback = url.indexOf(\"tag_exp=\") !== -1;\n const idMatch = url.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);\n return !!(hasGtmFallback && hasTagExpFallback && idMatch);\n }\n return false;\n }\n }\n\n function buildDuplicateUrl(originalUrl: string): string {\n const id = getMeasurementId(originalUrl);\n const dest = getDestinationForId(id);\n if (!dest) return \"\";\n\n const dst = getDuplicateEndpointUrl(dest);\n try {\n const src = new URL(originalUrl, location.href);\n dst.search = src.search;\n dst.searchParams.set(\"_dtv\", version);\n dst.searchParams.set(\"_dtn\", \"gd\");\n } catch {}\n return ensureBareQueryFlag(dst.toString(), \"richsstsse\");\n }\n\n function getConvertToGet(url: string): boolean {\n const id = getMeasurementId(url);\n const dest = getDestinationForId(id);\n return dest ? !!dest.convert_to_get : false;\n }\n\n const context: InterceptorContext = {\n debug: !!options.debug,\n isTargetUrl,\n buildDuplicateUrl,\n getConvertToGet,\n };\n\n const interceptors: NetworkInterceptor[] = [\n new FetchInterceptor(),\n new XhrInterceptor(),\n new BeaconInterceptor(),\n new ScriptInterceptor(),\n ];\n\n for (let i = 0; i < interceptors.length; i++) {\n try {\n interceptors[i].install(context);\n } catch (e) {\n if (options.debug) console.error(\"GA4 Duplicator: failed to install interceptor\", e);\n }\n }\n\n (window as any).__ga4DuplicatorInitialized = true;\n};\n"],
5
- "mappings": ";mBAaO,IAAMA,EACiD,UCK7D,OAAe,oBAAsB,SAAUC,EAA+B,CAkB7E,MAAMC,CAA+C,CACnD,QAAQC,EAA+B,CACrC,IAAMC,EAAgB,OAAO,MAC7B,OAAO,MAAQ,SAEbC,EACAC,EACmB,CACnB,IAAMC,EACJ,OAAOF,GAAa,SAChBA,EACAA,aAAoB,IAClBA,EAAS,SAAS,EACjBA,EAAiB,IACpBG,EAAUF,GAAUA,EAAO,QAAYD,EAAiB,QAAU,MAExE,GAAIF,EAAI,YAAYI,CAAU,EAAG,CAC/B,IAAME,GAAeD,GAAU,OAAO,YAAY,EAG9CE,EAAmC,QAAQ,QAAQ,MAAS,EAChE,GAAID,IAAgB,QAClB,GAAIH,GAAU,OAAO,UAAU,eAAe,KAAKA,EAAQ,MAAM,EAC/DI,EAAqB,QAAQ,QAAQJ,EAAO,IAAI,UACvC,OAAO,SAAY,aAAeD,aAAoB,QAC/D,GAAI,CAEFK,EADkBL,EAAS,MAAM,EACF,KAAK,EAAE,MAAM,IAAG,EAAY,CAC7D,OAAQM,EAAA,CACND,EAAqB,QAAQ,QAAQ,MAAS,CAChD,EAKJ,IAAME,EAAkBR,EAAc,MAAM,KAAM,SAAgB,EAG5DS,EAAeV,EAAI,kBAAkBI,CAAU,EAC/CO,EAAeX,EAAI,gBAAgBI,CAAU,EAEnD,OAAIE,IAAgB,MAClBL,EAAcS,EAAc,CAAE,OAAQ,MAAO,UAAW,EAAK,CAAC,EAAE,MAAOE,GAAU,CAC3EZ,EAAI,OAAO,QAAQ,MAAM,gDAAiDY,CAAK,CACrF,CAAC,EACQN,IAAgB,QACzBC,EAAmB,KAAMM,GAAY,CACnC,GAAIF,EAAc,CAEhB,IAAIG,EAAU,GACd,GAAI,OAAOD,GAAY,SACrBC,EAAUD,UACDA,aAAmB,KAAM,CAElCZ,EAAcS,EAAc,CAC1B,OAAQ,OACR,KAAMG,EACN,UAAW,EACb,CAAC,EAAE,MAAOD,GAAU,CACdZ,EAAI,OACN,QAAQ,MACN,4EACAY,CACF,CACJ,CAAC,EACD,MACF,CAEA,IAAMG,EAAQD,EAAQ,MAAM;AAAA,CAAI,EAC5BE,EAAU,GACd,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACrC,IAAMC,EAAOH,EAAME,CAAC,EAAE,KAAK,EAC3B,GAAIC,EAAM,CACR,IAAMC,EAAYnB,EAAI,kBAAkBI,CAAU,EAC5CgB,EAAoBC,EAAqBF,EAAWD,CAAI,EAC9DjB,EAAcmB,EAAmB,CAAE,OAAQ,MAAO,UAAW,EAAK,CAAC,EAAE,MAClER,GAAU,CACLZ,EAAI,OACN,QAAQ,MACN,sEACAY,CACF,CACJ,CACF,EACAI,EAAU,EACZ,CACF,CAGKA,GACHf,EAAcS,EAAc,CAAE,OAAQ,MAAO,UAAW,EAAK,CAAC,EAAE,MAAOE,GAAU,CAC3EZ,EAAI,OACN,QAAQ,MACN,4EACAY,CACF,CACJ,CAAC,CAEL,MAEEX,EAAcS,EAAc,CAC1B,OAAQ,OACR,KAAMG,EACN,UAAW,EACb,CAAC,EAAE,MAAOD,GAAU,CACdZ,EAAI,OACN,QAAQ,MAAM,iDAAkDY,CAAK,CACzE,CAAC,CAEL,CAAC,EAGIH,CACT,CAEA,OAAOR,EAAc,MAAM,KAAM,SAAgB,CACnD,CACF,CACF,CAEA,MAAMqB,CAA6C,CACjD,QAAQtB,EAA+B,CACrC,IAAMuB,EAAkB,eAAe,UAAU,KAC3CC,EAAkB,eAAe,UAAU,KAEjD,eAAe,UAAU,KAAO,SAAqBnB,EAAgBoB,EAAmB,CACtF,YAAK,eAAiBpB,EACtB,KAAK,YAAcoB,EACZF,EAAgB,MAAM,KAAM,SAAgB,CACrD,EAEA,eAAe,UAAU,KAAO,SAE9BG,EACA,CACA,GAAI,KAAK,aAAe1B,EAAI,YAAY,KAAK,WAAW,EAAG,CAEzD,IAAM2B,EAAiBH,EAAgB,MAAM,KAAM,SAAgB,EAGnE,GAAI,CACF,IAAMnB,GAAU,KAAK,gBAAkB,OAAO,YAAY,EACpDK,EAAeV,EAAI,kBAAkB,KAAK,WAAW,EACrDW,EAAeX,EAAI,gBAAgB,KAAK,WAAW,EAEzD,GAAIK,IAAW,MACb,MAAMK,EAAc,CAAE,OAAQ,MAAO,UAAW,EAAK,CAAC,EAAE,MAAOE,GAAU,CACnEZ,EAAI,OAAO,QAAQ,MAAM,8CAA+CY,CAAK,CACnF,CAAC,UACQP,IAAW,OACpB,GAAIM,EAAc,CAEhB,IAAIG,EAAU,GACd,GAAI,OAAOY,GAAS,SAClBZ,EAAUY,UACDA,GAAQ,OAAOA,GAAS,SAEjC,GAAI,CACFZ,EAAU,OAAOY,CAAI,CACvB,OAAQlB,EAAA,CACNM,EAAU,EACZ,CAGF,IAAMC,EAAQD,EAAQ,MAAM;AAAA,CAAI,EAC5BE,EAAU,GACd,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACrC,IAAMC,EAAOH,EAAME,CAAC,EAAE,KAAK,EAC3B,GAAIC,EAAM,CACR,IAAMC,EAAYnB,EAAI,kBAAkB,KAAK,WAAW,EAClDoB,EAAoBC,EAAqBF,EAAWD,CAAI,EAC9D,MAAME,EAAmB,CAAE,OAAQ,MAAO,UAAW,EAAK,CAAC,EAAE,MAAOR,GAAU,CACxEZ,EAAI,OACN,QAAQ,MACN,oEACAY,CACF,CACJ,CAAC,EACDI,EAAU,EACZ,CACF,CAGKA,GACH,MAAMN,EAAc,CAAE,OAAQ,MAAO,UAAW,EAAK,CAAC,EAAE,MAAOE,GAAU,CACnEZ,EAAI,OACN,QAAQ,MACN,0EACAY,CACF,CACJ,CAAC,CAEL,MAEE,MAAMF,EAAc,CAAE,OAAQ,OAAQ,KAAMgB,EAAa,UAAW,EAAK,CAAC,EAAE,MACzEd,GAAU,CACLZ,EAAI,OACN,QAAQ,MAAM,+CAAgDY,CAAK,CACvE,CACF,CAGN,OAASgB,EAAQ,CACX5B,EAAI,OAAO,QAAQ,MAAM,2CAA4C4B,CAAM,CACjF,CACA,OAAOD,CACT,CACA,OAAOH,EAAgB,MAAM,KAAM,SAAgB,CACrD,CACF,CACF,CAEA,MAAMK,CAAgD,CACpD,QAAQ7B,EAA+B,CACrC,GAAI,CAAC,UAAU,WAAY,OAE3B,IAAM8B,EAAqB,UAAU,WACrC,UAAU,WAAa,SAErBL,EACAM,EACS,CACT,GAAI/B,EAAI,YAAYyB,CAAa,EAAG,CAClC,IAAME,EAAiBG,EAAmB,MAAM,KAAM,SAAgB,EACtE,GAAI,CACF,IAAMpB,EAAeV,EAAI,kBAAkByB,CAAa,EAGxD,GAFqBzB,EAAI,gBAAgByB,CAAa,EAEpC,CAEhB,IAAIX,EAAU,GACd,GAAI,OAAOiB,GAAS,SAClBjB,EAAUiB,UACDA,GAAQ,OAAOA,GAAS,SACjC,GAAI,CACFjB,EAAU,OAAOiB,CAAI,CACvB,OAAQvB,EAAA,CACNM,EAAU,EACZ,CAGF,IAAMC,EAAQD,EAAQ,MAAM;AAAA,CAAI,EAC5BE,EAAU,GACd,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACrC,IAAMC,EAAOH,EAAME,CAAC,EAAE,KAAK,EAC3B,GAAIC,EAAM,CACR,IAAMC,EAAYnB,EAAI,kBAAkByB,CAAa,EAC/CL,EAAoBC,EAAqBF,EAAWD,CAAI,EAC9D,MAAME,EAAmB,CAAE,OAAQ,MAAO,UAAW,EAAK,CAAC,EAAE,MAAOR,GAAU,CACxEZ,EAAI,OACN,QAAQ,MACN,uEACAY,CACF,CACJ,CAAC,EACDI,EAAU,EACZ,CACF,CAGKA,GACH,MAAMN,EAAc,CAAE,OAAQ,MAAO,UAAW,EAAK,CAAC,EAAE,MAAOE,GAAU,CACnEZ,EAAI,OACN,QAAQ,MACN,6EACAY,CACF,CACJ,CAAC,CAEL,MAEEkB,EAAmB,KAAK,UAAWpB,EAAcqB,CAAI,CAEzD,OAASvB,EAAG,CACNR,EAAI,OAAO,QAAQ,MAAM,iDAAkDQ,CAAC,CAClF,CACA,OAAOmB,CACT,CACA,OAAOG,EAAmB,MAAM,KAAM,SAAgB,CACxD,CACF,CACF,CAEA,MAAME,CAAgD,CACpD,QAAQhC,EAA+B,CACrC,GAAI,CACF,IAAMiC,EAAsB,OAAO,yBACjC,kBAAkB,UAClB,KACF,EACMC,EAA0BD,GAAuBA,EAAoB,IACrEE,EAA0BF,GAAuBA,EAAoB,IACrEG,EAA6B,kBAAkB,UAAU,aAEzDC,EAAqBC,GAAsB,CAC/C,GAAI,CACF,GAAI,CAACtC,EAAI,YAAYsC,CAAS,EAAG,OACjC,MAAMtC,EAAI,kBAAkBsC,CAAS,EAAG,CAAE,OAAQ,MAAO,UAAW,EAAK,CAAC,EAAE,MACzE1B,GAAU,CACLZ,EAAI,OACN,QAAQ,MAAM,iDAAkDY,CAAK,CACzE,CACF,CACF,OAAQJ,EAAA,CAER,CACF,EAEA,GAAI0B,GAA2BC,EAAyB,CACtD,IAAMI,EAASL,EACTM,EAASL,EACf,OAAO,eAAe,kBAAkB,UAAW,MAAO,CACxD,aAAc,GACd,WAAY,GACZ,IAAK,UAAqB,CACxB,OAAOK,EAAO,KAAK,IAAI,CACzB,EACA,IAAK,SAAqBC,EAAe,CACvC,GAAI,CACF,IAAMC,EAAO,KAAK,uBACdD,GAASA,IAAUC,IACrBL,EAAkB,OAAOI,CAAK,CAAC,EAC/B,KAAK,uBAAyB,OAAOA,CAAK,GAE5C,IAAME,EAAO,KACPC,EAAa,UAAY,CAC7B,GAAI,CACF,IAAMC,EAAWF,EAAK,IAClBE,GAAYA,IAAaF,EAAK,yBAChCN,EAAkBQ,CAAQ,EAC1BF,EAAK,uBAAyBE,EAElC,OAAQrC,EAAA,CAAC,CACTmC,EAAK,oBAAoB,OAAQC,CAAU,CAC7C,EACA,KAAK,iBAAiB,OAAQA,CAAU,CAC1C,OAAQpC,EAAA,CAAC,CACT+B,EAAO,KAAK,KAAME,CAAK,CACzB,CACF,CAAC,CACH,CAEA,kBAAkB,UAAU,aAAe,SAEzCK,EACAL,EACA,CACA,GAAI,CACF,GAAI,OAAOK,CAAI,EAAE,YAAY,IAAM,MAAO,CACxC,IAAMC,EAAI,OAAON,CAAK,EAChBC,EAAO,KAAK,uBACdK,GAAKA,IAAML,IACbL,EAAkBU,CAAC,EACnB,KAAK,uBAAyBA,GAEhC,IAAMC,EAAW,KACXC,EAAiB,UAAY,CACjC,GAAI,CACF,IAAMC,EAAeF,EAAS,IAC1BE,GAAgBA,IAAiBF,EAAS,yBAC5CX,EAAkBa,CAAY,EAC9BF,EAAS,uBAAyBE,EAEtC,OAAQ1C,EAAA,CAAC,CACTwC,EAAS,oBAAoB,OAAQC,CAAc,CACrD,EACA,KAAK,iBAAiB,OAAQA,CAAc,CAC9C,CACF,OAAQzC,EAAA,CAER,CACA,OAAO4B,EAA2B,MAAM,KAAM,SAAgB,CAChE,CACF,OAAQ,GAAC,CACX,CACF,CAEA,GAAK,OAAe,2BAA4B,CAC1CtC,EAAQ,OAAO,QAAQ,KAAK,sCAAsC,EACtE,MACF,CAEA,IAAMqD,EAAiC,CAAC,EACxC,GAAIrD,EAAQ,cAAgB,MAAM,QAAQA,EAAQ,YAAY,EAC5D,QAASmB,EAAI,EAAGA,EAAInB,EAAQ,aAAa,OAAQmB,IAAK,CACpD,IAAMmC,EAAOtD,EAAQ,aAAamB,CAAC,EACnCkC,EAAa,KAAK,CAChB,eAAgBC,EAAK,eACrB,qBAAsBA,EAAK,qBAC3B,eACEA,EAAK,iBAAmB,OAAYA,EAAK,eAAiBtD,EAAQ,cACtE,CAAC,CACH,CAWF,GARIA,EAAQ,sBACVqD,EAAa,KAAK,CAChB,eAAgB,IAChB,qBAAsBrD,EAAQ,qBAC9B,eAAgBA,EAAQ,cAC1B,CAAC,EAGCqD,EAAa,SAAW,EAAG,CAC7B,QAAQ,MAAM,+EAA+E,EAC7F,MACF,CAEA,SAASE,EAAcC,EAAmB,CACxC,OAAAA,EAAI,OAAOA,GAAK,EAAE,EAClBA,EAAIA,EAAE,QAAQ,OAAQ,EAAE,EACjBA,IAAM,GAAK,IAAMA,CAC1B,CAEA,SAASC,EAAUC,EAAiBC,EAAqB,CACvD,GAAI,CAACD,GAAWA,IAAY,IAAK,MAAO,GACxC,GAAI,CACF,IAAME,EAAWF,EAAQ,QAAQ,oBAAqB,MAAM,EAAE,QAAQ,MAAO,IAAI,EACjF,OAAO,IAAI,OAAO,IAAME,EAAW,IAAK,GAAG,EAAE,KAAKD,CAAE,CACtD,OAAQ,GACN,OAAOD,EAAQ,YAAY,IAAMC,EAAG,YAAY,CAClD,CACF,CAEA,SAASE,EAAoBlC,EAAamC,EAAsB,CAC9D,IAAMC,EAAI,OAAOpC,GAAO,EAAE,EACpBqC,EAAI,OAAOF,GAAQ,EAAE,EAAE,KAAK,EAClC,GAAI,CAACC,GAAK,CAACC,EAAG,OAAOD,EAGrB,IAAME,EAAUF,EAAE,QAAQ,GAAG,EACvBG,EAAaD,GAAW,EAAIF,EAAE,MAAM,EAAGE,CAAO,EAAIF,EAClDI,EAAOF,GAAW,EAAIF,EAAE,MAAME,CAAO,EAAI,GAEzCG,EAAOF,EAAW,QAAQ,GAAG,EAC7BG,EAAOD,GAAQ,EAAIF,EAAW,MAAM,EAAGE,CAAI,EAAIF,EAC/CI,EAAWF,GAAQ,EAAIF,EAAW,MAAME,EAAO,CAAC,EAAI,GAEpDG,EAAQD,EACVA,EACG,MAAM,GAAG,EACT,IAAKd,GAAMA,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO,EACjB,CAAC,EAECgB,EAAiB,CAAC,EACxB,QAASrD,EAAI,EAAGA,EAAIoD,EAAM,OAAQpD,IAAK,CACrC,IAAMqC,EAAIe,EAAMpD,CAAC,EACbqC,IAAMQ,IACNR,EAAE,WAAWQ,EAAI,GAAG,GACxBQ,EAAK,KAAKhB,CAAC,EACb,CAEA,IAAMiB,EAAWD,EAAK,OAAS,EAAIA,EAAK,KAAK,GAAG,EAAI,IAAMR,EAAIA,EAC9D,OAAOK,EAAO,IAAMI,EAAWN,CACjC,CAEA,SAASO,EAAiB/C,EAAqB,CAC7C,GAAI,CACF,IAAMgD,EAAS,IAAI,IAAIhD,EAAK,SAAS,IAAI,EACzC,OAAOgD,EAAO,aAAa,IAAI,KAAK,GAAKA,EAAO,aAAa,IAAI,IAAI,GAAK,EAC5E,OAAQjE,EAAA,CACN,IAAMkE,EAAQjD,EAAI,MAAM,0BAA0B,EAClD,OAAOiD,EAAQ,mBAAmBA,EAAM,CAAC,CAAC,EAAI,EAChD,CACF,CAEA,SAASC,EAAoBlB,EAAmC,CAC9D,QAASxC,EAAI,EAAGA,EAAIkC,EAAa,OAAQlC,IACvC,GAAIsC,EAAUJ,EAAalC,CAAC,EAAE,eAAgBwC,CAAE,EAC9C,OAAON,EAAalC,CAAC,EAGzB,OAAO,IACT,CAEA,SAASI,EAAqBuD,EAAqBC,EAA0B,CAC3E,GAAI,CACF,IAAMpD,EAAM,IAAI,IAAImD,EAAa,SAAS,IAAI,EACxCE,EAAa,IAAI,gBAAgBD,CAAQ,EAG/C,OAAW,CAACE,CAAG,IAAKD,EAAW,QAAQ,EACrCrD,EAAI,aAAa,OAAOsD,CAAG,EAE7B,OAAW,CAACA,EAAKtC,CAAK,IAAKqC,EAAW,QAAQ,EAC5CrD,EAAI,aAAa,OAAOsD,EAAKtC,CAAK,EAGpC,OAAOkB,EAAoBlC,EAAI,SAAS,EAAG,YAAY,CACzD,OAAQ,GAEN,IAAMuD,EAAkBJ,EAAY,MAAM,GAAG,EAAE,CAAC,EAC1CK,EAAiBL,EAAY,MAAM,QAAQ,EAAIA,EAAY,MAAM,QAAQ,EAAG,CAAC,EAAI,GACjFM,EAASD,GAAkBA,GAAkBJ,EAAW,IAAM,IAAMA,EAC1E,OAAOlB,EAAoBqB,GAAmBE,EAAS,IAAMA,EAAS,IAAK,YAAY,CACzF,CACF,CAEA,SAASC,EAAwB/B,EAA2B,CAC1D,IAAMgC,EAAc,OAAOhC,EAAK,sBAAwB,EAAE,EAAE,KAAK,EAC3DS,EAAI,IAAI,IAAIuB,EAAa,SAAS,IAAI,EAC5C,OAAAvB,EAAE,OAAS,GACXA,EAAE,KAAO,GACFA,CACT,CAEA,SAASwB,EAAY5D,EAAyC,CAC5D,GAAI,CAACA,GAAO,OAAOA,GAAQ,SAAU,MAAO,GAC5C,GAAI,CACF,IAAMgD,EAAS,IAAI,IAAIhD,EAAK,SAAS,IAAI,EAEzC,QAASR,EAAI,EAAGA,EAAIkC,EAAa,OAAQlC,IAAK,CAC5C,IAAMqE,EAAkBH,EAAwBhC,EAAalC,CAAC,CAAC,EAC/D,GACEwD,EAAO,SAAWa,EAAgB,QAClCjC,EAAcoB,EAAO,QAAQ,IAAMpB,EAAciC,EAAgB,QAAQ,EAEzE,MAAO,EAEX,CAEA,IAAMC,EAASd,EAAO,aAChBe,EAASD,EAAO,IAAI,KAAK,EACzBE,EAAYF,EAAO,IAAI,SAAS,EAChCG,EAAgBH,EAAO,IAAI,KAAK,GAAKA,EAAO,IAAI,IAAI,GAAK,GACzDI,EAAqB,iBAAiB,KAAKD,CAAa,EAE9D,OAAOF,GAAUC,GAAaE,CAChC,OAAQnF,EAAA,CACN,GAAI,OAAOiB,GAAQ,SAAU,CAC3B,QAASmE,EAAI,EAAGA,EAAIzC,EAAa,OAAQyC,IACvC,GAAI,CACF,IAAMC,EAASV,EAAwBhC,EAAayC,CAAC,CAAC,EAChDE,EAAgBD,EAAO,OAASA,EAAO,SAC7C,GAAIpE,EAAI,QAAQqE,CAAa,IAAM,GAAI,MAAO,EAChD,OAAQtF,EAAA,CAER,CAGF,IAAMuF,EAAiBtE,EAAI,QAAQ,MAAM,IAAM,GACzCuE,EAAoBvE,EAAI,QAAQ,UAAU,IAAM,GAChDwE,EAAUxE,EAAI,MAAM,+BAA+B,EACzD,MAAO,CAAC,EAAEsE,GAAkBC,GAAqBC,EACnD,CACA,MAAO,EACT,CACF,CAEA,SAASC,EAAkBtB,EAA6B,CACtD,IAAMnB,EAAKe,EAAiBI,CAAW,EACjCxB,EAAOuB,EAAoBlB,CAAE,EACnC,GAAI,CAACL,EAAM,MAAO,GAElB,IAAM+C,EAAMhB,EAAwB/B,CAAI,EACxC,GAAI,CACF,IAAMgD,EAAM,IAAI,IAAIxB,EAAa,SAAS,IAAI,EAC9CuB,EAAI,OAASC,EAAI,OACjBD,EAAI,aAAa,IAAI,OAAQE,CAAO,EACpCF,EAAI,aAAa,IAAI,OAAQ,IAAI,CACnC,OAAQ3F,EAAA,CAAC,CACT,OAAOmD,EAAoBwC,EAAI,SAAS,EAAG,YAAY,CACzD,CAEA,SAASG,EAAgB7E,EAAsB,CAC7C,IAAMgC,EAAKe,EAAiB/C,CAAG,EACzB2B,EAAOuB,EAAoBlB,CAAE,EACnC,OAAOL,EAAO,CAAC,CAACA,EAAK,eAAiB,EACxC,CAEA,IAAMmD,EAA8B,CAClC,MAAO,CAAC,CAACzG,EAAQ,MACjB,YAAAuF,EACA,kBAAAa,EACA,gBAAAI,CACF,EAEME,EAAqC,CACzC,IAAIzG,EACJ,IAAIuB,EACJ,IAAIO,EACJ,IAAIG,CACN,EAEA,QAASf,EAAI,EAAGA,EAAIuF,EAAa,OAAQvF,IACvC,GAAI,CACFuF,EAAavF,CAAC,EAAE,QAAQsF,CAAO,CACjC,OAAS/F,EAAG,CACNV,EAAQ,OAAO,QAAQ,MAAM,gDAAiDU,CAAC,CACrF,CAGD,OAAe,2BAA6B,EAC/C",
4
+ "sourcesContent": ["/**\n * Package version identifier.\n * This value is replaced at build time via esbuild define.\n */\ndeclare const __D8A_VERSION__: string;\n\nfunction devVersionUtc(): string {\n const now = new Date();\n const year = String(now.getUTCFullYear()).slice(-2);\n const month = String(now.getUTCMonth() + 1).padStart(2, \"0\");\n return `dev-${year}-${month}`;\n}\n\nexport const version: string =\n typeof __D8A_VERSION__ !== \"undefined\" && __D8A_VERSION__ ? __D8A_VERSION__ : devVersionUtc();\n", "/**\n * GA4 Duplicator - Intercepts GA4 collect calls and sends duplicates to D8A.\n */\n\nimport { version } from \"./version\";\n\ninterface GA4Destination {\n measurement_id: string;\n server_container_url: string;\n convert_to_get?: boolean;\n}\n\ninterface GA4DuplicatorOptions {\n server_container_url?: string;\n destinations?: GA4Destination[];\n debug?: boolean;\n convert_to_get?: boolean;\n}\n\n(window as any).createGA4Duplicator = function (options: GA4DuplicatorOptions) {\n /**\n * Shared logic and configuration for interceptors.\n */\n interface InterceptorContext {\n debug: boolean;\n isTargetUrl(url: string | null | undefined): boolean;\n buildDuplicateUrl(url: string): string;\n getConvertToGet(url: string): boolean;\n }\n\n /**\n * Base interface for monkey-patching implementations.\n */\n interface NetworkInterceptor {\n install(context: InterceptorContext): void;\n }\n\n class FetchInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalFetch = window.fetch;\n window.fetch = function (\n this: any,\n resource: RequestInfo | URL,\n config?: RequestInit,\n ): Promise<Response> {\n const requestUrl =\n typeof resource === \"string\"\n ? resource\n : resource instanceof URL\n ? resource.toString()\n : (resource as any).url;\n const method = (config && config.method) || (resource as any).method || \"GET\";\n\n if (ctx.isTargetUrl(requestUrl)) {\n const upperMethod = (method || \"GET\").toUpperCase();\n\n // If we need the body from a Request, clone BEFORE calling the original fetch\n let prepareBodyPromise: Promise<any> = Promise.resolve(undefined);\n if (upperMethod === \"POST\") {\n if (config && Object.prototype.hasOwnProperty.call(config, \"body\")) {\n prepareBodyPromise = Promise.resolve(config.body);\n } else if (typeof Request !== \"undefined\" && resource instanceof Request) {\n try {\n const clonedReq = resource.clone();\n prepareBodyPromise = clonedReq.blob().catch(() => undefined);\n } catch {\n prepareBodyPromise = Promise.resolve(undefined);\n }\n }\n }\n\n // First send original request to Google Analytics\n const originalPromise = originalFetch.apply(this, arguments as any);\n\n // Then send duplicate\n const duplicateUrl = ctx.buildDuplicateUrl(requestUrl);\n const convertToGet = ctx.getConvertToGet(requestUrl);\n\n if (upperMethod === \"GET\") {\n originalFetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET fetch:\", error);\n });\n } else if (upperMethod === \"POST\") {\n prepareBodyPromise.then((dupBody) => {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof dupBody === \"string\") {\n bodyStr = dupBody;\n } else if (dupBody instanceof Blob) {\n // For blob, we can't easily convert synchronously, so fall back to POST\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating POST fetch (convert_to_get with Blob):\",\n error,\n );\n });\n return;\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n originalFetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n originalFetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET fetch (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n originalFetch(duplicateUrl, {\n method: \"POST\",\n body: dupBody,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST fetch:\", error);\n });\n }\n });\n }\n\n return originalPromise;\n }\n\n return originalFetch.apply(this, arguments as any);\n };\n }\n }\n\n class XhrInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (this: any, method: string, url: string | URL) {\n this._requestMethod = method;\n this._requestUrl = url;\n return originalXHROpen.apply(this, arguments as any);\n };\n\n XMLHttpRequest.prototype.send = function (\n this: any,\n body?: Document | XMLHttpRequestBodyInit | null,\n ) {\n if (this._requestUrl && ctx.isTargetUrl(this._requestUrl)) {\n // First send original request to Google Analytics\n const originalResult = originalXHRSend.apply(this, arguments as any);\n\n // Then send duplicate to our endpoint mimicking method and payload\n try {\n const method = (this._requestMethod || \"GET\").toUpperCase();\n const duplicateUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const convertToGet = ctx.getConvertToGet(this._requestUrl);\n\n if (method === \"GET\") {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating GET xhr:\", error);\n });\n } else if (method === \"POST\") {\n if (convertToGet) {\n // Convert POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof body === \"string\") {\n bodyStr = body;\n } else if (body && typeof body === \"object\") {\n // Try to convert Document or other types to string\n try {\n bodyStr = String(body);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(this._requestUrl);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET xhr (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original POST duplication\n fetch(duplicateUrl, {\n method: \"POST\",\n body: body as any,\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\"gtm interceptor: error duplicating POST xhr:\", error);\n });\n }\n }\n } catch (dupErr) {\n if (ctx.debug) console.error(\"gtm interceptor: xhr duplication failed:\", dupErr);\n }\n return originalResult;\n }\n return originalXHRSend.apply(this, arguments as any);\n };\n }\n }\n\n class BeaconInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n if (!navigator.sendBeacon) return;\n\n const originalSendBeacon = navigator.sendBeacon;\n navigator.sendBeacon = function (\n this: any,\n url: string | URL,\n data?: BodyInit | null,\n ): boolean {\n if (ctx.isTargetUrl(url as string)) {\n const originalResult = originalSendBeacon.apply(this, arguments as any);\n try {\n const duplicateUrl = ctx.buildDuplicateUrl(url as string);\n const convertToGet = ctx.getConvertToGet(url as string);\n\n if (convertToGet) {\n // Convert sendBeacon POST to GET: split body into lines and send each as a separate GET request\n let bodyStr = \"\";\n if (typeof data === \"string\") {\n bodyStr = data;\n } else if (data && typeof data === \"object\") {\n try {\n bodyStr = String(data);\n } catch {\n bodyStr = \"\";\n }\n }\n\n const lines = bodyStr.split(\"\\n\");\n let sentAny = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line) {\n const mergedUrl = ctx.buildDuplicateUrl(url as string);\n const urlWithMergedLine = mergeBodyLineWithUrl(mergedUrl, line);\n fetch(urlWithMergedLine, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (from convert_to_get):\",\n error,\n );\n });\n sentAny = true;\n }\n }\n\n // If body is empty or all lines were empty, send one GET with just URL params\n if (!sentAny) {\n fetch(duplicateUrl, {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug)\n console.error(\n \"gtm interceptor: error duplicating GET beacon (empty body convert_to_get):\",\n error,\n );\n });\n }\n } else {\n // Original sendBeacon duplication\n originalSendBeacon.call(navigator, duplicateUrl, data);\n }\n } catch (e) {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating sendBeacon:\", e);\n }\n return originalResult;\n }\n return originalSendBeacon.apply(this, arguments as any);\n };\n }\n }\n\n class ScriptInterceptor implements NetworkInterceptor {\n install(ctx: InterceptorContext): void {\n try {\n const scriptSrcDescriptor = Object.getOwnPropertyDescriptor(\n HTMLScriptElement.prototype,\n \"src\",\n );\n const originalScriptSrcSetter = scriptSrcDescriptor && scriptSrcDescriptor.set;\n const originalScriptSrcGetter = scriptSrcDescriptor && scriptSrcDescriptor.get;\n const originalScriptSetAttribute = HTMLScriptElement.prototype.setAttribute;\n\n const duplicateIfGA4Url = (urlString: string) => {\n try {\n if (!ctx.isTargetUrl(urlString)) return;\n fetch(ctx.buildDuplicateUrl(urlString), {\n method: \"GET\",\n keepalive: true,\n credentials: \"include\",\n }).catch((error) => {\n if (ctx.debug) console.error(\"gtm interceptor: error duplicating script GET:\", error);\n });\n } catch {\n // Intentionally empty\n }\n };\n\n if (originalScriptSrcSetter && originalScriptSrcGetter) {\n const setter = originalScriptSrcSetter;\n const getter = originalScriptSrcGetter;\n Object.defineProperty(HTMLScriptElement.prototype, \"src\", {\n configurable: true,\n enumerable: true,\n get: function (this: any) {\n return getter.call(this);\n },\n set: function (this: any, value: string) {\n try {\n const last = this.__ga4LastSrcDuplicated;\n if (value && value !== last) {\n duplicateIfGA4Url(String(value));\n this.__ga4LastSrcDuplicated = String(value);\n }\n const self = this;\n const onloadOnce = function () {\n try {\n const finalUrl = self.src;\n if (finalUrl && finalUrl !== self.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrl);\n self.__ga4LastSrcDuplicated = finalUrl;\n }\n } catch {}\n self.removeEventListener(\"load\", onloadOnce);\n };\n this.addEventListener(\"load\", onloadOnce);\n } catch {}\n setter.call(this, value);\n },\n });\n }\n\n HTMLScriptElement.prototype.setAttribute = function (\n this: any,\n name: string,\n value: string,\n ) {\n try {\n if (String(name).toLowerCase() === \"src\") {\n const v = String(value);\n const last = this.__ga4LastSrcDuplicated;\n if (v && v !== last) {\n duplicateIfGA4Url(v);\n this.__ga4LastSrcDuplicated = v;\n }\n const selfAttr = this;\n const onloadOnceAttr = function () {\n try {\n const finalUrlAttr = selfAttr.src;\n if (finalUrlAttr && finalUrlAttr !== selfAttr.__ga4LastSrcDuplicated) {\n duplicateIfGA4Url(finalUrlAttr);\n selfAttr.__ga4LastSrcDuplicated = finalUrlAttr;\n }\n } catch {}\n selfAttr.removeEventListener(\"load\", onloadOnceAttr);\n };\n this.addEventListener(\"load\", onloadOnceAttr);\n }\n } catch {\n // Intentionally empty\n }\n return originalScriptSetAttribute.apply(this, arguments as any);\n };\n } catch {}\n }\n }\n\n if ((window as any).__ga4DuplicatorInitialized) {\n if (options.debug) console.warn(\"GA4 Duplicator: already initialized.\");\n return;\n }\n\n const destinations: GA4Destination[] = [];\n if (options.destinations && Array.isArray(options.destinations)) {\n for (let i = 0; i < options.destinations.length; i++) {\n const dest = options.destinations[i];\n destinations.push({\n measurement_id: dest.measurement_id,\n server_container_url: dest.server_container_url,\n convert_to_get:\n dest.convert_to_get !== undefined ? dest.convert_to_get : options.convert_to_get,\n });\n }\n }\n\n if (options.server_container_url) {\n destinations.push({\n measurement_id: \"*\",\n server_container_url: options.server_container_url,\n convert_to_get: options.convert_to_get,\n });\n }\n\n if (destinations.length === 0) {\n console.error(\"GA4 Duplicator: either server_container_url or destinations array is required\");\n return;\n }\n\n function normalizePath(p: string): string {\n p = String(p || \"\");\n p = p.replace(/\\/+$/, \"\");\n return p === \"\" ? \"/\" : p;\n }\n\n function matchesId(pattern: string, id: string): boolean {\n if (!pattern || pattern === \"*\") return true;\n try {\n const regexStr = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/\\*/g, \".*\");\n return new RegExp(\"^\" + regexStr + \"$\", \"i\").test(id);\n } catch {\n return pattern.toLowerCase() === id.toLowerCase();\n }\n }\n\n function ensureBareQueryFlag(url: string, flag: string): string {\n const u = String(url || \"\");\n const f = String(flag || \"\").trim();\n if (!u || !f) return u;\n\n // Keep fragment intact\n const hashIdx = u.indexOf(\"#\");\n const beforeHash = hashIdx >= 0 ? u.slice(0, hashIdx) : u;\n const hash = hashIdx >= 0 ? u.slice(hashIdx) : \"\";\n\n const qIdx = beforeHash.indexOf(\"?\");\n const base = qIdx >= 0 ? beforeHash.slice(0, qIdx) : beforeHash;\n const rawQuery = qIdx >= 0 ? beforeHash.slice(qIdx + 1) : \"\";\n\n const parts = rawQuery\n ? rawQuery\n .split(\"&\")\n .map((p) => p.trim())\n .filter(Boolean)\n : [];\n\n const kept: string[] = [];\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n if (p === f) continue;\n if (p.startsWith(f + \"=\")) continue;\n kept.push(p);\n }\n\n const newQuery = kept.length > 0 ? kept.join(\"&\") + \"&\" + f : f;\n return base + \"?\" + newQuery + hash;\n }\n\n function getMeasurementId(url: string): string {\n try {\n const parsed = new URL(url, location.href);\n return parsed.searchParams.get(\"tid\") || parsed.searchParams.get(\"id\") || \"\";\n } catch {\n const match = url.match(/[?&](?:tid|id)=([^&?#]+)/);\n return match ? decodeURIComponent(match[1]) : \"\";\n }\n }\n\n function getDestinationForId(id: string): GA4Destination | null {\n for (let i = 0; i < destinations.length; i++) {\n if (matchesId(destinations[i].measurement_id, id)) {\n return destinations[i];\n }\n }\n return null;\n }\n\n function mergeBodyLineWithUrl(originalUrl: string, bodyLine: string): string {\n try {\n const url = new URL(originalUrl, location.href);\n const lineParams = new URLSearchParams(bodyLine);\n\n // Line parameters override URL parameters\n for (const [key] of lineParams.entries()) {\n url.searchParams.delete(key);\n }\n for (const [key, value] of lineParams.entries()) {\n url.searchParams.append(key, value);\n }\n\n return ensureBareQueryFlag(url.toString(), \"richsstsse\");\n } catch {\n // Fallback: if URL parsing fails, try string manipulation\n const urlWithoutQuery = originalUrl.split(\"?\")[0];\n const originalParams = originalUrl.match(/\\?(.*)/) ? originalUrl.match(/\\?(.*)/)![1] : \"\";\n const merged = originalParams + (originalParams && bodyLine ? \"&\" : \"\") + bodyLine;\n return ensureBareQueryFlag(urlWithoutQuery + (merged ? \"?\" + merged : \"\"), \"richsstsse\");\n }\n }\n\n function getDuplicateEndpointUrl(dest: GA4Destination): URL {\n const trackingURL = String(dest.server_container_url || \"\").trim();\n const u = new URL(trackingURL, location.href);\n u.search = \"\";\n u.hash = \"\";\n return u;\n }\n\n function isTargetUrl(url: string | null | undefined): boolean {\n if (!url || typeof url !== \"string\") return false;\n try {\n const parsed = new URL(url, location.href);\n\n for (let i = 0; i < destinations.length; i++) {\n const duplicateTarget = getDuplicateEndpointUrl(destinations[i]);\n if (\n parsed.origin === duplicateTarget.origin &&\n normalizePath(parsed.pathname) === normalizePath(duplicateTarget.pathname)\n ) {\n return false;\n }\n }\n\n const params = parsed.searchParams;\n const hasGtm = params.has(\"gtm\");\n const hasTagExp = params.has(\"tag_exp\");\n const measurementId = params.get(\"tid\") || params.get(\"id\") || \"\";\n const isMeasurementIdGA4 = /^G-[A-Z0-9]+$/i.test(measurementId);\n\n return hasGtm && hasTagExp && isMeasurementIdGA4;\n } catch {\n if (typeof url === \"string\") {\n for (let j = 0; j < destinations.length; j++) {\n try {\n const target = getDuplicateEndpointUrl(destinations[j]);\n const targetNoQuery = target.origin + target.pathname;\n if (url.indexOf(targetNoQuery) !== -1) return false;\n } catch {\n // Intentionally empty\n }\n }\n\n const hasGtmFallback = url.indexOf(\"gtm=\") !== -1;\n const hasTagExpFallback = url.indexOf(\"tag_exp=\") !== -1;\n const idMatch = url.match(/[?&](?:tid|id)=G-[A-Za-z0-9]+/);\n return !!(hasGtmFallback && hasTagExpFallback && idMatch);\n }\n return false;\n }\n }\n\n function buildDuplicateUrl(originalUrl: string): string {\n const id = getMeasurementId(originalUrl);\n const dest = getDestinationForId(id);\n if (!dest) return \"\";\n\n const dst = getDuplicateEndpointUrl(dest);\n try {\n const src = new URL(originalUrl, location.href);\n dst.search = src.search;\n dst.searchParams.set(\"_dtv\", version);\n dst.searchParams.set(\"_dtn\", \"gd\");\n } catch {}\n return ensureBareQueryFlag(dst.toString(), \"richsstsse\");\n }\n\n function getConvertToGet(url: string): boolean {\n const id = getMeasurementId(url);\n const dest = getDestinationForId(id);\n return dest ? !!dest.convert_to_get : false;\n }\n\n const context: InterceptorContext = {\n debug: !!options.debug,\n isTargetUrl,\n buildDuplicateUrl,\n getConvertToGet,\n };\n\n const interceptors: NetworkInterceptor[] = [\n new FetchInterceptor(),\n new XhrInterceptor(),\n new BeaconInterceptor(),\n new ScriptInterceptor(),\n ];\n\n for (let i = 0; i < interceptors.length; i++) {\n try {\n interceptors[i].install(context);\n } catch (e) {\n if (options.debug) console.error(\"GA4 Duplicator: failed to install interceptor\", e);\n }\n }\n\n (window as any).__ga4DuplicatorInitialized = true;\n};\n"],
5
+ "mappings": ";mBAaO,IAAMA,EACiD,UCK7D,OAAe,oBAAsB,SAAUC,EAA+B,CAkB7E,MAAMC,CAA+C,CACnD,QAAQC,EAA+B,CACrC,IAAMC,EAAgB,OAAO,MAC7B,OAAO,MAAQ,SAEbC,EACAC,EACmB,CACnB,IAAMC,EACJ,OAAOF,GAAa,SAChBA,EACAA,aAAoB,IAClBA,EAAS,SAAS,EACjBA,EAAiB,IACpBG,EAAUF,GAAUA,EAAO,QAAYD,EAAiB,QAAU,MAExE,GAAIF,EAAI,YAAYI,CAAU,EAAG,CAC/B,IAAME,GAAeD,GAAU,OAAO,YAAY,EAG9CE,EAAmC,QAAQ,QAAQ,MAAS,EAChE,GAAID,IAAgB,QAClB,GAAIH,GAAU,OAAO,UAAU,eAAe,KAAKA,EAAQ,MAAM,EAC/DI,EAAqB,QAAQ,QAAQJ,EAAO,IAAI,UACvC,OAAO,SAAY,aAAeD,aAAoB,QAC/D,GAAI,CAEFK,EADkBL,EAAS,MAAM,EACF,KAAK,EAAE,MAAM,IAAG,EAAY,CAC7D,OAAQM,EAAA,CACND,EAAqB,QAAQ,QAAQ,MAAS,CAChD,EAKJ,IAAME,EAAkBR,EAAc,MAAM,KAAM,SAAgB,EAG5DS,EAAeV,EAAI,kBAAkBI,CAAU,EAC/CO,EAAeX,EAAI,gBAAgBI,CAAU,EAEnD,OAAIE,IAAgB,MAClBL,EAAcS,EAAc,CAC1B,OAAQ,MACR,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOE,GAAU,CACdZ,EAAI,OAAO,QAAQ,MAAM,gDAAiDY,CAAK,CACrF,CAAC,EACQN,IAAgB,QACzBC,EAAmB,KAAMM,GAAY,CACnC,GAAIF,EAAc,CAEhB,IAAIG,EAAU,GACd,GAAI,OAAOD,GAAY,SACrBC,EAAUD,UACDA,aAAmB,KAAM,CAElCZ,EAAcS,EAAc,CAC1B,OAAQ,OACR,KAAMG,EACN,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOD,GAAU,CACdZ,EAAI,OACN,QAAQ,MACN,4EACAY,CACF,CACJ,CAAC,EACD,MACF,CAEA,IAAMG,EAAQD,EAAQ,MAAM;AAAA,CAAI,EAC5BE,EAAU,GACd,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACrC,IAAMC,EAAOH,EAAME,CAAC,EAAE,KAAK,EAC3B,GAAIC,EAAM,CACR,IAAMC,EAAYnB,EAAI,kBAAkBI,CAAU,EAC5CgB,EAAoBC,EAAqBF,EAAWD,CAAI,EAC9DjB,EAAcmB,EAAmB,CAC/B,OAAQ,MACR,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOR,GAAU,CACdZ,EAAI,OACN,QAAQ,MACN,sEACAY,CACF,CACJ,CAAC,EACDI,EAAU,EACZ,CACF,CAGKA,GACHf,EAAcS,EAAc,CAC1B,OAAQ,MACR,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOE,GAAU,CACdZ,EAAI,OACN,QAAQ,MACN,4EACAY,CACF,CACJ,CAAC,CAEL,MAEEX,EAAcS,EAAc,CAC1B,OAAQ,OACR,KAAMG,EACN,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOD,GAAU,CACdZ,EAAI,OACN,QAAQ,MAAM,iDAAkDY,CAAK,CACzE,CAAC,CAEL,CAAC,EAGIH,CACT,CAEA,OAAOR,EAAc,MAAM,KAAM,SAAgB,CACnD,CACF,CACF,CAEA,MAAMqB,CAA6C,CACjD,QAAQtB,EAA+B,CACrC,IAAMuB,EAAkB,eAAe,UAAU,KAC3CC,EAAkB,eAAe,UAAU,KAEjD,eAAe,UAAU,KAAO,SAAqBnB,EAAgBoB,EAAmB,CACtF,YAAK,eAAiBpB,EACtB,KAAK,YAAcoB,EACZF,EAAgB,MAAM,KAAM,SAAgB,CACrD,EAEA,eAAe,UAAU,KAAO,SAE9BG,EACA,CACA,GAAI,KAAK,aAAe1B,EAAI,YAAY,KAAK,WAAW,EAAG,CAEzD,IAAM2B,EAAiBH,EAAgB,MAAM,KAAM,SAAgB,EAGnE,GAAI,CACF,IAAMnB,GAAU,KAAK,gBAAkB,OAAO,YAAY,EACpDK,EAAeV,EAAI,kBAAkB,KAAK,WAAW,EACrDW,EAAeX,EAAI,gBAAgB,KAAK,WAAW,EAEzD,GAAIK,IAAW,MACb,MAAMK,EAAc,CAClB,OAAQ,MACR,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOE,GAAU,CACdZ,EAAI,OAAO,QAAQ,MAAM,8CAA+CY,CAAK,CACnF,CAAC,UACQP,IAAW,OACpB,GAAIM,EAAc,CAEhB,IAAIG,EAAU,GACd,GAAI,OAAOY,GAAS,SAClBZ,EAAUY,UACDA,GAAQ,OAAOA,GAAS,SAEjC,GAAI,CACFZ,EAAU,OAAOY,CAAI,CACvB,OAAQlB,EAAA,CACNM,EAAU,EACZ,CAGF,IAAMC,EAAQD,EAAQ,MAAM;AAAA,CAAI,EAC5BE,EAAU,GACd,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACrC,IAAMC,EAAOH,EAAME,CAAC,EAAE,KAAK,EAC3B,GAAIC,EAAM,CACR,IAAMC,EAAYnB,EAAI,kBAAkB,KAAK,WAAW,EAClDoB,EAAoBC,EAAqBF,EAAWD,CAAI,EAC9D,MAAME,EAAmB,CACvB,OAAQ,MACR,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOR,GAAU,CACdZ,EAAI,OACN,QAAQ,MACN,oEACAY,CACF,CACJ,CAAC,EACDI,EAAU,EACZ,CACF,CAGKA,GACH,MAAMN,EAAc,CAClB,OAAQ,MACR,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOE,GAAU,CACdZ,EAAI,OACN,QAAQ,MACN,0EACAY,CACF,CACJ,CAAC,CAEL,MAEE,MAAMF,EAAc,CAClB,OAAQ,OACR,KAAMgB,EACN,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOd,GAAU,CACdZ,EAAI,OACN,QAAQ,MAAM,+CAAgDY,CAAK,CACvE,CAAC,CAGP,OAASgB,EAAQ,CACX5B,EAAI,OAAO,QAAQ,MAAM,2CAA4C4B,CAAM,CACjF,CACA,OAAOD,CACT,CACA,OAAOH,EAAgB,MAAM,KAAM,SAAgB,CACrD,CACF,CACF,CAEA,MAAMK,CAAgD,CACpD,QAAQ7B,EAA+B,CACrC,GAAI,CAAC,UAAU,WAAY,OAE3B,IAAM8B,EAAqB,UAAU,WACrC,UAAU,WAAa,SAErBL,EACAM,EACS,CACT,GAAI/B,EAAI,YAAYyB,CAAa,EAAG,CAClC,IAAME,EAAiBG,EAAmB,MAAM,KAAM,SAAgB,EACtE,GAAI,CACF,IAAMpB,EAAeV,EAAI,kBAAkByB,CAAa,EAGxD,GAFqBzB,EAAI,gBAAgByB,CAAa,EAEpC,CAEhB,IAAIX,EAAU,GACd,GAAI,OAAOiB,GAAS,SAClBjB,EAAUiB,UACDA,GAAQ,OAAOA,GAAS,SACjC,GAAI,CACFjB,EAAU,OAAOiB,CAAI,CACvB,OAAQvB,EAAA,CACNM,EAAU,EACZ,CAGF,IAAMC,EAAQD,EAAQ,MAAM;AAAA,CAAI,EAC5BE,EAAU,GACd,QAASC,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACrC,IAAMC,EAAOH,EAAME,CAAC,EAAE,KAAK,EAC3B,GAAIC,EAAM,CACR,IAAMC,EAAYnB,EAAI,kBAAkByB,CAAa,EAC/CL,EAAoBC,EAAqBF,EAAWD,CAAI,EAC9D,MAAME,EAAmB,CACvB,OAAQ,MACR,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOR,GAAU,CACdZ,EAAI,OACN,QAAQ,MACN,uEACAY,CACF,CACJ,CAAC,EACDI,EAAU,EACZ,CACF,CAGKA,GACH,MAAMN,EAAc,CAClB,OAAQ,MACR,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAOE,GAAU,CACdZ,EAAI,OACN,QAAQ,MACN,6EACAY,CACF,CACJ,CAAC,CAEL,MAEEkB,EAAmB,KAAK,UAAWpB,EAAcqB,CAAI,CAEzD,OAASvB,EAAG,CACNR,EAAI,OAAO,QAAQ,MAAM,iDAAkDQ,CAAC,CAClF,CACA,OAAOmB,CACT,CACA,OAAOG,EAAmB,MAAM,KAAM,SAAgB,CACxD,CACF,CACF,CAEA,MAAME,CAAgD,CACpD,QAAQhC,EAA+B,CACrC,GAAI,CACF,IAAMiC,EAAsB,OAAO,yBACjC,kBAAkB,UAClB,KACF,EACMC,EAA0BD,GAAuBA,EAAoB,IACrEE,EAA0BF,GAAuBA,EAAoB,IACrEG,EAA6B,kBAAkB,UAAU,aAEzDC,EAAqBC,GAAsB,CAC/C,GAAI,CACF,GAAI,CAACtC,EAAI,YAAYsC,CAAS,EAAG,OACjC,MAAMtC,EAAI,kBAAkBsC,CAAS,EAAG,CACtC,OAAQ,MACR,UAAW,GACX,YAAa,SACf,CAAC,EAAE,MAAO1B,GAAU,CACdZ,EAAI,OAAO,QAAQ,MAAM,iDAAkDY,CAAK,CACtF,CAAC,CACH,OAAQJ,EAAA,CAER,CACF,EAEA,GAAI0B,GAA2BC,EAAyB,CACtD,IAAMI,EAASL,EACTM,EAASL,EACf,OAAO,eAAe,kBAAkB,UAAW,MAAO,CACxD,aAAc,GACd,WAAY,GACZ,IAAK,UAAqB,CACxB,OAAOK,EAAO,KAAK,IAAI,CACzB,EACA,IAAK,SAAqBC,EAAe,CACvC,GAAI,CACF,IAAMC,EAAO,KAAK,uBACdD,GAASA,IAAUC,IACrBL,EAAkB,OAAOI,CAAK,CAAC,EAC/B,KAAK,uBAAyB,OAAOA,CAAK,GAE5C,IAAME,EAAO,KACPC,EAAa,UAAY,CAC7B,GAAI,CACF,IAAMC,EAAWF,EAAK,IAClBE,GAAYA,IAAaF,EAAK,yBAChCN,EAAkBQ,CAAQ,EAC1BF,EAAK,uBAAyBE,EAElC,OAAQrC,EAAA,CAAC,CACTmC,EAAK,oBAAoB,OAAQC,CAAU,CAC7C,EACA,KAAK,iBAAiB,OAAQA,CAAU,CAC1C,OAAQpC,EAAA,CAAC,CACT+B,EAAO,KAAK,KAAME,CAAK,CACzB,CACF,CAAC,CACH,CAEA,kBAAkB,UAAU,aAAe,SAEzCK,EACAL,EACA,CACA,GAAI,CACF,GAAI,OAAOK,CAAI,EAAE,YAAY,IAAM,MAAO,CACxC,IAAMC,EAAI,OAAON,CAAK,EAChBC,EAAO,KAAK,uBACdK,GAAKA,IAAML,IACbL,EAAkBU,CAAC,EACnB,KAAK,uBAAyBA,GAEhC,IAAMC,EAAW,KACXC,EAAiB,UAAY,CACjC,GAAI,CACF,IAAMC,EAAeF,EAAS,IAC1BE,GAAgBA,IAAiBF,EAAS,yBAC5CX,EAAkBa,CAAY,EAC9BF,EAAS,uBAAyBE,EAEtC,OAAQ1C,EAAA,CAAC,CACTwC,EAAS,oBAAoB,OAAQC,CAAc,CACrD,EACA,KAAK,iBAAiB,OAAQA,CAAc,CAC9C,CACF,OAAQzC,EAAA,CAER,CACA,OAAO4B,EAA2B,MAAM,KAAM,SAAgB,CAChE,CACF,OAAQ,GAAC,CACX,CACF,CAEA,GAAK,OAAe,2BAA4B,CAC1CtC,EAAQ,OAAO,QAAQ,KAAK,sCAAsC,EACtE,MACF,CAEA,IAAMqD,EAAiC,CAAC,EACxC,GAAIrD,EAAQ,cAAgB,MAAM,QAAQA,EAAQ,YAAY,EAC5D,QAASmB,EAAI,EAAGA,EAAInB,EAAQ,aAAa,OAAQmB,IAAK,CACpD,IAAMmC,EAAOtD,EAAQ,aAAamB,CAAC,EACnCkC,EAAa,KAAK,CAChB,eAAgBC,EAAK,eACrB,qBAAsBA,EAAK,qBAC3B,eACEA,EAAK,iBAAmB,OAAYA,EAAK,eAAiBtD,EAAQ,cACtE,CAAC,CACH,CAWF,GARIA,EAAQ,sBACVqD,EAAa,KAAK,CAChB,eAAgB,IAChB,qBAAsBrD,EAAQ,qBAC9B,eAAgBA,EAAQ,cAC1B,CAAC,EAGCqD,EAAa,SAAW,EAAG,CAC7B,QAAQ,MAAM,+EAA+E,EAC7F,MACF,CAEA,SAASE,EAAcC,EAAmB,CACxC,OAAAA,EAAI,OAAOA,GAAK,EAAE,EAClBA,EAAIA,EAAE,QAAQ,OAAQ,EAAE,EACjBA,IAAM,GAAK,IAAMA,CAC1B,CAEA,SAASC,EAAUC,EAAiBC,EAAqB,CACvD,GAAI,CAACD,GAAWA,IAAY,IAAK,MAAO,GACxC,GAAI,CACF,IAAME,EAAWF,EAAQ,QAAQ,oBAAqB,MAAM,EAAE,QAAQ,MAAO,IAAI,EACjF,OAAO,IAAI,OAAO,IAAME,EAAW,IAAK,GAAG,EAAE,KAAKD,CAAE,CACtD,OAAQ,GACN,OAAOD,EAAQ,YAAY,IAAMC,EAAG,YAAY,CAClD,CACF,CAEA,SAASE,EAAoBlC,EAAamC,EAAsB,CAC9D,IAAMC,EAAI,OAAOpC,GAAO,EAAE,EACpBqC,EAAI,OAAOF,GAAQ,EAAE,EAAE,KAAK,EAClC,GAAI,CAACC,GAAK,CAACC,EAAG,OAAOD,EAGrB,IAAME,EAAUF,EAAE,QAAQ,GAAG,EACvBG,EAAaD,GAAW,EAAIF,EAAE,MAAM,EAAGE,CAAO,EAAIF,EAClDI,EAAOF,GAAW,EAAIF,EAAE,MAAME,CAAO,EAAI,GAEzCG,EAAOF,EAAW,QAAQ,GAAG,EAC7BG,EAAOD,GAAQ,EAAIF,EAAW,MAAM,EAAGE,CAAI,EAAIF,EAC/CI,EAAWF,GAAQ,EAAIF,EAAW,MAAME,EAAO,CAAC,EAAI,GAEpDG,EAAQD,EACVA,EACG,MAAM,GAAG,EACT,IAAKd,GAAMA,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO,EACjB,CAAC,EAECgB,EAAiB,CAAC,EACxB,QAASrD,EAAI,EAAGA,EAAIoD,EAAM,OAAQpD,IAAK,CACrC,IAAMqC,EAAIe,EAAMpD,CAAC,EACbqC,IAAMQ,IACNR,EAAE,WAAWQ,EAAI,GAAG,GACxBQ,EAAK,KAAKhB,CAAC,EACb,CAEA,IAAMiB,EAAWD,EAAK,OAAS,EAAIA,EAAK,KAAK,GAAG,EAAI,IAAMR,EAAIA,EAC9D,OAAOK,EAAO,IAAMI,EAAWN,CACjC,CAEA,SAASO,EAAiB/C,EAAqB,CAC7C,GAAI,CACF,IAAMgD,EAAS,IAAI,IAAIhD,EAAK,SAAS,IAAI,EACzC,OAAOgD,EAAO,aAAa,IAAI,KAAK,GAAKA,EAAO,aAAa,IAAI,IAAI,GAAK,EAC5E,OAAQjE,EAAA,CACN,IAAMkE,EAAQjD,EAAI,MAAM,0BAA0B,EAClD,OAAOiD,EAAQ,mBAAmBA,EAAM,CAAC,CAAC,EAAI,EAChD,CACF,CAEA,SAASC,EAAoBlB,EAAmC,CAC9D,QAASxC,EAAI,EAAGA,EAAIkC,EAAa,OAAQlC,IACvC,GAAIsC,EAAUJ,EAAalC,CAAC,EAAE,eAAgBwC,CAAE,EAC9C,OAAON,EAAalC,CAAC,EAGzB,OAAO,IACT,CAEA,SAASI,EAAqBuD,EAAqBC,EAA0B,CAC3E,GAAI,CACF,IAAMpD,EAAM,IAAI,IAAImD,EAAa,SAAS,IAAI,EACxCE,EAAa,IAAI,gBAAgBD,CAAQ,EAG/C,OAAW,CAACE,CAAG,IAAKD,EAAW,QAAQ,EACrCrD,EAAI,aAAa,OAAOsD,CAAG,EAE7B,OAAW,CAACA,EAAKtC,CAAK,IAAKqC,EAAW,QAAQ,EAC5CrD,EAAI,aAAa,OAAOsD,EAAKtC,CAAK,EAGpC,OAAOkB,EAAoBlC,EAAI,SAAS,EAAG,YAAY,CACzD,OAAQ,GAEN,IAAMuD,EAAkBJ,EAAY,MAAM,GAAG,EAAE,CAAC,EAC1CK,EAAiBL,EAAY,MAAM,QAAQ,EAAIA,EAAY,MAAM,QAAQ,EAAG,CAAC,EAAI,GACjFM,EAASD,GAAkBA,GAAkBJ,EAAW,IAAM,IAAMA,EAC1E,OAAOlB,EAAoBqB,GAAmBE,EAAS,IAAMA,EAAS,IAAK,YAAY,CACzF,CACF,CAEA,SAASC,EAAwB/B,EAA2B,CAC1D,IAAMgC,EAAc,OAAOhC,EAAK,sBAAwB,EAAE,EAAE,KAAK,EAC3DS,EAAI,IAAI,IAAIuB,EAAa,SAAS,IAAI,EAC5C,OAAAvB,EAAE,OAAS,GACXA,EAAE,KAAO,GACFA,CACT,CAEA,SAASwB,EAAY5D,EAAyC,CAC5D,GAAI,CAACA,GAAO,OAAOA,GAAQ,SAAU,MAAO,GAC5C,GAAI,CACF,IAAMgD,EAAS,IAAI,IAAIhD,EAAK,SAAS,IAAI,EAEzC,QAASR,EAAI,EAAGA,EAAIkC,EAAa,OAAQlC,IAAK,CAC5C,IAAMqE,EAAkBH,EAAwBhC,EAAalC,CAAC,CAAC,EAC/D,GACEwD,EAAO,SAAWa,EAAgB,QAClCjC,EAAcoB,EAAO,QAAQ,IAAMpB,EAAciC,EAAgB,QAAQ,EAEzE,MAAO,EAEX,CAEA,IAAMC,EAASd,EAAO,aAChBe,EAASD,EAAO,IAAI,KAAK,EACzBE,EAAYF,EAAO,IAAI,SAAS,EAChCG,EAAgBH,EAAO,IAAI,KAAK,GAAKA,EAAO,IAAI,IAAI,GAAK,GACzDI,EAAqB,iBAAiB,KAAKD,CAAa,EAE9D,OAAOF,GAAUC,GAAaE,CAChC,OAAQnF,EAAA,CACN,GAAI,OAAOiB,GAAQ,SAAU,CAC3B,QAASmE,EAAI,EAAGA,EAAIzC,EAAa,OAAQyC,IACvC,GAAI,CACF,IAAMC,EAASV,EAAwBhC,EAAayC,CAAC,CAAC,EAChDE,EAAgBD,EAAO,OAASA,EAAO,SAC7C,GAAIpE,EAAI,QAAQqE,CAAa,IAAM,GAAI,MAAO,EAChD,OAAQtF,EAAA,CAER,CAGF,IAAMuF,EAAiBtE,EAAI,QAAQ,MAAM,IAAM,GACzCuE,EAAoBvE,EAAI,QAAQ,UAAU,IAAM,GAChDwE,EAAUxE,EAAI,MAAM,+BAA+B,EACzD,MAAO,CAAC,EAAEsE,GAAkBC,GAAqBC,EACnD,CACA,MAAO,EACT,CACF,CAEA,SAASC,EAAkBtB,EAA6B,CACtD,IAAMnB,EAAKe,EAAiBI,CAAW,EACjCxB,EAAOuB,EAAoBlB,CAAE,EACnC,GAAI,CAACL,EAAM,MAAO,GAElB,IAAM+C,EAAMhB,EAAwB/B,CAAI,EACxC,GAAI,CACF,IAAMgD,EAAM,IAAI,IAAIxB,EAAa,SAAS,IAAI,EAC9CuB,EAAI,OAASC,EAAI,OACjBD,EAAI,aAAa,IAAI,OAAQE,CAAO,EACpCF,EAAI,aAAa,IAAI,OAAQ,IAAI,CACnC,OAAQ3F,EAAA,CAAC,CACT,OAAOmD,EAAoBwC,EAAI,SAAS,EAAG,YAAY,CACzD,CAEA,SAASG,EAAgB7E,EAAsB,CAC7C,IAAMgC,EAAKe,EAAiB/C,CAAG,EACzB2B,EAAOuB,EAAoBlB,CAAE,EACnC,OAAOL,EAAO,CAAC,CAACA,EAAK,eAAiB,EACxC,CAEA,IAAMmD,EAA8B,CAClC,MAAO,CAAC,CAACzG,EAAQ,MACjB,YAAAuF,EACA,kBAAAa,EACA,gBAAAI,CACF,EAEME,EAAqC,CACzC,IAAIzG,EACJ,IAAIuB,EACJ,IAAIO,EACJ,IAAIG,CACN,EAEA,QAASf,EAAI,EAAGA,EAAIuF,EAAa,OAAQvF,IACvC,GAAI,CACFuF,EAAavF,CAAC,EAAE,QAAQsF,CAAO,CACjC,OAAS/F,EAAG,CACNV,EAAQ,OAAO,QAAQ,MAAM,gDAAiDU,CAAC,CACrF,CAGD,OAAe,2BAA6B,EAC/C",
6
6
  "names": ["version", "options", "FetchInterceptor", "ctx", "originalFetch", "resource", "config", "requestUrl", "method", "upperMethod", "prepareBodyPromise", "e", "originalPromise", "duplicateUrl", "convertToGet", "error", "dupBody", "bodyStr", "lines", "sentAny", "i", "line", "mergedUrl", "urlWithMergedLine", "mergeBodyLineWithUrl", "XhrInterceptor", "originalXHROpen", "originalXHRSend", "url", "body", "originalResult", "dupErr", "BeaconInterceptor", "originalSendBeacon", "data", "ScriptInterceptor", "scriptSrcDescriptor", "originalScriptSrcSetter", "originalScriptSrcGetter", "originalScriptSetAttribute", "duplicateIfGA4Url", "urlString", "setter", "getter", "value", "last", "self", "onloadOnce", "finalUrl", "name", "v", "selfAttr", "onloadOnceAttr", "finalUrlAttr", "destinations", "dest", "normalizePath", "p", "matchesId", "pattern", "id", "regexStr", "ensureBareQueryFlag", "flag", "u", "f", "hashIdx", "beforeHash", "hash", "qIdx", "base", "rawQuery", "parts", "kept", "newQuery", "getMeasurementId", "parsed", "match", "getDestinationForId", "originalUrl", "bodyLine", "lineParams", "key", "urlWithoutQuery", "originalParams", "merged", "getDuplicateEndpointUrl", "trackingURL", "isTargetUrl", "duplicateTarget", "params", "hasGtm", "hasTagExp", "measurementId", "isMeasurementIdGA4", "j", "target", "targetNoQuery", "hasGtmFallback", "hasTagExpFallback", "idMatch", "buildDuplicateUrl", "dst", "src", "version", "getConvertToGet", "context", "interceptors"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@d8a-tech/gd",
3
- "version": "0.35.0",
3
+ "version": "0.36.0",
4
4
  "type": "module",
5
5
  "description": "GA4 network request duplicator (browser inline script) - TypeScript source + minified dist build.",
6
6
  "license": "MIT",
package/src.hash CHANGED
@@ -1 +1 @@
1
- ac610db3a099cfbc776efbecb0b9cd96e3e7c5f9014d4b6c19e59631e8e4584d -
1
+ 17117454d817fdc6cd06ea872f1800180524a7c9e009756af13fa445a3baa9b8 -