@buildbase/sdk 0.0.70 → 0.0.73
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/AGENTS.md +5 -2
- package/CHANGELOG.md +114 -0
- package/README.md +141 -4
- package/dist/cli.mjs +2 -0
- package/dist/css/styles.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +589 -14
- package/dist/index.mjs +1 -1
- package/dist/mcp/index.cjs +1 -1
- package/dist/mcp/index.d.ts +102 -0
- package/dist/mcp/index.mjs +1 -1
- package/dist/react/chunks/SettingsDialog-CvBSuMf-.mjs +2 -0
- package/dist/react/chunks/SettingsDialog-DdOUkwIi.cjs +2 -0
- package/dist/react/chunks/SubscriptionDialog-CdZzF5eK.cjs +2 -0
- package/dist/react/chunks/SubscriptionDialog-D8_frxHc.mjs +2 -0
- package/dist/react/chunks/ar-CRVhjpVE.cjs +2 -0
- package/dist/react/chunks/ar-DFPDdu2U.mjs +2 -0
- package/dist/react/chunks/de-BGhzn711.cjs +2 -0
- package/dist/react/chunks/de-Bqi8scew.mjs +2 -0
- package/dist/react/chunks/es-D_Eqhob3.mjs +2 -0
- package/dist/react/chunks/es-DyrMaeUp.cjs +2 -0
- package/dist/react/chunks/fr-C0SkloRr.cjs +2 -0
- package/dist/react/chunks/fr-DkZpFQ1Q.mjs +2 -0
- package/dist/react/chunks/hi-B9TK87T8.cjs +2 -0
- package/dist/react/chunks/hi-DrTcPkiY.mjs +2 -0
- package/dist/react/chunks/ja-Dgahn--0.mjs +2 -0
- package/dist/react/chunks/ja-LjzlAhAT.cjs +2 -0
- package/dist/react/chunks/react-BSHCN-ZU.mjs +2 -0
- package/dist/react/chunks/react-DQqr117G.cjs +2 -0
- package/dist/react/chunks/zh-BezRHDHs.mjs +2 -0
- package/dist/react/chunks/zh-CcodKi4U.cjs +2 -0
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +826 -25
- package/dist/react/index.mjs +1 -1
- package/dist/server/browser.cjs +1 -0
- package/dist/server/browser.mjs +1 -0
- package/dist/server/index.cjs +1 -0
- package/dist/server/index.d.ts +556 -0
- package/dist/server/index.mjs +1 -0
- package/dist/server/next/index.cjs +1 -0
- package/dist/server/next/index.d.ts +156 -0
- package/dist/server/next/index.mjs +1 -0
- package/dist/tracking/index.cjs +1 -1
- package/dist/tracking/index.d.ts +205 -8
- package/dist/tracking/index.mjs +1 -1
- package/docs/ERROR_CODES.md +24 -0
- package/docs/SERVER-CONTENT.md +297 -0
- package/docs/UI-CONFIG.md +1 -0
- package/package.json +66 -5
- package/dist/react/chunks/SettingsDialog-VKPguQBs.mjs +0 -2
- package/dist/react/chunks/SettingsDialog-_kfJ6j25.cjs +0 -2
- package/dist/react/chunks/SubscriptionDialog-C_1ipsC2.cjs +0 -2
- package/dist/react/chunks/SubscriptionDialog-Cbk3EGBr.mjs +0 -2
- package/dist/react/chunks/ar-CHTRXlXt.mjs +0 -2
- package/dist/react/chunks/ar-DPJVNHJV.cjs +0 -2
- package/dist/react/chunks/de-CdPeKWZ2.mjs +0 -2
- package/dist/react/chunks/de-DPd09yf-.cjs +0 -2
- package/dist/react/chunks/es-BWGnjJKJ.mjs +0 -2
- package/dist/react/chunks/es-WdOYGt6G.cjs +0 -2
- package/dist/react/chunks/fr-Big5DFPB.mjs +0 -2
- package/dist/react/chunks/fr-LIbCvYeh.cjs +0 -2
- package/dist/react/chunks/hi-BoCY3pFe.cjs +0 -2
- package/dist/react/chunks/hi-jArNRknR.mjs +0 -2
- package/dist/react/chunks/ja-Cwdz0hCu.mjs +0 -2
- package/dist/react/chunks/ja-E0jqCiVq.cjs +0 -2
- package/dist/react/chunks/react-B0MFoaXI.mjs +0 -2
- package/dist/react/chunks/react-DSRfaDnZ.cjs +0 -2
- package/dist/react/chunks/zh-glRKcdia.mjs +0 -2
- package/dist/react/chunks/zh-tU-AqFYI.cjs +0 -2
package/dist/tracking/index.d.ts
CHANGED
|
@@ -385,8 +385,65 @@ interface PublicTrackingConfig {
|
|
|
385
385
|
scripts: PublicTrackingScript[];
|
|
386
386
|
consent: {
|
|
387
387
|
manifest: TrackingConsentEntry[];
|
|
388
|
+
/**
|
|
389
|
+
* The client's regional default, as set in the console. Absent on a
|
|
390
|
+
* client that never chose one, and on a server older than this field -
|
|
391
|
+
* both of which keep the long-standing default of denied everywhere.
|
|
392
|
+
*/
|
|
393
|
+
defaults?: RegionalConsent;
|
|
394
|
+
/** Bumped by the console whenever the manifest's meaning changes. */
|
|
395
|
+
manifestVersion?: string;
|
|
388
396
|
};
|
|
389
397
|
dataLayerName?: string;
|
|
398
|
+
/**
|
|
399
|
+
* The caller's country as the edge saw it (ISO 3166-1 alpha-2), or `null`
|
|
400
|
+
* when the request carried no country header. Never guessed in the browser.
|
|
401
|
+
*/
|
|
402
|
+
country?: string | null;
|
|
403
|
+
/** The caller's subdivision (`CA` for California) when the edge sends one. */
|
|
404
|
+
region?: string | null;
|
|
405
|
+
/**
|
|
406
|
+
* `consent.defaults` resolved against `country` on the server, so the SDK
|
|
407
|
+
* and any server-side send agree on what this visitor's default was.
|
|
408
|
+
*/
|
|
409
|
+
resolvedConsentDefault?: ConsentDefault;
|
|
410
|
+
/**
|
|
411
|
+
* Whether this app sends hashed user data with conversions (enhanced
|
|
412
|
+
* conversions). Off unless switched on per app in the console.
|
|
413
|
+
*/
|
|
414
|
+
enhancedConversions?: boolean;
|
|
415
|
+
}
|
|
416
|
+
/** A consent default: what applies before the visitor has answered. */
|
|
417
|
+
type ConsentDefault = 'granted' | 'denied';
|
|
418
|
+
/**
|
|
419
|
+
* A consent default that depends on where the visitor is.
|
|
420
|
+
*
|
|
421
|
+
* `default` covers everyone no region rule matches. Region entries are ISO
|
|
422
|
+
* 3166-1 alpha-2 countries (`GB`), ISO 3166-2 subdivisions (`US-CA`), or `EEA`,
|
|
423
|
+
* which expands to the current member states.
|
|
424
|
+
*
|
|
425
|
+
* @example The recommended setting
|
|
426
|
+
* ```ts
|
|
427
|
+
* { default: 'granted', regions: { denied: ['EEA', 'GB', 'CH'] } }
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
interface RegionalConsent {
|
|
431
|
+
default: ConsentDefault;
|
|
432
|
+
regions?: {
|
|
433
|
+
denied?: string[];
|
|
434
|
+
granted?: string[];
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
/** Extra detail recorded with a consent answer. */
|
|
438
|
+
interface ConsentSetOptions {
|
|
439
|
+
/**
|
|
440
|
+
* Where the answer was given, stored on the consent record: `banner`,
|
|
441
|
+
* `sign_up_prompt`, or a label of the app's own. Passing one always sends a
|
|
442
|
+
* record, even when the same answer was recorded before.
|
|
443
|
+
*/
|
|
444
|
+
source?: string;
|
|
445
|
+
/** The IAB TCF (or similar) string from the app's CMP, when it has one. */
|
|
446
|
+
consentString?: string;
|
|
390
447
|
}
|
|
391
448
|
/** What the visitor has agreed to. `null` until they have been asked. */
|
|
392
449
|
interface ConsentState {
|
|
@@ -433,12 +490,21 @@ interface TrackingOptions {
|
|
|
433
490
|
/** Set false to fetch nothing and render nothing. */
|
|
434
491
|
enabled?: boolean;
|
|
435
492
|
/**
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
493
|
+
* The consent default, before the visitor answers.
|
|
494
|
+
*
|
|
495
|
+
* - `auto` (default): the client's regional default from the console, when
|
|
496
|
+
* one is set; otherwise Consent Mode v2 denied everywhere until
|
|
497
|
+
* `consent.set()`.
|
|
498
|
+
* - `{ default, regions }`: a regional default set in code, which wins over
|
|
499
|
+
* the console's. Resolved against the country the server saw.
|
|
500
|
+
* - `granted`: the app asserting it already has a lawful basis everywhere -
|
|
501
|
+
* their assertion, not ours.
|
|
502
|
+
* - `denied`: nothing loads at all, not even a Consent Mode tag.
|
|
503
|
+
*
|
|
504
|
+
* Whichever default applies, `consent.set()` replaces it. The choice of
|
|
505
|
+
* default, and its lawful basis, belong to the app.
|
|
440
506
|
*/
|
|
441
|
-
consent?: 'auto' | 'granted' | 'denied';
|
|
507
|
+
consent?: 'auto' | 'granted' | 'denied' | RegionalConsent;
|
|
442
508
|
/**
|
|
443
509
|
* Fire a `page_view` on SPA navigation. Turn it off when the app's GTM
|
|
444
510
|
* container already does it - double-counted pageviews is the single most
|
|
@@ -483,12 +549,69 @@ interface TrackingOptions {
|
|
|
483
549
|
debug?: boolean;
|
|
484
550
|
}
|
|
485
551
|
|
|
552
|
+
/**
|
|
553
|
+
* Enhanced conversions: hashed user data sent with a conversion so the ad
|
|
554
|
+
* platform can match it to a signed-in account on its side.
|
|
555
|
+
*
|
|
556
|
+
* Match rates without it are low, and lowest exactly where it matters: an
|
|
557
|
+
* iOS Safari sign-up has no third-party cookie to match on, so it goes
|
|
558
|
+
* unattributed. A SHA-256 of the normalised email is what Google and Meta
|
|
559
|
+
* both specify for that match.
|
|
560
|
+
*
|
|
561
|
+
* Three rules hold throughout:
|
|
562
|
+
* 1. Plaintext never leaves this file. The identity is hashed as soon as it
|
|
563
|
+
* is handed over, and only the hashes are kept.
|
|
564
|
+
* 2. Nothing is sent unless the org switched enhanced conversions on for this
|
|
565
|
+
* app AND the visitor granted `ad_user_data` - which for us is marketing
|
|
566
|
+
* consent. The hashes wait in memory until both are true.
|
|
567
|
+
* 3. None of this touches `setUser`'s user id, which every ad network forbids
|
|
568
|
+
* from carrying an email.
|
|
569
|
+
*/
|
|
570
|
+
interface UserIdentity {
|
|
571
|
+
email?: string | null;
|
|
572
|
+
/** E.164, with the country code: `+14155550100`. Anything else is dropped. */
|
|
573
|
+
phone?: string | null;
|
|
574
|
+
}
|
|
575
|
+
interface HashedIdentity {
|
|
576
|
+
emailHash?: string;
|
|
577
|
+
phoneHash?: string;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Google's normalisation: trim, lower case, and for gmail.com and
|
|
581
|
+
* googlemail.com remove the dots in the local part, because Gmail ignores
|
|
582
|
+
* them and one inbox must be one hash.
|
|
583
|
+
*/
|
|
584
|
+
declare function normalizeEmail(email: string | null | undefined): string;
|
|
585
|
+
/** E.164 digits with a leading `+`, or '' when there is no country code. */
|
|
586
|
+
declare function normalizePhone(phone: string | null | undefined): string;
|
|
587
|
+
declare function hashIdentity(identity: UserIdentity): Promise<HashedIdentity>;
|
|
588
|
+
|
|
486
589
|
interface TrackingContextValue {
|
|
487
590
|
/** What is installed, for a banner to render. Empty until config loads. */
|
|
488
591
|
consent: {
|
|
489
592
|
manifest: TrackingConsentEntry[];
|
|
593
|
+
/** The visitor's own answer. `null` until they have given one. */
|
|
490
594
|
state: ConsentState | null;
|
|
491
|
-
|
|
595
|
+
/**
|
|
596
|
+
* What is in force right now: the answer when there is one, otherwise the
|
|
597
|
+
* default for this visitor's region. `null` while that default is denied
|
|
598
|
+
* or not yet known. This, not `state`, is what a server-side send should
|
|
599
|
+
* be told.
|
|
600
|
+
*/
|
|
601
|
+
effective: ConsentState | null;
|
|
602
|
+
/**
|
|
603
|
+
* The default that applied to this visitor before any answer, once the
|
|
604
|
+
* config has arrived. `null` before then.
|
|
605
|
+
*/
|
|
606
|
+
default: ConsentDefault | null;
|
|
607
|
+
/** The country the server saw this visitor in, or `null` if it did not know. */
|
|
608
|
+
country: string | null;
|
|
609
|
+
/**
|
|
610
|
+
* Give the visitor's answer. Also sends a consent record to the server,
|
|
611
|
+
* so the app can later show what was agreed to and when; the same answer
|
|
612
|
+
* restored on every page load is recorded once.
|
|
613
|
+
*/
|
|
614
|
+
set: (state: ConsentState, options?: ConsentSetOptions) => void;
|
|
492
615
|
};
|
|
493
616
|
/** Fire an event. Canonical names map to every vendor; others go to the data layer. */
|
|
494
617
|
track: (name: string, params?: Record<string, unknown>, options?: TrackOptions) => void;
|
|
@@ -498,6 +621,22 @@ interface TrackingContextValue {
|
|
|
498
621
|
* Never an email or a name: every ad network forbids it in these fields.
|
|
499
622
|
*/
|
|
500
623
|
setUser: (userId: string, traits?: Record<string, unknown>) => void;
|
|
624
|
+
/**
|
|
625
|
+
* The signed-in person's email and phone, for enhanced conversions.
|
|
626
|
+
*
|
|
627
|
+
* Hashed with SHA-256 in the browser the moment it is called; the plaintext
|
|
628
|
+
* is not kept and never sent. The hashes reach Google (`user_data`) and Meta
|
|
629
|
+
* (advanced matching) only when enhanced conversions is on for this app in
|
|
630
|
+
* the console AND the visitor granted marketing consent. An `email` or
|
|
631
|
+
* `phone` passed in `setUser` traits is routed here instead of to vendors.
|
|
632
|
+
*/
|
|
633
|
+
setIdentity: (identity: UserIdentity | null) => void;
|
|
634
|
+
/**
|
|
635
|
+
* Headers sent with consent records, so a record is linked to the account
|
|
636
|
+
* that gave it: `x-session-id` in an app, the auth `state` on the hosted
|
|
637
|
+
* pages. The SDK's own providers set this; most apps never need it.
|
|
638
|
+
*/
|
|
639
|
+
setConsentRecordHeaders: (headers: Record<string, string>) => void;
|
|
501
640
|
/**
|
|
502
641
|
* Add fields to every event from here on. For anything not known when the
|
|
503
642
|
* provider mounted: an experiment assignment, a tenant tier fetched after
|
|
@@ -665,5 +804,63 @@ declare const FUNNEL_EVENTS: {
|
|
|
665
804
|
};
|
|
666
805
|
type FunnelEventName = keyof typeof FUNNEL_EVENTS;
|
|
667
806
|
|
|
668
|
-
|
|
669
|
-
|
|
807
|
+
/**
|
|
808
|
+
* Where a consent default applies.
|
|
809
|
+
*
|
|
810
|
+
* A single global default makes every tenant choose between two wrong answers:
|
|
811
|
+
* denied everywhere, which throws away measurement in the US and India where
|
|
812
|
+
* nobody asked for it, or granted everywhere, which is unlawful in the EEA.
|
|
813
|
+
* Google's own Consent Mode takes a `region` list for exactly this reason, and
|
|
814
|
+
* this is the same idea one level up, so the SDK's decision about which tags
|
|
815
|
+
* may load and Google's decision about which pings may carry cookies agree.
|
|
816
|
+
*
|
|
817
|
+
* ── Why the country comes from the server ───────────────────────────────────
|
|
818
|
+
* The browser does not know where it is. A timezone is a setting the visitor
|
|
819
|
+
* chose, a language is a preference, and both are wrong for every traveller,
|
|
820
|
+
* every VPN and every expat. The CDN in front of the tracking-config endpoint
|
|
821
|
+
* does know - it routed the request - so that endpoint returns the country it
|
|
822
|
+
* saw and this file only ever resolves a rule against that answer. With no
|
|
823
|
+
* answer, the rule resolves to denied: an unknown visitor is treated as one
|
|
824
|
+
* the law protects, never as one it does not.
|
|
825
|
+
*/
|
|
826
|
+
|
|
827
|
+
/**
|
|
828
|
+
* The European Economic Area: the 27 EU member states plus Iceland,
|
|
829
|
+
* Liechtenstein and Norway. ISO 3166-1 alpha-2, which is what Google's
|
|
830
|
+
* `region` parameter and every CDN country header use - so Greece is `GR`
|
|
831
|
+
* here, not the `EL` the EU uses in its own documents.
|
|
832
|
+
*
|
|
833
|
+
* The UK and Switzerland are NOT in it. Both have their own regimes that a
|
|
834
|
+
* tenant will usually want treated the same way, which is why the safe default
|
|
835
|
+
* lists `GB` and `CH` beside `EEA` rather than folding them in here.
|
|
836
|
+
*/
|
|
837
|
+
declare const EEA_COUNTRIES: readonly ["AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE", "IS", "LI", "NO"];
|
|
838
|
+
/**
|
|
839
|
+
* The default we recommend, and the one the console pre-selects: denied where
|
|
840
|
+
* a consent law applies before any tracking, granted elsewhere.
|
|
841
|
+
*
|
|
842
|
+
* A recommendation, not a ruling. Which default is lawful for a given app
|
|
843
|
+
* depends on its audience, its purposes and its own legal advice, and that
|
|
844
|
+
* decision belongs to the tenant.
|
|
845
|
+
*/
|
|
846
|
+
declare const SAFE_REGIONAL_CONSENT: RegionalConsent;
|
|
847
|
+
/**
|
|
848
|
+
* Expand `EEA` and normalise a region list. Unknown shapes are dropped rather
|
|
849
|
+
* than passed on: Google ignores a malformed region silently, so forwarding
|
|
850
|
+
* one would look like it worked.
|
|
851
|
+
*/
|
|
852
|
+
declare function expandRegions(regions: readonly string[] | undefined): string[];
|
|
853
|
+
/**
|
|
854
|
+
* The default that applies to one visitor.
|
|
855
|
+
*
|
|
856
|
+
* A subdivision rule (`US-CA`) beats a country rule, as it does in Google's
|
|
857
|
+
* own resolution, and `denied` beats `granted` where a tenant listed a place
|
|
858
|
+
* under both - a contradiction resolved in the visitor's favour.
|
|
859
|
+
*
|
|
860
|
+
* `country` is what the server saw at the edge. `null` or empty means it did
|
|
861
|
+
* not know, and that is denied whatever the rule says.
|
|
862
|
+
*/
|
|
863
|
+
declare function resolveConsentDefault(rule: RegionalConsent, country: string | null | undefined, subdivision?: string | null): ConsentDefault;
|
|
864
|
+
|
|
865
|
+
export { ATTRIBUTION_PARAMS, BuildBaseTracking, EEA_COUNTRIES, EVENT_MAPPINGS, FUNNEL_EVENTS, SAFE_REGIONAL_CONSENT, TAG_PROVIDERS, TAG_PROVIDER_IDS, TAG_SCRIPT_ORIGINS, captureAttribution, expandRegions, getAttribution, hashIdentity, isCanonicalEvent, isTagProviderId, isValidProviderId, normalizeEmail, normalizePhone, resolveConsentDefault, useCheckoutCompleted, useTracking };
|
|
866
|
+
export type { Attribution, AttributionParam, BuildBaseTrackingProps, CanonicalEventName, ConsentDefault, ConsentSetOptions, ConsentState, EventOwnership, FunnelEventName, HashedIdentity, PublicTrackingConfig, PublicTrackingScript, RegionalConsent, TagConsentCategory, TagProviderId, TagProviderSpec, TrackOptions, TrackingConsentEntry, TrackingContextValue, TrackingEvent, TrackingEventsConfig, TrackingOptions, UserIdentity };
|
package/dist/tracking/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as e}from"react/jsx-runtime";import{useRef as t,useState as n,useCallback as r,useEffect as i,useMemo as o,useContext as a,createContext as s}from"react";const c="__buildbaseBeforeLeave",d=globalThis,l=d[c]??(d[c]=new Set);const u="bb_attr",p=["gclid","gbraid","wbraid","dclid","fbclid","msclkid","li_fat_id","twclid","ttclid","rdt_cid","epik","irclickid","utm_source","utm_medium","utm_campaign","utm_term","utm_content","utm_id"],g=/^[\w.~-]{1,200}$/;function f(){return"undefined"==typeof window?null:window}function m(e,t){if(!e||!e.includes("."))return"";if(/^\d{1,3}(\.\d{1,3}){3}$/.test(e))return"";const n=t??f()?.document;if(!n)return"";const r=e.split(".");for(let e=r.length-2;e>=0;e--){const t="."+r.slice(e).join("."),i=`__bb_probe_${Date.now()}`;n.cookie=`${i}=1; domain=${t}; path=/; SameSite=Lax`;const o=n.cookie.includes(`${i}=1`);if(n.cookie=`${i}=; domain=${t}; path=/; max-age=0; SameSite=Lax`,o)return t}return""}function h(e){const t=e.cookie.split("; ").find(e=>e.startsWith(`${u}=`));if(!t)return{};try{const e=JSON.parse(decodeURIComponent(t.slice(8)));return"object"==typeof e&&e?e:{}}catch{return{}}}const y=p.filter(e=>!e.startsWith("utm_")),w=e=>y.some(t=>!!e[t]);function v(){const e=f();if(!e)return{};const t=e.document,n=h(t),r=function(e){const t=new URLSearchParams(e),n={};for(const e of p){const r=t.get(e);r&&(r.length>200||g.test(r)&&(n[e]=r))}return n}(e.location.search),i=Object.keys(r).length>0&&(w(r)||!w(n)),o=i?r:n;return 0===Object.keys(o).length?{}:(i&&!function(e,t){const n=new Set([...Object.keys(e),...Object.keys(t)]);for(const r of n)if(e[r]!==t[r])return!1;return!0}(r,n)&&function(e,t,n){const r=encodeURIComponent(JSON.stringify(t));e.cookie=`${u}=${r}; path=/; max-age=7776000; SameSite=Lax`+(n?`; domain=${n}`:"")}(t,o,m(e.location.hostname,t)),o)}function _(){const e=f();return e?h(e.document):{}}function k(e){try{const t=new URLSearchParams(e);return t.has("code")&&t.has("state")}catch{return!1}}const b="bb_pending_checkout";function I(){try{return"undefined"==typeof window?null:window.sessionStorage}catch{return null}}const C="bb_co";function $(){try{return"undefined"==typeof window?null:window.document??null}catch{return null}}function j(){const e=$();if(e)try{const t=m(window.location?.hostname??"",e);e.cookie=`${C}=; path=/; max-age=0; SameSite=Lax`+(t?`; domain=${t}`:"")}catch{}}function x(e,t){if(!e)return null;try{const n=JSON.parse(e);return n&&"string"==typeof n.eventId&&n.eventId?"number"!=typeof n.startedAt||t-n.startedAt>216e5?null:n:null}catch{return null}}function q(e=Date.now()){const t=I();if(!t)return null;let n=null;try{n=t.getItem(b),t.removeItem(b)}catch{return null}const r=x(n,e);return r&&j(),r}function A(e){try{return x(I()?.getItem(b)??null,e)}catch{return null}}function P(e,t=Date.now()){let n=null;try{n=new URLSearchParams(e).get("session_id")}catch{return null}if(!n)return null;const r=A(t);if(r?.sessionId===n)return q(t);const i=function(e){const t=$();if(!t||"string"!=typeof t.cookie)return null;const n=t.cookie.split("; ").find(e=>e.startsWith(`${C}=`));return n?x(decodeURIComponent(n.slice(6)),e):null}(t);return i?.sessionId!==n?null:(j(),i)}function S(e,t=Date.now()){return function(e){let t=null;try{t=new URLSearchParams(e).get("bb")}catch{return!1}if(!t)return!1;const n={};for(const e of t.split(",")){const t=e.indexOf(":");if(-1!==t)try{n[decodeURIComponent(e.slice(0,t))]=decodeURIComponent(e.slice(t+1))}catch{}}return"checkout"===n.action&&"cancel"===n.status}(e)&&A(t)?q(t):null}const O=new Set(["bif","clp","djf","gnf","jpy","kmf","krw","mga","pyg","rwf","ugx","vnd","vuv","xaf","xof","xpf"]),E=new Set(["bhd","jod","kwd","omr","tnd"]);function U(e,t){if("number"!=typeof e||!Number.isFinite(e))return;const n=(t??"").toLowerCase();return O.has(n)?e:e/(E.has(n)?1e3:100)}function L(){return"undefined"==typeof window?null:window}function T(e){const t=L();if(!t)return;t.gtag?.("consent","update",{ad_storage:e.marketing?"granted":"denied",ad_user_data:e.marketing?"granted":"denied",ad_personalization:e.marketing?"granted":"denied",analytics_storage:e.analytics?"granted":"denied"});const n=t.fbq;n?.("consent",e.marketing?"grant":"revoke")}const M={gtm:{title:"Google Tag Manager",vendor:"Google LLC",privacyUrl:"https://policies.google.com/privacy",idLabel:"Container ID",idPattern:"^GTM-[A-Z0-9]{4,10}$",idExample:"GTM-ABC1234",scriptOrigin:"https://www.googletagmanager.com",defaultConsentCategory:"analytics",supportsConsentMode:!0,needsConversionIds:!1},ga4:{title:"Google Analytics 4",vendor:"Google LLC",privacyUrl:"https://policies.google.com/privacy",idLabel:"Measurement ID",idPattern:"^G-[A-Z0-9]{8,12}$",idExample:"G-ABCD123456",scriptOrigin:"https://www.googletagmanager.com",defaultConsentCategory:"analytics",supportsConsentMode:!0,needsConversionIds:!1},google_ads:{title:"Google Ads",vendor:"Google LLC",privacyUrl:"https://policies.google.com/privacy",idLabel:"Conversion ID",idPattern:"^AW-[0-9]{9,12}$",idExample:"AW-123456789",scriptOrigin:"https://www.googletagmanager.com",defaultConsentCategory:"marketing",supportsConsentMode:!0,needsConversionIds:!0},meta_pixel:{title:"Meta Pixel",vendor:"Meta Platforms Ireland Limited",privacyUrl:"https://www.facebook.com/privacy/policy",idLabel:"Pixel ID",idPattern:"^[0-9]{15,16}$",idExample:"123456789012345",scriptOrigin:"https://connect.facebook.net",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!1,multiInstance:!0},x_pixel:{title:"X (Twitter) Pixel",vendor:"X Corp.",privacyUrl:"https://x.com/en/privacy",idLabel:"Pixel ID",idPattern:"^o[a-z0-9]{4,6}$",idExample:"o1a2b3",scriptOrigin:"https://static.ads-twitter.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!0,multiInstance:!0},linkedin:{title:"LinkedIn Insight Tag",vendor:"LinkedIn Ireland Unlimited Company",privacyUrl:"https://www.linkedin.com/legal/privacy-policy",idLabel:"Partner ID",idPattern:"^[0-9]{6,9}$",idExample:"1234567",scriptOrigin:"https://snap.licdn.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!0,multiInstance:!0},tiktok:{title:"TikTok Pixel",vendor:"TikTok Information Technologies UK Limited",privacyUrl:"https://www.tiktok.com/legal/privacy-policy",idLabel:"Pixel ID",idPattern:"^[A-Z0-9]{20}$",idExample:"C4A1B2C3D4E5F6G7H8I9",scriptOrigin:"https://analytics.tiktok.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!1,multiInstance:!0},reddit:{title:"Reddit Pixel",vendor:"Reddit, Inc.",privacyUrl:"https://www.reddit.com/policies/privacy-policy",idLabel:"Advertiser ID",idPattern:"^t2_[a-z0-9]{4,12}$",idExample:"t2_abc123",scriptOrigin:"https://www.redditstatic.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!1,multiInstance:!0},bing_uet:{title:"Microsoft Advertising (UET)",vendor:"Microsoft Corporation",privacyUrl:"https://privacy.microsoft.com/en-us/privacystatement",idLabel:"Tag ID",idPattern:"^[0-9]{7,9}$",idExample:"12345678",scriptOrigin:"https://bat.bing.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!1,multiInstance:!0},clarity:{title:"Microsoft Clarity",vendor:"Microsoft Corporation",privacyUrl:"https://privacy.microsoft.com/en-us/privacystatement",idLabel:"Project ID",idPattern:"^[a-z0-9]{10}$",idExample:"ab12cd34ef",scriptOrigin:"https://www.clarity.ms",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1},hotjar:{title:"Hotjar",vendor:"Hotjar Limited",privacyUrl:"https://www.hotjar.com/legal/policies/privacy/",idLabel:"Site ID",idPattern:"^[0-9]{6,9}$",idExample:"1234567",scriptOrigin:"https://static.hotjar.com",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1},posthog:{title:"PostHog",vendor:"PostHog, Inc.",privacyUrl:"https://posthog.com/privacy",idLabel:"Project API key",idPattern:"^phc_[A-Za-z0-9]{32,48}$",idExample:"phc_abcdefghijklmnopqrstuvwxyz012345",scriptOrigin:"https://us-assets.i.posthog.com",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1,hosts:["us.i.posthog.com","eu.i.posthog.com"]},plausible:{title:"Plausible Analytics",vendor:"Plausible Insights OÜ",privacyUrl:"https://plausible.io/privacy",idLabel:"Domain",idPattern:"^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$",idExample:"example.com",scriptOrigin:"https://plausible.io",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1},ahrefs:{title:"Ahrefs Analytics",vendor:"Ahrefs Pte. Ltd.",privacyUrl:"https://ahrefs.com/privacy",idLabel:"Analytics key",idPattern:"^[A-Za-z0-9+/=]{20,64}$",idExample:"AbCdEfGhIjKlMnOpQrStUv==",scriptOrigin:"https://analytics.ahrefs.com",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1}},D=Object.keys(M);function N(e){return"string"==typeof e&&Object.prototype.hasOwnProperty.call(M,e)}function B(e,t){return!!N(e)&&("string"==typeof t&&0!==t.length&&new RegExp(M[e].idPattern).test(t))}const R=/^[a-z][a-z0-9-]{0,40}$/,z=/^[\w.:/@+=-]{1,200}$/;function G(e){return function(e){if("string"!=typeof e)return!1;if(0===e.length||e.length>300)return!1;let t;try{t=new URL(e)}catch{return!1}return!("https:"!==t.protocol||!t.hostname||!t.hostname.includes(".")||e.includes("?")||e.includes("#")||t.username||t.password)}(e.src)&&function(e){if(null==e)return!0;if("object"!=typeof e||Array.isArray(e))return!1;const t=Object.entries(e);return!(t.length>12)&&t.every(([e,t])=>R.test(e)&&"string"==typeof t&&z.test(t))}(e.dataAttributes)}const V=Array.from(new Set(D.map(e=>M[e].scriptOrigin))).sort(),F={sign_up:{ga4:"sign_up",meta:"CompleteRegistration",tiktok:"CompleteRegistration",reddit:"SignUp"},login:{ga4:"login",meta:null,tiktok:null,reddit:null},trial_started:{ga4:"begin_checkout",meta:"StartTrial",tiktok:"StartTrial",reddit:"Lead"},checkout_started:{ga4:"begin_checkout",meta:"InitiateCheckout",tiktok:"InitiateCheckout",reddit:"AddToCart"},purchase:{ga4:"purchase",meta:"Purchase",tiktok:"CompletePayment",reddit:"Purchase"},subscription_created:{ga4:"purchase",meta:"Subscribe",tiktok:"Subscribe",reddit:"Purchase"},subscription_upgraded:{ga4:"subscription_upgraded",meta:null,tiktok:null,reddit:null},lead:{ga4:"generate_lead",meta:"Lead",tiktok:"SubmitForm",reddit:"Lead"},workspace_created:{ga4:"workspace_created",meta:null,tiktok:null,reddit:null}},H=Object.keys(F);function W(e){return H.includes(e)}function Z(){return"undefined"==typeof window?null:window}const J={gtm:"dataLayer",ga4:"gtag",google_ads:"gtag",meta_pixel:"fbq",x_pixel:"twq",linkedin:"lintrk",tiktok:"ttq",reddit:"rdt",bing_uet:"uetq",clarity:"clarity",hotjar:"hj",posthog:"posthog",plausible:"plausible",ahrefs:"__ahrefs_loaded"};function K(){return"undefined"==typeof window?null:window}function Q(e,t={}){const n=K();if(!n)return null;const r=n.document.createElement("script");r.async=!0,r.src=e;for(const[e,n]of Object.entries(t))r.setAttribute(e,n);return n.document.head.appendChild(r),r}function X(e){const t=K();if(!t)return;const n=t.document.createElement("script");n.text=e,t.document.head.appendChild(n)}function Y(e){const t=K();t&&(Array.isArray(t[e])||(t[e]=[]),"function"!=typeof t.gtag&&(t.gtag=function(){t[e].push(arguments)}))}const ee=new Set;function te(e){for(const t of ee)if(t.slice(0,t.indexOf(":"))===e)return!0;return!1}function ne(e,t){const n=K();if(!n)return!1;if("gtm"===e||"ga4"===e||"google_ads"===e){const e=n.google_tag_manager;return!(!e||"object"!=typeof e)&&Object.prototype.hasOwnProperty.call(e,t)}const r=J[e];if(!r)return!1;if(void 0===n[r])return!1;if(ee.has(`${e}:${t}`))return!0;return!M[e].multiInstance||!te(e)}const re={meta_pixel:e=>`fbq('init','${e}');fbq('track','PageView');`,x_pixel:e=>`twq('config','${e}');`,tiktok:e=>`ttq.load('${e}');ttq.page();`,reddit:e=>`rdt('init','${e}');rdt('track','PageVisit');`,bing_uet:e=>`window.uetq=window.uetq||[];window.uetq.push({ti:'${e}',enableAutoSpaTracking:false});`,linkedin:e=>`window._linkedin_data_partner_ids=window._linkedin_data_partner_ids||[];window._linkedin_data_partner_ids.push('${e}');`};function ie(e,t,n){const r=function(e,t,n){const r=K();if(!r)return!1;if("external"===e.provider){if(!e.src)return!1;const t={};for(const[n,r]of Object.entries(e.dataAttributes??{}))t[`data-${n}`]=r;return Q(e.src,t),!0}const i=e.provider,o=M[i];if(!o)return!1;const a=e.providerId;if(!a)return!1;const s=re[i];if(s&&te(i))return X(s(a)),!0;switch(i){case"gtm":{Y(t),r[t].push({"gtm.start":Date.now(),event:"gtm.js"});const e="dataLayer"===t?"":`&l=${t}`;return Q(`${o.scriptOrigin}/gtm.js?id=${a}${e}`),!0}case"ga4":case"google_ads":{Y(t),Q(`${o.scriptOrigin}/gtag/js?id=${a}`);const e=r.gtag;e("js",new Date);const s="ga4"===i&&n?.gaClientId?{client_id:n.gaClientId}:void 0;return s?e("config",a,s):e("config",a),!0}case"meta_pixel":return X(`!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,document,'script','${o.scriptOrigin}/en_US/fbevents.js');fbq('init','${a}');fbq('track','PageView');`),!0;case"x_pixel":return X(`!function(e,t,n,s,u,a){e.twq||(s=e.twq=function(){s.exe?s.exe.apply(s,arguments):s.queue.push(arguments)},s.version='1.1',s.queue=[],u=t.createElement(n),u.async=!0,u.src='${o.scriptOrigin}/uwt.js',a=t.getElementsByTagName(n)[0],a.parentNode.insertBefore(u,a))}(window,document,'script');twq('config','${a}');`),!0;case"linkedin":return X(`window._linkedin_partner_id='${a}';window._linkedin_data_partner_ids=window._linkedin_data_partner_ids||[];window._linkedin_data_partner_ids.push('${a}');window.lintrk=window.lintrk||function(a,b){(window.lintrk.q=window.lintrk.q||[]).push([a,b])};window.lintrk.q=window.lintrk.q||[];`),Q(`${o.scriptOrigin}/li.lms-analytics/insight.min.js`),!0;case"tiktok":return X(`!function(w,d,t){w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];ttq.methods=['page','track','identify','instances','debug','on','off','once','ready','alias','group','enableCookie','disableCookie'];ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);ttq.load=function(e,n){var r='${o.scriptOrigin}/i18n/pixel/events.js';ttq._i=ttq._i||{};ttq._i[e]=[];ttq._i[e]._u=r;ttq._t=ttq._t||{};ttq._t[e]=+new Date;ttq._o=ttq._o||{};ttq._o[e]=n||{};var o=d.createElement('script');o.type='text/javascript';o.async=!0;o.src=r+'?sdkid='+e+'&lib='+t;var a=d.getElementsByTagName('script')[0];a.parentNode.insertBefore(o,a)};ttq.load('${a}');ttq.page()}(window,document,'ttq');`),!0;case"reddit":return X(`!function(w,d){if(!w.rdt){var p=w.rdt=function(){p.sendEvent?p.sendEvent.apply(p,arguments):p.callQueue.push(arguments)};p.callQueue=[];var t=d.createElement('script');t.src='${o.scriptOrigin}/ads/pixel.js';t.async=!0;var s=d.getElementsByTagName('script')[0];s.parentNode.insertBefore(t,s)}}(window,document);rdt('init','${a}');rdt('track','PageVisit');`),!0;case"bing_uet":return X(`(function(w,d,t,r,u){w[u]=w[u]||[];w[u].push({ti:'${a}',enableAutoSpaTracking:false});var o=d.createElement(t);o.src='${o.scriptOrigin}/bat.js';o.async=1;var i=d.getElementsByTagName(t)[0];i.parentNode.insertBefore(o,i)})(window,document,'script',0,'uetq');`),!0;case"clarity":return X(`(function(c,l,a,r,i,t,y){c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};t=l.createElement(r);t.async=1;t.src='${o.scriptOrigin}/tag/'+i;y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y)})(window,document,'clarity','script','${a}');`),!0;case"hotjar":return X(`(function(h,o,t,j,a,r){h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};h._hjSettings={hjid:${a},hjsv:6};a=o.getElementsByTagName('head')[0];r=o.createElement('script');r.async=1;r.src='${o.scriptOrigin}/hotjar-'+h._hjSettings.hjid+'.js?sv='+h._hjSettings.hjsv;a.appendChild(r)})(window,document);`),!0;case"posthog":{const t=o.hosts,n=t?.includes(e.host??"")?e.host:t?.[0]??"us.i.posthog.com";return X(`!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split('.');2==o.length&&(t=t[o[0]],e=o[1]);t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement('script')).type='text/javascript',p.async=!0,p.src='${o.scriptOrigin}/static/array.js',(r=t.getElementsByTagName('script')[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a='posthog',u.people=u.people||[],u.toString=function(t){var e='posthog';return'posthog'!==a&&(e+='.'+a),t||(e+=' (stub)'),e},u.people.toString=function(){return u.toString(1)+'.people (stub)'},o='init capture register register_once identify alias people.set people.set_once set_config get_distinct_id getFeatureFlag isFeatureEnabled onFeatureFlags reloadFeatureFlags group reset'.split(' '),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);posthog.init('${a}',{api_host:'https://${n}'});`),!0}case"plausible":return X("window.plausible=window.plausible||function(){(window.plausible.q=window.plausible.q||[]).push(arguments)};"),Q(`${o.scriptOrigin}/js/script.js`,{"data-domain":a,defer:"true"}),!0;case"ahrefs":return Q(`${o.scriptOrigin}/analytics.js`,{"data-key":a}),r.__ahrefs_loaded=!0,!0;default:return!1}}(e,t,n);return r&&"external"!==e.provider&&e.providerId&&ee.add(`${e.provider}:${e.providerId}`),r}const oe=Symbol.for("@buildbase/sdk.tracking.context"),ae=globalThis,se=ae[oe]??(ae[oe]=s(null)),ce={consent:{manifest:[],state:null,set:()=>{}},track:()=>{},setUser:()=>{},setProperties:()=>{},getProperties:()=>({}),completeCheckout:async()=>{},installed:{},ready:!0,attribution:{}};function de(){return a(se)??ce}const le=({serverUrl:a,orgId:s,clientId:c,enabled:d=!0,consent:u="auto",autoPageview:p=!0,events:g,onEvent:f,properties:m,enrich:h,identity:y,debug:w=!1,children:_})=>{const b=t(y);b.current=y;const[I,C]=n(null),[$,j]=n(!1),[x,q]=n(!1),A="granted"===u?{analytics:!0,marketing:!0}:"denied"===u?{analytics:!1,marketing:!1}:null,[O,E]=n(A),D=t(null),R=t(f);R.current=f;const z=t(h);z.current=h;const V=t({});V.current=m??{};const H=t({}),J=r(()=>({...V.current,...H.current}),[]),K=r(e=>{const t={...H.current,...e};for(const[e,n]of Object.entries(t))void 0===n&&delete t[e];H.current=t},[]),[Q,X]=n({}),ee=t({}),[te,re]=n(0),oe=I?.dataLayerName??"dataLayer",ae=r((...e)=>{w&&console.info("[buildbase:tracking]",...e)},[w]);i(()=>{return e=()=>{0!==Object.keys(ee.current).length&&window.dispatchEvent("function"==typeof PageTransitionEvent?new PageTransitionEvent("pagehide",{persisted:!1}):new Event("pagehide"))},l.add(e),()=>{l.delete(e)};var e},[]),i(()=>{if(!(d&&a&&s&&c))return void j(!0);let e=!1;const t=`${a.replace(/\/$/,"")}/api/v1/public/${s}/tracking?clientId=${encodeURIComponent(c)}`;return fetch(t).then(e=>e.ok?e.json():null).then(t=>{if(e||!t)return;const n=t.data??t;n&&Array.isArray(n.scripts)&&C(n)}).catch(()=>{ae("config fetch failed; nothing installed")}).finally(()=>{e||j(!0)}),()=>{e=!0}},[d,a,s,c,ae]),i(()=>{d&&X(v())},[d]),i(()=>{d&&I?.enabled&&(Y(oe),function(e,t){const n=L();if(!n)return;Array.isArray(n[e])||(n[e]=[]),"function"!=typeof n.gtag&&(n.gtag=function(){n[e].push(arguments)});const r="granted"===t?"granted":"denied";n.gtag("consent","default",{ad_storage:r,ad_user_data:r,ad_personalization:r,analytics_storage:r,wait_for_update:500})}(oe,u),D.current&&T(D.current))},[d,I?.enabled,oe,u]);const ce=o(()=>I?.enabled?I.scripts.filter(e=>{const t=N(e.provider)&&M[e.provider].supportsConsentMode;return function(e,t,n,r){return"denied"!==r&&("granted"===r||(n?"marketing"===e?n.marketing:n.analytics:t&&"analytics"===e))}(e.consentCategory,t,O,u)}):[],[I,O,u]),[de,le]=n(()=>"undefined"==typeof window||!k(window.location.search));i(()=>{if(de)return;const e=setInterval(()=>{k(window.location.search)||le(!0)},50),t=setTimeout(()=>le(!0),5e3);return()=>{clearInterval(e),clearTimeout(t)}},[de]),i(()=>{if(!de)return;if(!d||!I?.enabled)return void($&&q(!0));let e=0;for(const t of ce)if(!ee.current[t.key]){if("external"===t.provider){if(!G({src:t.src,dataAttributes:t.dataAttributes})){ae("rejected external script",t.key);continue}}else{if(!N(t.provider)){ae("rejected unknown provider",t.provider);continue}if(!B(t.provider,t.providerId)){ae("rejected id for",t.provider);continue}if(ne(t.provider,t.providerId??"")){ae(`${t.provider} ${t.providerId} is already on the page; skipping. Configure each tag in exactly one place.`);continue}}ie(t,oe,b.current)&&(ee.current[t.key]=t.providerId??t.src??"",e+=1,ae("installed",t.key))}e&&re(e=>e+1);const t=window;t.__buildbase=t.__buildbase??{},t.__buildbase.tracking={installed:{...ee.current},dataLayerName:oe,clientId:c};const n=Object.keys(ee.current).length>0,r=null!==O||0===I.scripts.length;(n||r)&&q(!0)},[d,I,ce,$,O,oe,ae,de,c]),i(()=>{if(!d||!p||!I?.enabled)return;if("undefined"==typeof window)return;if(!de)return;let e=null;const t=()=>{e&&clearTimeout(e),e=setTimeout(()=>function(e,t){const n=Z();if(!n)return;const r=n[t];Array.isArray(r)&&r.push({event:"page_view",page_path:n.location.pathname,page_location:n.location.href,page_title:n.document.title});for(const t of e)switch(t.provider){case"ga4":n.gtag?.("event","page_view",{send_to:t.providerId,page_path:n.location.pathname,page_location:n.location.href,page_title:n.document.title});break;case"meta_pixel":n.fbq?.("track","PageView");break;case"tiktok":{const e=n.ttq;e?.page?.();break}case"reddit":n.rdt?.("track","PageVisit")}}(ce,oe),50)},n=window.history,r=n.pushState,i=n.replaceState;return n.pushState=function(...e){const n=r.apply(this,e);return t(),n},n.replaceState=function(...e){const n=i.apply(this,e);return t(),n},window.addEventListener("popstate",t),()=>{n.pushState=r,n.replaceState=i,window.removeEventListener("popstate",t),e&&clearTimeout(e)}},[d,p,I?.enabled,ce,oe,de]),i(()=>{if(!d)return;const e=function(e,t){const n=e?.mode??"auto",r=e?.overrides??{};if(("manual"===n||Object.values(r).some(e=>"manual"===e))&&!t)return'[buildbase:tracking] events are set to "manual" but no onEvent handler was provided, so those events would never fire anywhere. Pass onEvent, or use mode "auto".';for(const e of Object.keys(r))if(!W(e))return`[buildbase:tracking] unknown event "${e}" in events.overrides. Overrides only apply to the events the SDK fires itself.`;return null}(g,!!f);if(e)throw new Error(e)},[d,g,f]);const ue=r((e,t={},n)=>{if(!d)return;const r=n?.eventId||function(){const e=globalThis.crypto;return e?.randomUUID?e.randomUUID():`${Date.now().toString(16)}-${Math.random().toString(16).slice(2,10)}`}(),i=g?.mode??"auto",o=(W(e)?g?.overrides?.[e]:void 0)??i,a={...V.current,...H.current,...Q,...t},s=z.current?.({name:e,params:a})??{},c={...a,...s},l=R.current?.({name:e,params:c,eventId:r,handledBy:o});"manual"!==o&&!0!==l?(!function(e,t,n,r,i){const o=Z();if(!o)return;const a=o[i];Array.isArray(a)&&a.push({event:e,...t,event_id:n});const s=W(e)?F[e]:{ga4:e,meta:null,tiktok:null,reddit:null};for(const i of r){const r=i.provider,a=M[r];if(a){if(a.needsConversionIds){const a=i.conversionIds?.[e];if(!a)continue;"google_ads"===r?o.gtag?.("event","conversion",{send_to:`${i.providerId}/${a}`,transaction_id:n,...t}):"x_pixel"===r?o.twq?.("event",a,{...t,conversion_id:n}):"linkedin"===r&&o.lintrk?.("track",{conversion_id:a});continue}switch(r){case"ga4":s.ga4&&o.gtag?.("event",s.ga4,{...t,send_to:i.providerId,event_id:n});break;case"meta_pixel":s.meta&&o.fbq?.("track",s.meta,t,{eventID:n});break;case"tiktok":if(s.tiktok){const e=o.ttq;e?.track?.(s.tiktok,{...t,event_id:n})}break;case"reddit":s.reddit&&o.rdt?.("track",s.reddit,{...t,conversionId:n});break;case"bing_uet":{const r=o.uetq;r?.push?.("event",s.ga4??e,{...t,event_id:n});break}case"clarity":o.clarity?.("event",e);break;case"hotjar":{const t=o.hj;t?.("event",e);break}case"posthog":{const r=o.posthog;r?.capture?.(e,{...t,event_id:n});break}case"plausible":o.plausible?.(e,{props:t})}}}}(e,c,r,ce,oe),ae("event fired:",e,r)):ae("event handled by app:",e)},[d,g,ce,oe,Q,ae]),pe=r(async(e,t={})=>{const n=function(e){return{name:"trial_started"===e.kind?"trial_started":"purchase",params:{...e.workspaceId?{workspace_id:e.workspaceId}:{},...e.planVersionId?{plan_version_id:e.planVersionId}:{},...e.creditPackageId?{credit_package_id:e.creditPackageId}:{},...e.billingInterval?{billing_interval:e.billingInterval}:{},...e.currency?{currency:e.currency.toUpperCase()}:{},..."number"==typeof e.value?{value:e.value}:{},...e.sessionId?{transaction_id:e.sessionId}:{}}}}(e);let r=n.params;if(e.sessionId&&a&&s){const t=await async function(e,t){try{const n=e.serverUrl.replace(/\/$/,""),r=await fetch(`${n}/api/v1/public/${encodeURIComponent(e.orgId)}/checkout/${encodeURIComponent(t)}`,{credentials:"omit",..."undefined"!=typeof AbortSignal&&AbortSignal.timeout?{signal:AbortSignal.timeout(2e3)}:{}});if(!r.ok)return null;const i=await r.json(),o=i?.data??i;return"number"!=typeof o?.amount?null:{value:U(o.amount,o.currency),currency:"string"==typeof o.currency?o.currency:void 0,...Array.isArray(o.items)&&o.items.length?{items:o.items}:{}}}catch{return null}}({serverUrl:a,orgId:s},e.sessionId);t&&"number"==typeof t.value&&(r={...r,value:t.value,...t.currency?{currency:t.currency.toUpperCase()}:{},...t.items?.length?{items:t.items}:{}})}if(ue(n.name,{...r,...t},{eventId:e.eventId}),"purchase"===n.name&&e.sessionId&&a&&s){const t=(I?.scripts??[]).find(e=>"ga4"===e.provider&&e.providerId);t&&ne("ga4",t.providerId??"")&&function(e,t,n){try{const r=e.serverUrl.replace(/\/$/,"");fetch(`${r}/api/v1/public/${encodeURIComponent(e.orgId)}/checkout/${encodeURIComponent(t)}/reported`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:n}),keepalive:!0,credentials:"omit"}).catch(()=>{})}catch{}}({serverUrl:a,orgId:s},e.sessionId,"ga4")}},[a,s,ue,I]),[ge]=n(()=>"undefined"==typeof window?"":window.location.search);i(()=>{if(!d||!x)return;if("undefined"==typeof window)return;const e=P(window.location.search);if(e)return void pe(e);const t=S(ge);t&&ue("checkout_abandoned",{...t.workspaceId?{workspace_id:t.workspaceId}:{},...t.planVersionId?{plan_version_id:t.planVersionId}:{},...t.creditPackageId?{credit_package_id:t.creditPackageId}:{},...t.billingInterval?{billing_interval:t.billingInterval}:{},...t.currency?{currency:t.currency.toUpperCase()}:{},..."number"==typeof t.value?{value:t.value}:{},seconds_at_checkout:Math.max(0,Math.round((Date.now()-t.startedAt)/1e3))})},[d,x,pe,ge,ue]);const fe=r(e=>{D.current=e,E(e),T(e)},[]),me=r((e,t)=>function(e,t,n){const r=Z();if(!r)return;const i=!!n&&Object.keys(n).length>0;for(const o of t)switch(o.provider){case"ga4":case"google_ads":r.gtag?.("set",{user_id:e}),i&&r.gtag?.("set",{user_properties:n});break;case"meta_pixel":o.providerId&&r.fbq?.("init",o.providerId,{external_id:e});break;case"posthog":r.posthog?.identify?.(e,i?n:void 0);break;case"clarity":if(r.clarity?.("identify",e),i)for(const[e,t]of Object.entries(n))r.clarity?.("set",e,String(t));break;case"hotjar":r.hj?.("identify",e,{});break;case"tiktok":{const t=r.ttq;t?.identify?.({external_id:e});break}}}(e,ce,t),[ce]),he=o(()=>({consent:{manifest:I?.consent?.manifest??[],state:O,set:fe},track:ue,setUser:me,setProperties:K,getProperties:J,completeCheckout:pe,installed:{...ee.current},ready:x,attribution:Q}),[I,O,fe,ue,me,K,J,pe,x,te,Q]);return e(se.Provider,{value:he,children:_})};function ue(e={}){const{completeCheckout:n,ready:r}=de(),o=t(e);o.current=e;const a=t(!1);i(()=>{if(!r)return;if(a.current)return;const e=P(window.location.search)??q();e&&(a.current=!0,n(e,o.current))},[r,n])}le.displayName="BuildBaseTracking";const pe={sign_in_started:"The sign-in / sign-up button was pressed.",pricing_viewed:"A <PricingPage> finished loading its plans.",pricing_plan_selected:"A plan was chosen on a <PricingPage>.",workspace_switcher_opened:"The workspace switcher was opened.",workspace_settings_opened:"The workspace settings modal was opened.",workspace_settings_section_viewed:"A different section of the settings modal was opened.",plan_picker_opened:"The plan picker was shown.",billing_interval_changed:"Monthly / quarterly / yearly was switched in the plan picker.",plan_selected:"A plan was chosen in the plan picker.",plan_picker_dismissed:"The plan picker was closed without choosing a plan.",checkout_abandoned:"The customer came back from Stripe without paying.",billing_portal_opened:"Stripe’s billing portal was opened.",subscription_cancel_started:"The cancel-subscription confirmation was opened.",subscription_cancelled:"A subscription was cancelled.",subscription_resumed:"A cancelled subscription was resumed.",feature_gate_shown:'A feature gate rendered its "not on your plan" side.',quota_limit_reached:"A quota gate rendered because a quota is used up.",quota_threshold_reached:"A usage-threshold gate rendered.",plan_gate_shown:'A plan gate rendered its "needs another plan" side.',subscription_notice_shown:"A billing notice (trial ending, payment failed…) was shown.",sdk_error:"An SDK operation failed (component, action and code only)."};export{p as ATTRIBUTION_PARAMS,le as BuildBaseTracking,F as EVENT_MAPPINGS,pe as FUNNEL_EVENTS,M as TAG_PROVIDERS,D as TAG_PROVIDER_IDS,V as TAG_SCRIPT_ORIGINS,v as captureAttribution,_ as getAttribution,W as isCanonicalEvent,N as isTagProviderId,B as isValidProviderId,ue as useCheckoutCompleted,de as useTracking};
|
|
2
|
+
import{jsx as e}from"react/jsx-runtime";import{useRef as t,useState as n,useMemo as r,useCallback as i,useEffect as o,useContext as a,createContext as s}from"react";const c="__buildbaseBeforeLeave",d=globalThis,l=d[c]??(d[c]=new Set);const u="bb_attr",p=["gclid","gbraid","wbraid","dclid","fbclid","msclkid","li_fat_id","twclid","ttclid","rdt_cid","epik","irclickid","utm_source","utm_medium","utm_campaign","utm_term","utm_content","utm_id"],g=/^[\w.~-]{1,200}$/;function f(){return"undefined"==typeof window?null:window}function m(e,t){if(!e||!e.includes("."))return"";if(/^\d{1,3}(\.\d{1,3}){3}$/.test(e))return"";const n=t??f()?.document;if(!n)return"";const r=e.split(".");for(let e=r.length-2;e>=0;e--){const t="."+r.slice(e).join("."),i=`__bb_probe_${Date.now()}`;n.cookie=`${i}=1; domain=${t}; path=/; SameSite=Lax`;const o=n.cookie.includes(`${i}=1`);if(n.cookie=`${i}=; domain=${t}; path=/; max-age=0; SameSite=Lax`,o)return t}return""}const h="$t",y="$l";function w(e){return function(e){const t=e.cookie.split("; ").find(e=>e.startsWith(`${u}=`));if(!t)return{params:{}};try{const e=JSON.parse(decodeURIComponent(t.slice(8)));if("object"!=typeof e||!e)return{params:{}};const{[h]:n,[y]:r,...i}=e;return{params:i,..."number"==typeof n&&n>0?{capturedAt:n}:{},..."string"==typeof r&&r?{landingUrl:r}:{}}}catch{return{params:{}}}}(e).params}function v(e){try{const{origin:t,pathname:n}=e.location;return t&&"null"!==t?`${t}${n}`.slice(0,300):void 0}catch{return}}const _=p.filter(e=>!e.startsWith("utm_")),b=e=>_.some(t=>!!e[t]);function k(){const e=f();if(!e)return{};const t=e.document,n=w(t),r=function(e){const t=new URLSearchParams(e),n={};for(const e of p){const r=t.get(e);r&&(r.length>200||g.test(r)&&(n[e]=r))}return n}(e.location.search),i=Object.keys(r).length>0&&(b(r)||!b(n)),o=i?r:n;return 0===Object.keys(o).length?{}:(i&&!function(e,t){const n=new Set([...Object.keys(e),...Object.keys(t)]);for(const r of n)if(e[r]!==t[r])return!1;return!0}(r,n)&&function(e,t,n,r){const i=encodeURIComponent(JSON.stringify({...t,[h]:r.capturedAt,...r.landingUrl?{[y]:r.landingUrl}:{}}));e.cookie=`${u}=${i}; path=/; max-age=7776000; SameSite=Lax`+(n?`; domain=${n}`:"")}(t,o,m(e.location.hostname,t),{capturedAt:Date.now(),landingUrl:v(e)}),o)}function I(){const e=f();return e?w(e.document):{}}function C(e){try{const t=new URLSearchParams(e);return t.has("code")&&t.has("state")}catch{return!1}}const $="bb_pending_checkout";function S(){try{return"undefined"==typeof window?null:window.sessionStorage}catch{return null}}const A="bb_co";function j(){try{return"undefined"==typeof window?null:window.document??null}catch{return null}}function x(){const e=j();if(e)try{const t=m(window.location?.hostname??"",e);e.cookie=`${A}=; path=/; max-age=0; SameSite=Lax`+(t?`; domain=${t}`:"")}catch{}}function q(e,t){if(!e)return null;try{const n=JSON.parse(e);return n&&"string"==typeof n.eventId&&n.eventId?"number"!=typeof n.startedAt||t-n.startedAt>216e5?null:n:null}catch{return null}}function U(e=Date.now()){const t=S();if(!t)return null;let n=null;try{n=t.getItem($),t.removeItem($)}catch{return null}const r=q(n,e);return r&&x(),r}function O(e){try{return q(S()?.getItem($)??null,e)}catch{return null}}function P(e,t=Date.now()){let n=null;try{n=new URLSearchParams(e).get("session_id")}catch{return null}if(!n)return null;const r=O(t);if(r?.sessionId===n)return U(t);const i=function(e){const t=j();if(!t||"string"!=typeof t.cookie)return null;const n=t.cookie.split("; ").find(e=>e.startsWith(`${A}=`));return n?q(decodeURIComponent(n.slice(6)),e):null}(t);return i?.sessionId!==n?null:(x(),i)}function E(e,t=Date.now()){return function(e){let t=null;try{t=new URLSearchParams(e).get("bb")}catch{return!1}if(!t)return!1;const n={};for(const e of t.split(",")){const t=e.indexOf(":");if(-1!==t)try{n[decodeURIComponent(e.slice(0,t))]=decodeURIComponent(e.slice(t+1))}catch{}}return"checkout"===n.action&&"cancel"===n.status}(e)&&O(t)?U(t):null}const T=new Set(["bif","clp","djf","gnf","jpy","kmf","krw","mga","pyg","rwf","ugx","vnd","vuv","xaf","xof","xpf"]),L=new Set(["bhd","jod","kwd","omr","tnd"]);function D(e,t){if("number"!=typeof e||!Number.isFinite(e))return;const n=(t??"").toLowerCase();return T.has(n)?e:e/(L.has(n)?1e3:100)}const M=["AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","IS","LI","NO"],N={default:"granted",regions:{denied:["EEA","GB","CH"]}},R=/^[A-Z]{2}(-[A-Z0-9]{1,3})?$/;function B(e){const t=new Set;for(const n of e??[]){const e=String(n).trim().toUpperCase();if("EEA"===e)for(const e of M)t.add(e);else R.test(e)&&t.add(e)}return[...t]}function H(e,t,n){return e.includes(t)}function V(e,t,n){const r=(t??"").trim().toUpperCase();if(!/^[A-Z]{2}$/.test(r)||"XX"===r||"T1"===r)return"denied";const i=(n??"").trim().toUpperCase()||void 0,o=B(e.regions?.denied),a=B(e.regions?.granted);if(i){if(o.includes(`${r}-${i}`))return"denied";if(a.includes(`${r}-${i}`))return"granted"}return H(o,r)?"denied":H(a,r)||"granted"===e.default?"granted":"denied"}function z(){return"undefined"==typeof window?null:window}const G=["ad_storage","ad_user_data","ad_personalization","analytics_storage"];function F(e){const t={};for(const n of G)t[n]=e;return t}function J(e){const t=z();if(!t)return;const n=t.gtag;n?.("consent","update",{ad_storage:e.marketing?"granted":"denied",ad_user_data:e.marketing?"granted":"denied",ad_personalization:e.marketing?"granted":"denied",analytics_storage:e.analytics?"granted":"denied"}),n?.("set","ads_data_redaction",!e.marketing);const r=t.fbq;r?.("consent",e.marketing?"grant":"revoke")}const Z="bb_cid";function W(){if("undefined"!=typeof document&&"undefined"!=typeof window)try{const e=document.cookie.split("; ").find(e=>e.startsWith(`${Z}=`)),t=e?.slice(7);if(t&&/^[\w-]{16,64}$/.test(t))return t;const n=function(){const e=globalThis.crypto;if(e&&"function"==typeof e.randomUUID)return e.randomUUID();const t=new Uint8Array(16);if(e&&"function"==typeof e.getRandomValues)e.getRandomValues(t);else for(let e=0;e<t.length;e++)t[e]=Math.floor(256*Math.random());return Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("")}(),r=m(window.location.hostname,document);return document.cookie=`${Z}=${n}; path=/; max-age=34128000; SameSite=Lax`+(r?`; domain=${r}`:""),n}catch{return}}const K="bb_consent_recorded";function X(e){if("function"!=typeof fetch||!e.serverUrl||!e.orgId||!e.clientId)return;const t=JSON.stringify([e.orgId,e.clientId,!!e.state.analytics,!!e.state.marketing,e.manifestVersion??"",e.consentString??"",e.headers?.["x-session-id"]?"account":"anonymous"]);if(!e.source&&function(e){try{return window.localStorage.getItem(K)===e}catch{return!1}}(t))return;!function(e){try{window.localStorage.setItem(K,e)}catch{}}(t);const n=W();if(!n)return;const r=`${e.serverUrl.replace(/\/$/,"")}/api/v1/public/${e.orgId}/consent`;try{fetch(r,{method:"POST",keepalive:!0,headers:{"content-type":"application/json",...e.headers??{}},body:JSON.stringify({clientId:e.clientId,visitorId:n,choices:{analytics:!!e.state.analytics,marketing:!!e.state.marketing},...e.manifestVersion?{manifestVersion:e.manifestVersion}:{},...e.source?{source:e.source.slice(0,40)}:{},...e.consentString?{consentString:e.consentString.slice(0,2e3)}:{}})}).catch(()=>{})}catch{}}const Q=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),Y=(e,t)=>e>>>t|e<<32-t;function ee(e){return function(e){let t="";for(let n=0;n<e.length;n++)t+=e[n].toString(16).padStart(2,"0");return t}(function(e){let t=1779033703,n=3144134277,r=1013904242,i=2773480762,o=1359893119,a=2600822924,s=528734635,c=1541459225;const d=e.length,l=d+1,u=l+(56-l%64+64)%64+8,p=new Uint8Array(u);p.set(e,0),p[d]=128;const g=8*d,f=Math.floor(g/4294967296),m=g>>>0;p[u-8]=f>>>24&255,p[u-7]=f>>>16&255,p[u-6]=f>>>8&255,p[u-5]=255&f,p[u-4]=m>>>24&255,p[u-3]=m>>>16&255,p[u-2]=m>>>8&255,p[u-1]=255&m;const h=new Uint32Array(64);for(let e=0;e<u;e+=64){for(let t=0;t<16;t++){const n=e+4*t;h[t]=p[n]<<24|p[n+1]<<16|p[n+2]<<8|p[n+3]}for(let e=16;e<64;e++){const t=Y(h[e-15],7)^Y(h[e-15],18)^h[e-15]>>>3,n=Y(h[e-2],17)^Y(h[e-2],19)^h[e-2]>>>10;h[e]=h[e-16]+t+h[e-7]+n>>>0}let d=t,l=n,u=r,g=i,f=o,m=a,y=s,w=c;for(let e=0;e<64;e++){const t=w+(Y(f,6)^Y(f,11)^Y(f,25))+(f&m^~f&y)+Q[e]+h[e]>>>0,n=d&l^d&u^l&u;w=y,y=m,m=f,f=g+t>>>0,g=u,u=l,l=d,d=t+((Y(d,2)^Y(d,13)^Y(d,22))+n>>>0)>>>0}t=t+d>>>0,n=n+l>>>0,r=r+u>>>0,i=i+g>>>0,o=o+f>>>0,a=a+m>>>0,s=s+y>>>0,c=c+w>>>0}const y=new Uint8Array(32),w=[t,n,r,i,o,a,s,c];for(let e=0;e<8;e++)y[4*e]=w[e]>>>24&255,y[4*e+1]=w[e]>>>16&255,y[4*e+2]=w[e]>>>8&255,y[4*e+3]=255&w[e];return y}(e))}function te(e){const t=String(e??"").trim().toLowerCase(),n=t.lastIndexOf("@");if(n<1||n===t.length-1)return"";let r=t.slice(0,n);const i=t.slice(n+1);return"gmail.com"!==i&&"googlemail.com"!==i||(r=r.replace(/\./g,"")),`${r}@${i}`}function ne(e){const t=String(e??"").trim();if(!t.startsWith("+"))return"";const n=t.replace(/[^\d]/g,"");return n.length>=8&&n.length<=15?`+${n}`:""}async function re(e){const t=globalThis.crypto?.subtle;if(t&&"function"==typeof t.digest)try{const n=await t.digest("SHA-256",(new TextEncoder).encode(e));return Array.from(new Uint8Array(n)).map(e=>e.toString(16).padStart(2,"0")).join("")}catch{}return ee((n=e,(new TextEncoder).encode(n)));var n}async function ie(e){const t=te(e.email),n=ne(e.phone),r={};return t&&(r.emailHash=await re(t)),n&&(r.phoneHash=await re(n)),r}function oe(e,t){if("undefined"==typeof window)return;if(!t.emailHash&&!t.phoneHash)return;const n=window;e.some(e=>"google_ads"===e.provider||"ga4"===e.provider||"gtm"===e.provider)&&n.gtag?.("set","user_data",{...t.emailHash?{sha256_email_address:t.emailHash}:{},...t.phoneHash?{sha256_phone_number:t.phoneHash}:{}});for(const r of e)"meta_pixel"===r.provider&&r.providerId&&n.fbq?.("init",r.providerId,{...t.emailHash?{em:t.emailHash}:{},...t.phoneHash?{ph:t.phoneHash}:{}})}const ae={gtm:{title:"Google Tag Manager",vendor:"Google LLC",privacyUrl:"https://policies.google.com/privacy",idLabel:"Container ID",idPattern:"^GTM-[A-Z0-9]{4,10}$",idExample:"GTM-ABC1234",scriptOrigin:"https://www.googletagmanager.com",defaultConsentCategory:"analytics",supportsConsentMode:!0,needsConversionIds:!1},ga4:{title:"Google Analytics 4",vendor:"Google LLC",privacyUrl:"https://policies.google.com/privacy",idLabel:"Measurement ID",idPattern:"^G-[A-Z0-9]{8,12}$",idExample:"G-ABCD123456",scriptOrigin:"https://www.googletagmanager.com",defaultConsentCategory:"analytics",supportsConsentMode:!0,needsConversionIds:!1},google_ads:{title:"Google Ads",vendor:"Google LLC",privacyUrl:"https://policies.google.com/privacy",idLabel:"Conversion ID",idPattern:"^AW-[0-9]{9,12}$",idExample:"AW-123456789",scriptOrigin:"https://www.googletagmanager.com",defaultConsentCategory:"marketing",supportsConsentMode:!0,needsConversionIds:!0},meta_pixel:{title:"Meta Pixel",vendor:"Meta Platforms Ireland Limited",privacyUrl:"https://www.facebook.com/privacy/policy",idLabel:"Pixel ID",idPattern:"^[0-9]{15,16}$",idExample:"123456789012345",scriptOrigin:"https://connect.facebook.net",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!1,multiInstance:!0},x_pixel:{title:"X (Twitter) Pixel",vendor:"X Corp.",privacyUrl:"https://x.com/en/privacy",idLabel:"Pixel ID",idPattern:"^o[a-z0-9]{4,6}$",idExample:"o1a2b3",scriptOrigin:"https://static.ads-twitter.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!0,multiInstance:!0},linkedin:{title:"LinkedIn Insight Tag",vendor:"LinkedIn Ireland Unlimited Company",privacyUrl:"https://www.linkedin.com/legal/privacy-policy",idLabel:"Partner ID",idPattern:"^[0-9]{6,9}$",idExample:"1234567",scriptOrigin:"https://snap.licdn.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!0,multiInstance:!0},tiktok:{title:"TikTok Pixel",vendor:"TikTok Information Technologies UK Limited",privacyUrl:"https://www.tiktok.com/legal/privacy-policy",idLabel:"Pixel ID",idPattern:"^[A-Z0-9]{20}$",idExample:"C4A1B2C3D4E5F6G7H8I9",scriptOrigin:"https://analytics.tiktok.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!1,multiInstance:!0},reddit:{title:"Reddit Pixel",vendor:"Reddit, Inc.",privacyUrl:"https://www.reddit.com/policies/privacy-policy",idLabel:"Advertiser ID",idPattern:"^t2_[a-z0-9]{4,12}$",idExample:"t2_abc123",scriptOrigin:"https://www.redditstatic.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!1,multiInstance:!0},bing_uet:{title:"Microsoft Advertising (UET)",vendor:"Microsoft Corporation",privacyUrl:"https://privacy.microsoft.com/en-us/privacystatement",idLabel:"Tag ID",idPattern:"^[0-9]{7,9}$",idExample:"12345678",scriptOrigin:"https://bat.bing.com",defaultConsentCategory:"marketing",supportsConsentMode:!1,needsConversionIds:!1,multiInstance:!0},clarity:{title:"Microsoft Clarity",vendor:"Microsoft Corporation",privacyUrl:"https://privacy.microsoft.com/en-us/privacystatement",idLabel:"Project ID",idPattern:"^[a-z0-9]{10}$",idExample:"ab12cd34ef",scriptOrigin:"https://www.clarity.ms",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1},hotjar:{title:"Hotjar",vendor:"Hotjar Limited",privacyUrl:"https://www.hotjar.com/legal/policies/privacy/",idLabel:"Site ID",idPattern:"^[0-9]{6,9}$",idExample:"1234567",scriptOrigin:"https://static.hotjar.com",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1},posthog:{title:"PostHog",vendor:"PostHog, Inc.",privacyUrl:"https://posthog.com/privacy",idLabel:"Project API key",idPattern:"^phc_[A-Za-z0-9]{32,48}$",idExample:"phc_abcdefghijklmnopqrstuvwxyz012345",scriptOrigin:"https://us-assets.i.posthog.com",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1,hosts:["us.i.posthog.com","eu.i.posthog.com"]},plausible:{title:"Plausible Analytics",vendor:"Plausible Insights OÜ",privacyUrl:"https://plausible.io/privacy",idLabel:"Domain",idPattern:"^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$",idExample:"example.com",scriptOrigin:"https://plausible.io",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1},ahrefs:{title:"Ahrefs Analytics",vendor:"Ahrefs Pte. Ltd.",privacyUrl:"https://ahrefs.com/privacy",idLabel:"Analytics key",idPattern:"^[A-Za-z0-9+/=]{20,64}$",idExample:"AbCdEfGhIjKlMnOpQrStUv==",scriptOrigin:"https://analytics.ahrefs.com",defaultConsentCategory:"analytics",supportsConsentMode:!1,needsConversionIds:!1}},se=Object.keys(ae);function ce(e){return"string"==typeof e&&Object.prototype.hasOwnProperty.call(ae,e)}function de(e,t){return!!ce(e)&&("string"==typeof t&&0!==t.length&&new RegExp(ae[e].idPattern).test(t))}const le=/^[a-z][a-z0-9-]{0,40}$/,ue=/^[\w.:/@+=-]{1,200}$/;function pe(e){return function(e){if("string"!=typeof e)return!1;if(0===e.length||e.length>300)return!1;let t;try{t=new URL(e)}catch{return!1}return!("https:"!==t.protocol||!t.hostname||!t.hostname.includes(".")||e.includes("?")||e.includes("#")||t.username||t.password)}(e.src)&&function(e){if(null==e)return!0;if("object"!=typeof e||Array.isArray(e))return!1;const t=Object.entries(e);return!(t.length>12)&&t.every(([e,t])=>le.test(e)&&"string"==typeof t&&ue.test(t))}(e.dataAttributes)}const ge=Array.from(new Set(se.map(e=>ae[e].scriptOrigin))).sort(),fe={sign_up:{ga4:"sign_up",meta:"CompleteRegistration",tiktok:"CompleteRegistration",reddit:"SignUp"},login:{ga4:"login",meta:null,tiktok:null,reddit:null},trial_started:{ga4:"begin_checkout",meta:"StartTrial",tiktok:"StartTrial",reddit:"Lead"},checkout_started:{ga4:"begin_checkout",meta:"InitiateCheckout",tiktok:"InitiateCheckout",reddit:"AddToCart"},purchase:{ga4:"purchase",meta:"Purchase",tiktok:"CompletePayment",reddit:"Purchase"},subscription_created:{ga4:"purchase",meta:"Subscribe",tiktok:"Subscribe",reddit:"Purchase"},subscription_upgraded:{ga4:"subscription_upgraded",meta:null,tiktok:null,reddit:null},lead:{ga4:"generate_lead",meta:"Lead",tiktok:"SubmitForm",reddit:"Lead"},workspace_created:{ga4:"workspace_created",meta:null,tiktok:null,reddit:null}},me=Object.keys(fe);function he(e){return me.includes(e)}function ye(){return"undefined"==typeof window?null:window}const we={gtm:"dataLayer",ga4:"gtag",google_ads:"gtag",meta_pixel:"fbq",x_pixel:"twq",linkedin:"lintrk",tiktok:"ttq",reddit:"rdt",bing_uet:"uetq",clarity:"clarity",hotjar:"hj",posthog:"posthog",plausible:"plausible",ahrefs:"__ahrefs_loaded"};function ve(){return"undefined"==typeof window?null:window}function _e(e,t={}){const n=ve();if(!n)return null;const r=n.document.createElement("script");r.async=!0,r.src=e;for(const[e,n]of Object.entries(t))r.setAttribute(e,n);return n.document.head.appendChild(r),r}function be(e){const t=ve();if(!t)return;const n=t.document.createElement("script");n.text=e,t.document.head.appendChild(n)}function ke(e){const t=ve();t&&(Array.isArray(t[e])||(t[e]=[]),"function"!=typeof t.gtag&&(t.gtag=function(){t[e].push(arguments)}))}const Ie=new Set;function Ce(e){for(const t of Ie)if(t.slice(0,t.indexOf(":"))===e)return!0;return!1}function $e(e,t){const n=ve();if(!n)return!1;if("gtm"===e||"ga4"===e||"google_ads"===e){const e=n.google_tag_manager;return!(!e||"object"!=typeof e)&&Object.prototype.hasOwnProperty.call(e,t)}const r=we[e];if(!r)return!1;if(void 0===n[r])return!1;if(Ie.has(`${e}:${t}`))return!0;return!ae[e].multiInstance||!Ce(e)}const Se={meta_pixel:e=>`fbq('init','${e}');fbq('track','PageView');`,x_pixel:e=>`twq('config','${e}');`,tiktok:e=>`ttq.load('${e}');ttq.page();`,reddit:e=>`rdt('init','${e}');rdt('track','PageVisit');`,bing_uet:e=>`window.uetq=window.uetq||[];window.uetq.push({ti:'${e}',enableAutoSpaTracking:false});`,linkedin:e=>`window._linkedin_data_partner_ids=window._linkedin_data_partner_ids||[];window._linkedin_data_partner_ids.push('${e}');`};function Ae(e,t,n){const r=function(e,t,n){const r=ve();if(!r)return!1;if("external"===e.provider){if(!e.src)return!1;const t={};for(const[n,r]of Object.entries(e.dataAttributes??{}))t[`data-${n}`]=r;return _e(e.src,t),!0}const i=e.provider,o=ae[i];if(!o)return!1;const a=e.providerId;if(!a)return!1;const s=Se[i];if(s&&Ce(i))return be(s(a)),!0;switch(i){case"gtm":{ke(t),r[t].push({"gtm.start":Date.now(),event:"gtm.js"});const e="dataLayer"===t?"":`&l=${t}`;return _e(`${o.scriptOrigin}/gtm.js?id=${a}${e}`),!0}case"ga4":case"google_ads":{ke(t),_e(`${o.scriptOrigin}/gtag/js?id=${a}`);const e=r.gtag;e("js",new Date);const s="ga4"===i&&n?.gaClientId?{client_id:n.gaClientId}:void 0;return s?e("config",a,s):e("config",a),!0}case"meta_pixel":return be(`!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,document,'script','${o.scriptOrigin}/en_US/fbevents.js');fbq('init','${a}');fbq('track','PageView');`),!0;case"x_pixel":return be(`!function(e,t,n,s,u,a){e.twq||(s=e.twq=function(){s.exe?s.exe.apply(s,arguments):s.queue.push(arguments)},s.version='1.1',s.queue=[],u=t.createElement(n),u.async=!0,u.src='${o.scriptOrigin}/uwt.js',a=t.getElementsByTagName(n)[0],a.parentNode.insertBefore(u,a))}(window,document,'script');twq('config','${a}');`),!0;case"linkedin":return be(`window._linkedin_partner_id='${a}';window._linkedin_data_partner_ids=window._linkedin_data_partner_ids||[];window._linkedin_data_partner_ids.push('${a}');window.lintrk=window.lintrk||function(a,b){(window.lintrk.q=window.lintrk.q||[]).push([a,b])};window.lintrk.q=window.lintrk.q||[];`),_e(`${o.scriptOrigin}/li.lms-analytics/insight.min.js`),!0;case"tiktok":return be(`!function(w,d,t){w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];ttq.methods=['page','track','identify','instances','debug','on','off','once','ready','alias','group','enableCookie','disableCookie'];ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);ttq.load=function(e,n){var r='${o.scriptOrigin}/i18n/pixel/events.js';ttq._i=ttq._i||{};ttq._i[e]=[];ttq._i[e]._u=r;ttq._t=ttq._t||{};ttq._t[e]=+new Date;ttq._o=ttq._o||{};ttq._o[e]=n||{};var o=d.createElement('script');o.type='text/javascript';o.async=!0;o.src=r+'?sdkid='+e+'&lib='+t;var a=d.getElementsByTagName('script')[0];a.parentNode.insertBefore(o,a)};ttq.load('${a}');ttq.page()}(window,document,'ttq');`),!0;case"reddit":return be(`!function(w,d){if(!w.rdt){var p=w.rdt=function(){p.sendEvent?p.sendEvent.apply(p,arguments):p.callQueue.push(arguments)};p.callQueue=[];var t=d.createElement('script');t.src='${o.scriptOrigin}/ads/pixel.js';t.async=!0;var s=d.getElementsByTagName('script')[0];s.parentNode.insertBefore(t,s)}}(window,document);rdt('init','${a}');rdt('track','PageVisit');`),!0;case"bing_uet":return be(`(function(w,d,t,r,u){w[u]=w[u]||[];w[u].push({ti:'${a}',enableAutoSpaTracking:false});var o=d.createElement(t);o.src='${o.scriptOrigin}/bat.js';o.async=1;var i=d.getElementsByTagName(t)[0];i.parentNode.insertBefore(o,i)})(window,document,'script',0,'uetq');`),!0;case"clarity":return be(`(function(c,l,a,r,i,t,y){c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};t=l.createElement(r);t.async=1;t.src='${o.scriptOrigin}/tag/'+i;y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y)})(window,document,'clarity','script','${a}');`),!0;case"hotjar":return be(`(function(h,o,t,j,a,r){h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};h._hjSettings={hjid:${a},hjsv:6};a=o.getElementsByTagName('head')[0];r=o.createElement('script');r.async=1;r.src='${o.scriptOrigin}/hotjar-'+h._hjSettings.hjid+'.js?sv='+h._hjSettings.hjsv;a.appendChild(r)})(window,document);`),!0;case"posthog":{const t=o.hosts,n=t?.includes(e.host??"")?e.host:t?.[0]??"us.i.posthog.com";return be(`!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split('.');2==o.length&&(t=t[o[0]],e=o[1]);t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement('script')).type='text/javascript',p.async=!0,p.src='${o.scriptOrigin}/static/array.js',(r=t.getElementsByTagName('script')[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a='posthog',u.people=u.people||[],u.toString=function(t){var e='posthog';return'posthog'!==a&&(e+='.'+a),t||(e+=' (stub)'),e},u.people.toString=function(){return u.toString(1)+'.people (stub)'},o='init capture register register_once identify alias people.set people.set_once set_config get_distinct_id getFeatureFlag isFeatureEnabled onFeatureFlags reloadFeatureFlags group reset'.split(' '),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);posthog.init('${a}',{api_host:'https://${n}'});`),!0}case"plausible":return be("window.plausible=window.plausible||function(){(window.plausible.q=window.plausible.q||[]).push(arguments)};"),_e(`${o.scriptOrigin}/js/script.js`,{"data-domain":a,defer:"true"}),!0;case"ahrefs":return _e(`${o.scriptOrigin}/analytics.js`,{"data-key":a}),r.__ahrefs_loaded=!0,!0;default:return!1}}(e,t,n);return r&&"external"!==e.provider&&e.providerId&&Ie.add(`${e.provider}:${e.providerId}`),r}const je=Symbol.for("@buildbase/sdk.tracking.context"),xe=globalThis,qe=xe[je]??(xe[je]=s(null)),Ue={consent:{manifest:[],state:null,effective:null,default:null,country:null,set:()=>{}},track:()=>{},setUser:()=>{},setIdentity:()=>{},setConsentRecordHeaders:()=>{},setProperties:()=>{},getProperties:()=>({}),completeCheckout:async()=>{},installed:{},ready:!0,attribution:{}};function Oe(){return a(qe)??Ue}const Pe=({serverUrl:a,orgId:s,clientId:c,enabled:d=!0,consent:u="auto",autoPageview:p=!0,events:g,onEvent:f,properties:m,enrich:h,identity:y,debug:w=!1,children:v})=>{const _=t(y);_.current=y;const[b,I]=n(null),[$,S]=n(!1),[A,j]=n(!1),x="object"==typeof u?JSON.stringify(u):"",q=r(()=>x?function(e){if(!e||"object"!=typeof e)return null;const t=e;if("granted"!==t.default&&"denied"!==t.default)return null;const n=e=>Array.isArray(e)?e.filter(e=>"string"==typeof e):void 0;return{default:t.default,regions:{...n(t.regions?.denied)?{denied:n(t.regions?.denied)}:{},...n(t.regions?.granted)?{granted:n(t.regions?.granted)}:{}}}}(JSON.parse(x)):null,[x]),U="string"==typeof u?u:"auto",O="granted"===U?{analytics:!0,marketing:!0}:"denied"===U?{analytics:!1,marketing:!1}:null,[T,L]=n(O),M=t(null),N=t(f);N.current=f;const R=t(h);R.current=h;const H=t({});H.current=m??{};const G=t({}),Z=i(()=>({...H.current,...G.current}),[]),W=i(e=>{const t={...G.current,...e};for(const[e,n]of Object.entries(t))void 0===n&&delete t[e];G.current=t},[]),[K,Q]=n({}),Y=t({}),[ee,te]=n(0),ne=t(null),[re,se]=n(0),le=t({}),ue=t(null);ue.current=b;const ge=b?.dataLayerName??"dataLayer",me=i((...e)=>{w&&console.info("[buildbase:tracking]",...e)},[w]);o(()=>{return e=()=>{0!==Object.keys(Y.current).length&&window.dispatchEvent("function"==typeof PageTransitionEvent?new PageTransitionEvent("pagehide",{persisted:!1}):new Event("pagehide"))},l.add(e),()=>{l.delete(e)};var e},[]),o(()=>{if(!(d&&a&&s&&c))return void S(!0);let e=!1;const t=`${a.replace(/\/$/,"")}/api/v1/public/${s}/tracking?clientId=${encodeURIComponent(c)}`;return fetch(t).then(e=>e.ok?e.json():null).then(t=>{if(e||!t)return;const n=t.data??t;n&&Array.isArray(n.scripts)&&I(n)}).catch(()=>{me("config fetch failed; nothing installed")}).finally(()=>{e||S(!0)}),()=>{e=!0}},[d,a,s,c,me]),o(()=>{d&&Q(k())},[d]);const we="auto"===U?q??b?.consent?.defaults??null:null,ve=r(()=>b?"auto"!==U?U:q?V(q,b.country,b.region):b.consent?.defaults?b.resolvedConsentDefault??V(b.consent.defaults,b.country,b.region):"denied":null,[b,U,q]),_e=T??("granted"===ve?{analytics:!0,marketing:!0}:null),be=!!b?.enhancedConversions&&!!_e?.marketing,Ie=!!b?.scripts?.some(e=>"ga4"===e.provider||"google_ads"===e.provider||"gtm"===e.provider),Ce=we?JSON.stringify(we):"";o(()=>{d&&b?.enabled&&(ke(ge),function(e,t,n={}){const r=z();if(!r)return;Array.isArray(r[e])||(r[e]=[]),"function"!=typeof r.gtag&&(r.gtag=function(){r[e].push(arguments)});const i=r.gtag,o="auto"===t?n.regional:null;let a="granted"===t?"granted":"denied";if(o){const e=B(o.regions?.denied),t=B(o.regions?.granted).filter(t=>!e.includes(t));e.length&&i("consent","default",{...F("denied"),region:e,wait_for_update:500}),t.length&&i("consent","default",{...F("granted"),region:t}),a=o.default}i("consent","default",{...F(a),..."denied"===a?{wait_for_update:500}:{}}),n.google&&(i("set","url_passthrough",!0),i("set","ads_data_redaction","granted"!==(n.resolved??a)))}(ge,U,{regional:Ce?JSON.parse(Ce):null,resolved:ve,google:Ie}),M.current&&J(M.current))},[d,b?.enabled,ge,U,Ce,Ie]);const Se=r(()=>b?.enabled?b.scripts.filter(e=>{const t=ce(e.provider)&&ae[e.provider].supportsConsentMode;return function(e,t,n,r){return"denied"!==r&&("granted"===r||!!t||!!n&&("marketing"===e?n.marketing:n.analytics))}(e.consentCategory,t,_e,U)}):[],[b,T,ve,U]),[je,xe]=n(()=>"undefined"==typeof window||!C(window.location.search));o(()=>{if(je)return;const e=setInterval(()=>{C(window.location.search)||xe(!0)},50),t=setTimeout(()=>xe(!0),5e3);return()=>{clearInterval(e),clearTimeout(t)}},[je]),o(()=>{if(!je)return;if(!d||!b?.enabled)return void($&&j(!0));let e=0;for(const t of Se)if(!Y.current[t.key]){if("external"===t.provider){if(!pe({src:t.src,dataAttributes:t.dataAttributes})){me("rejected external script",t.key);continue}}else{if(!ce(t.provider)){me("rejected unknown provider",t.provider);continue}if(!de(t.provider,t.providerId)){me("rejected id for",t.provider);continue}if($e(t.provider,t.providerId??"")){me(`${t.provider} ${t.providerId} is already on the page; skipping. Configure each tag in exactly one place.`);continue}}Ae(t,ge,_.current)&&(Y.current[t.key]=t.providerId??t.src??"",e+=1,me("installed",t.key))}e&&te(e=>e+1);const t=window;t.__buildbase=t.__buildbase??{},t.__buildbase.tracking={installed:{...Y.current},dataLayerName:ge,clientId:c};const n=Object.keys(Y.current).length>0,r=null!==_e||0===b.scripts.length;(n||r)&&j(!0)},[d,b,Se,$,T,ve,ge,me,je,c]),o(()=>{if(!d||!p||!b?.enabled)return;if("undefined"==typeof window)return;if(!je)return;let e=null;const t=()=>{e&&clearTimeout(e),e=setTimeout(()=>function(e,t){const n=ye();if(!n)return;const r=n[t];Array.isArray(r)&&r.push({event:"page_view",page_path:n.location.pathname,page_location:n.location.href,page_title:n.document.title});for(const t of e)switch(t.provider){case"ga4":n.gtag?.("event","page_view",{send_to:t.providerId,page_path:n.location.pathname,page_location:n.location.href,page_title:n.document.title});break;case"meta_pixel":n.fbq?.("track","PageView");break;case"tiktok":{const e=n.ttq;e?.page?.();break}case"reddit":n.rdt?.("track","PageVisit")}}(Se,ge),50)},n=window.history,r=n.pushState,i=n.replaceState;return n.pushState=function(...e){const n=r.apply(this,e);return t(),n},n.replaceState=function(...e){const n=i.apply(this,e);return t(),n},window.addEventListener("popstate",t),()=>{n.pushState=r,n.replaceState=i,window.removeEventListener("popstate",t),e&&clearTimeout(e)}},[d,p,b?.enabled,Se,ge,je]),o(()=>{if(!d)return;const e=function(e,t){const n=e?.mode??"auto",r=e?.overrides??{};if(("manual"===n||Object.values(r).some(e=>"manual"===e))&&!t)return'[buildbase:tracking] events are set to "manual" but no onEvent handler was provided, so those events would never fire anywhere. Pass onEvent, or use mode "auto".';for(const e of Object.keys(r))if(!he(e))return`[buildbase:tracking] unknown event "${e}" in events.overrides. Overrides only apply to the events the SDK fires itself.`;return null}(g,!!f);if(e)throw new Error(e)},[d,g,f]);const Ue=i((e,t={},n)=>{if(!d)return;const r=n?.eventId||function(){const e=globalThis.crypto;return e?.randomUUID?e.randomUUID():`${Date.now().toString(16)}-${Math.random().toString(16).slice(2,10)}`}(),i=g?.mode??"auto",o=(he(e)?g?.overrides?.[e]:void 0)??i,a={...H.current,...G.current,...K,...t},s=R.current?.({name:e,params:a})??{},c={...a,...s},l=N.current?.({name:e,params:c,eventId:r,handledBy:o});"manual"!==o&&!0!==l?(be&&ne.current&&oe(Se,ne.current),function(e,t,n,r,i){const o=ye();if(!o)return;const a=o[i];Array.isArray(a)&&a.push({event:e,...t,event_id:n});const s=he(e)?fe[e]:{ga4:e,meta:null,tiktok:null,reddit:null};for(const i of r){const r=i.provider,a=ae[r];if(a){if(a.needsConversionIds){const a=i.conversionIds?.[e];if(!a)continue;"google_ads"===r?o.gtag?.("event","conversion",{send_to:`${i.providerId}/${a}`,transaction_id:n,...t}):"x_pixel"===r?o.twq?.("event",a,{...t,conversion_id:n}):"linkedin"===r&&o.lintrk?.("track",{conversion_id:a});continue}switch(r){case"ga4":s.ga4&&o.gtag?.("event",s.ga4,{...t,send_to:i.providerId,event_id:n});break;case"meta_pixel":s.meta&&o.fbq?.("track",s.meta,t,{eventID:n});break;case"tiktok":if(s.tiktok){const e=o.ttq;e?.track?.(s.tiktok,{...t,event_id:n})}break;case"reddit":s.reddit&&o.rdt?.("track",s.reddit,{...t,conversionId:n});break;case"bing_uet":{const r=o.uetq;r?.push?.("event",s.ga4??e,{...t,event_id:n});break}case"clarity":o.clarity?.("event",e);break;case"hotjar":{const t=o.hj;t?.("event",e);break}case"posthog":{const r=o.posthog;r?.capture?.(e,{...t,event_id:n});break}case"plausible":o.plausible?.(e,{props:t})}}}}(e,c,r,Se,ge),me("event fired:",e,r)):me("event handled by app:",e)},[d,g,Se,ge,K,me,be]),Oe=i(async(e,t={})=>{const n=function(e){return{name:"trial_started"===e.kind?"trial_started":"purchase",params:{...e.workspaceId?{workspace_id:e.workspaceId}:{},...e.planVersionId?{plan_version_id:e.planVersionId}:{},...e.creditPackageId?{credit_package_id:e.creditPackageId}:{},...e.billingInterval?{billing_interval:e.billingInterval}:{},...e.currency?{currency:e.currency.toUpperCase()}:{},..."number"==typeof e.value?{value:e.value}:{},...e.sessionId?{transaction_id:e.sessionId}:{}}}}(e);let r=n.params;if(e.sessionId&&a&&s){const t=await async function(e,t){try{const n=e.serverUrl.replace(/\/$/,""),r=await fetch(`${n}/api/v1/public/${encodeURIComponent(e.orgId)}/checkout/${encodeURIComponent(t)}`,{credentials:"omit",..."undefined"!=typeof AbortSignal&&AbortSignal.timeout?{signal:AbortSignal.timeout(2e3)}:{}});if(!r.ok)return null;const i=await r.json(),o=i?.data??i;return"number"!=typeof o?.amount?null:{value:D(o.amount,o.currency),currency:"string"==typeof o.currency?o.currency:void 0,...Array.isArray(o.items)&&o.items.length?{items:o.items}:{}}}catch{return null}}({serverUrl:a,orgId:s},e.sessionId);t&&"number"==typeof t.value&&(r={...r,value:t.value,...t.currency?{currency:t.currency.toUpperCase()}:{},...t.items?.length?{items:t.items}:{}})}if(Ue(n.name,{...r,...t},{eventId:e.eventId}),"purchase"===n.name&&e.sessionId&&a&&s){const t=(b?.scripts??[]).find(e=>"ga4"===e.provider&&e.providerId);t&&$e("ga4",t.providerId??"")&&function(e,t,n){try{const r=e.serverUrl.replace(/\/$/,"");fetch(`${r}/api/v1/public/${encodeURIComponent(e.orgId)}/checkout/${encodeURIComponent(t)}/reported`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:n}),keepalive:!0,credentials:"omit"}).catch(()=>{})}catch{}}({serverUrl:a,orgId:s},e.sessionId,"ga4")}},[a,s,Ue,b]),[Pe]=n(()=>"undefined"==typeof window?"":window.location.search);o(()=>{if(!d||!A)return;if("undefined"==typeof window)return;const e=P(window.location.search);if(e)return void Oe(e);const t=E(Pe);t&&Ue("checkout_abandoned",{...t.workspaceId?{workspace_id:t.workspaceId}:{},...t.planVersionId?{plan_version_id:t.planVersionId}:{},...t.creditPackageId?{credit_package_id:t.creditPackageId}:{},...t.billingInterval?{billing_interval:t.billingInterval}:{},...t.currency?{currency:t.currency.toUpperCase()}:{},..."number"==typeof t.value?{value:t.value}:{},seconds_at_checkout:Math.max(0,Math.round((Date.now()-t.startedAt)/1e3))})},[d,A,Oe,Pe,Ue]);const Ee=i((e,t)=>{M.current=e,L(e),J(e),d&&X({serverUrl:a,orgId:s,clientId:c,state:e,manifestVersion:ue.current?.consent?.manifestVersion,source:t?.source,consentString:t?.consentString,headers:le.current})},[d,a,s,c]),Te=i(e=>{le.current={...e}},[]),Le=i(e=>{if(!e)return ne.current=null,void se(e=>e+1);ie(e).then(e=>{ne.current=e.emailHash||e.phoneHash?e:null,se(e=>e+1)})},[]),De=i((e,t)=>{const n=function(e){if(!e)return{traits:e,identity:null};const{email:t,phone:n,...r}=e,i={};return"string"==typeof t&&t&&(i.email=t),"string"==typeof n&&n&&(i.phone=n),{traits:r,identity:i.email||i.phone?i:null}}(t);n.identity&&Le(n.identity),function(e,t,n){const r=ye();if(!r)return;const i=!!n&&Object.keys(n).length>0;for(const o of t)switch(o.provider){case"ga4":case"google_ads":r.gtag?.("set",{user_id:e}),i&&r.gtag?.("set",{user_properties:n});break;case"meta_pixel":o.providerId&&r.fbq?.("init",o.providerId,{external_id:e});break;case"posthog":r.posthog?.identify?.(e,i?n:void 0);break;case"clarity":if(r.clarity?.("identify",e),i)for(const[e,t]of Object.entries(n))r.clarity?.("set",e,String(t));break;case"hotjar":r.hj?.("identify",e,{});break;case"tiktok":{const t=r.ttq;t?.identify?.({external_id:e});break}}}(e,Se,n.traits)},[Se,Le]);o(()=>{be&&ne.current&&0!==Object.keys(Y.current).length&&oe(Se,ne.current)},[be,Se,re,ee]);const Me=r(()=>({consent:{manifest:b?.consent?.manifest??[],state:T,effective:_e,default:ve,country:b?.country??null,set:Ee},track:Ue,setUser:De,setIdentity:Le,setConsentRecordHeaders:Te,setProperties:W,getProperties:Z,completeCheckout:Oe,installed:{...Y.current},ready:A,attribution:K}),[b,T,ve,Ee,Ue,De,Le,Te,W,Z,Oe,A,ee,K]);return e(qe.Provider,{value:Me,children:v})};function Ee(e={}){const{completeCheckout:n,ready:r}=Oe(),i=t(e);i.current=e;const a=t(!1);o(()=>{if(!r)return;if(a.current)return;const e=P(window.location.search)??U();e&&(a.current=!0,n(e,i.current))},[r,n])}Pe.displayName="BuildBaseTracking";const Te={sign_in_started:"The sign-in / sign-up button was pressed.",pricing_viewed:"A <PricingPage> finished loading its plans.",pricing_plan_selected:"A plan was chosen on a <PricingPage>.",workspace_switcher_opened:"The workspace switcher was opened.",workspace_settings_opened:"The workspace settings modal was opened.",workspace_settings_section_viewed:"A different section of the settings modal was opened.",plan_picker_opened:"The plan picker was shown.",billing_interval_changed:"Monthly / quarterly / yearly was switched in the plan picker.",plan_selected:"A plan was chosen in the plan picker.",plan_picker_dismissed:"The plan picker was closed without choosing a plan.",checkout_abandoned:"The customer came back from Stripe without paying.",billing_portal_opened:"Stripe’s billing portal was opened.",subscription_cancel_started:"The cancel-subscription confirmation was opened.",subscription_cancelled:"A subscription was cancelled.",subscription_resumed:"A cancelled subscription was resumed.",feature_gate_shown:'A feature gate rendered its "not on your plan" side.',quota_limit_reached:"A quota gate rendered because a quota is used up.",quota_threshold_reached:"A usage-threshold gate rendered.",plan_gate_shown:'A plan gate rendered its "needs another plan" side.',subscription_notice_shown:"A billing notice (trial ending, payment failed…) was shown.",sdk_error:"An SDK operation failed (component, action and code only)."};export{p as ATTRIBUTION_PARAMS,Pe as BuildBaseTracking,M as EEA_COUNTRIES,fe as EVENT_MAPPINGS,Te as FUNNEL_EVENTS,N as SAFE_REGIONAL_CONSENT,ae as TAG_PROVIDERS,se as TAG_PROVIDER_IDS,ge as TAG_SCRIPT_ORIGINS,k as captureAttribution,B as expandRegions,I as getAttribution,ie as hashIdentity,he as isCanonicalEvent,ce as isTagProviderId,de as isValidProviderId,te as normalizeEmail,ne as normalizePhone,V as resolveConsentDefault,Ee as useCheckoutCompleted,Oe as useTracking};
|
package/docs/ERROR_CODES.md
CHANGED
|
@@ -41,6 +41,30 @@ This document lists error codes used in the BuildBase SDK and their meanings. Th
|
|
|
41
41
|
| `WORKSPACE_OWNER_REQUIRED` | Workspace owner required | When operation requires workspace owner (e.g., delete) |
|
|
42
42
|
| `INVALID_WORKSPACE_ID` | Invalid workspace ID | When workspace ID format is invalid |
|
|
43
43
|
|
|
44
|
+
### Workspace Invitation Errors
|
|
45
|
+
|
|
46
|
+
Thrown by `inviteMember`, `resendInvitation`, `revokeInvitation`, `acceptInvitation`, `declineInvitation` and `previewInvitation`. The error is a plain `Error` with `status` and `code` properties, plus the fields listed; check with `isInvitationError(err)`.
|
|
47
|
+
|
|
48
|
+
| Code | HTTP | When It Occurs | Extra fields |
|
|
49
|
+
| ---------------------------- | ---- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
|
|
50
|
+
| `SEAT_LIMIT_REACHED` | 402 | Members plus pending invitations fill the plan's seats or `maxWorkspaceUsers` | `currentUserCount`, `limit` |
|
|
51
|
+
| `INVITATION_NOT_FOUND` | 404 | Unknown id, or a revoked link | |
|
|
52
|
+
| `INVITATION_ALREADY_HANDLED` | 409 | Already accepted, declined, or already a live invitation for that address | `invitationStatus`, `invitationId` |
|
|
53
|
+
| `INVITATION_EXPIRED` | 410 | Past its 14 days, or the workspace no longer exists | |
|
|
54
|
+
| `INVITATION_EMAIL_MISMATCH` | 403 | The signed-in account is not the invited address | `invitedEmail` (scrambled) |
|
|
55
|
+
| `EMAIL_NOT_VERIFIED` | 403 | Accepting from the list needs a verified email. An accept carrying the link's `token` proves the address instead | |
|
|
56
|
+
| `WORKSPACE_INVITES_DISABLED` | 403 | The organization's workspace mode does not allow invitations | |
|
|
57
|
+
| `INVITATION_RATE_LIMITED` | 429 | Resend inside the cooldown, or the hourly/daily send budget | `retryAfterSeconds` (resend only) |
|
|
58
|
+
| `INVITATION_EMAIL_FAILED` | 502 | The invitation email could not be sent; nothing was created | |
|
|
59
|
+
| `USER_BLOCKED` | 403 | The invited or accepting account is blocked | |
|
|
60
|
+
|
|
61
|
+
### Notification Send Errors
|
|
62
|
+
|
|
63
|
+
| Code | HTTP | When It Occurs | Extra fields |
|
|
64
|
+
| ------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------- | ------------ |
|
|
65
|
+
| `NOTIFICATION_EVENT_NOT_SET_UP` | 403 | `notification.send()` named a slug the org has not set up and the plan's custom-event limit is reached (server release 22) | |
|
|
66
|
+
| `NO_SENDER_CONFIGURED` | 503 | The organization has no usable email sender, so nothing can be sent | |
|
|
67
|
+
|
|
44
68
|
### User Management Errors
|
|
45
69
|
|
|
46
70
|
| Code | Description | When It Occurs |
|