trala-angulartics2
Version:
Vendor-agnostic web analytics for Angular2 applications
1 lines • 147 kB
Source Map (JSON)
{"version":3,"file":"trala-angulartics2.mjs","sources":["../../src/lib/angulartics2-config.ts","../../src/lib/angulartics2-token.ts","../../src/lib/routerless.ts","../../src/lib/angulartics2-core.ts","../../src/lib/angular-router.ts","../../src/lib/angulartics2On.ts","../../src/lib/angulartics2.module.ts","../../src/lib/routerless.module.ts","../../src/lib/providers/adobeanalytics/adobeanalytics.ts","../../src/lib/providers/appinsights/appinsights.ts","../../src/lib/providers/baidu/baidu.ts","../../src/lib/providers/facebook/facebook.ts","../../src/lib/providers/ga/ga.ts","../../src/lib/providers/ga-enhanced-ecom/ga-enhanced-ecom.ts","../../src/lib/providers/gtm/gtm.ts","../../src/lib/providers/gst/gst.ts","../../src/lib/providers/hubspot/hubspot.ts","../../src/lib/providers/kissmetrics/kissmetrics.ts","../../src/lib/providers/launch/launch.ts","../../src/lib/providers/mixpanel/mixpanel.ts","../../src/lib/providers/pyze/pyze.ts","../../src/lib/providers/matomo/matomo.ts","../../src/lib/providers/segment/segment.ts","../../src/lib/providers/intercom/intercom.ts","../../src/lib/providers/woopra/woopra.ts","../../src/lib/providers/clicky/clicky.ts","../../src/lib/providers/amplitude/amplitude.ts","../../src/lib/providers/splunk/splunk.ts","../../src/lib/providers/ibm-digital-analytics/ibm-digital-analytics.ts","../../src/lib/providers/gosquared/gosquared.ts","../../src/lib/trala-angulartics2.ts"],"sourcesContent":["export interface GoogleAnalyticsSettings {\r\n /** array of additional account names (only works for analyticsjs) */\r\n additionalAccountNames: string[];\r\n userId: any;\r\n /** see https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#transport */\r\n transport: string;\r\n anonymizeIp: boolean;\r\n}\r\n\r\nexport interface AppInsightsSettings {\r\n userId: string;\r\n}\r\n\r\nexport interface GoogleTagManagerSettings {\r\n userId: any;\r\n}\r\n\r\nexport interface GoogleGlobalSiteTagSettings {\r\n trackingIds: any;\r\n userId?: any;\r\n anonymizeIp?: boolean;\r\n customMap?: { [key: string]: string };\r\n}\r\n\r\nexport interface PageTrackingSettings {\r\n autoTrackVirtualPages: boolean;\r\n basePath: string;\r\n excludedRoutes: (string | RegExp)[];\r\n /** drop ids from url `/sections/123/pages/456` -> `/sections/pages` */\r\n clearIds: boolean;\r\n /** drop contents of url after hash marker `/callback#authcode=1234` -> `/callback` */\r\n clearHash: boolean;\r\n /** drop query params from url `/sections/123/pages?param=456¶m2=789` -> `/sections/123/pages` */\r\n clearQueryParams: boolean;\r\n /** used with clearIds, define the matcher to clear url parts */\r\n idsRegExp: RegExp;\r\n}\r\n\r\nexport interface Angulartics2Settings {\r\n pageTracking: Partial<PageTrackingSettings>;\r\n /** Disable page tracking */\r\n developerMode: boolean;\r\n ga: Partial<GoogleAnalyticsSettings>;\r\n appInsights: Partial<AppInsightsSettings>;\r\n gtm: Partial<GoogleTagManagerSettings>;\r\n gst: Partial<GoogleGlobalSiteTagSettings>;\r\n}\r\n\r\nexport class DefaultConfig implements Angulartics2Settings {\r\n pageTracking = {\r\n autoTrackVirtualPages: true,\r\n basePath: '',\r\n excludedRoutes: [],\r\n clearIds: false,\r\n clearHash: false,\r\n clearQueryParams: false,\r\n idsRegExp:\r\n /^\\d+$|^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,\r\n };\r\n developerMode = false;\r\n ga = {};\r\n appInsights = {};\r\n gtm = {};\r\n gst = {};\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\nimport { Angulartics2Settings } from './angulartics2-config';\r\n\r\nexport interface Angulartics2Token {\r\n settings: Partial<Angulartics2Settings>;\r\n}\r\n\r\nexport const ANGULARTICS2_TOKEN = new InjectionToken<Angulartics2Token>(\r\n 'ANGULARTICS2'\r\n);\r\n","import { BehaviorSubject, Observable } from 'rxjs';\r\n\r\nimport { Angulartics2Settings } from './angulartics2-config';\r\n\r\nexport interface TrackNavigationEnd {\r\n url: string;\r\n}\r\n\r\nexport class RouterlessTracking {\r\n trackLocation(settings: Angulartics2Settings): Observable<TrackNavigationEnd> {\r\n return new BehaviorSubject<TrackNavigationEnd>({ url: '/' });\r\n }\r\n\r\n prepareExternalUrl(url: string): string {\r\n return url;\r\n }\r\n}\r\n","import { Inject, Injectable } from '@angular/core';\r\n\r\nimport { MonoTypeOperatorFunction, ReplaySubject } from 'rxjs';\r\nimport { filter } from 'rxjs/operators';\r\n\r\nimport { Angulartics2Settings, DefaultConfig } from './angulartics2-config';\r\nimport { EventTrack, PageTrack, UserTimings } from './angulartics2-interfaces';\r\nimport { Angulartics2Token, ANGULARTICS2_TOKEN } from './angulartics2-token';\r\nimport { RouterlessTracking, TrackNavigationEnd } from './routerless';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2 {\r\n settings: Angulartics2Settings;\r\n\r\n pageTrack = new ReplaySubject<Partial<PageTrack>>(10);\r\n eventTrack = new ReplaySubject<Partial<EventTrack>>(10);\r\n exceptionTrack = new ReplaySubject<any>(10);\r\n setAlias = new ReplaySubject<string>(10);\r\n setUsername = new ReplaySubject<{ userId: string | number } | string>(10);\r\n setUserProperties = new ReplaySubject<any>(10);\r\n setUserPropertiesOnce = new ReplaySubject<any>(10);\r\n setSuperProperties = new ReplaySubject<any>(10);\r\n setSuperPropertiesOnce = new ReplaySubject<any>(10);\r\n userTimings = new ReplaySubject<UserTimings>(10);\r\n\r\n constructor(\r\n private tracker: RouterlessTracking,\r\n @Inject(ANGULARTICS2_TOKEN) setup: Angulartics2Token,\r\n ) {\r\n const defaultConfig = new DefaultConfig();\r\n this.settings = { ...defaultConfig, ...setup.settings };\r\n this.settings.pageTracking = {\r\n ...defaultConfig.pageTracking,\r\n ...setup.settings.pageTracking,\r\n };\r\n this.tracker\r\n .trackLocation(this.settings)\r\n .subscribe((event: TrackNavigationEnd) => this.trackUrlChange(event.url));\r\n }\r\n\r\n /** filters all events when developer mode is true */\r\n filterDeveloperMode<T>(): MonoTypeOperatorFunction<T> {\r\n return filter((value, index) => !this.settings.developerMode);\r\n }\r\n\r\n protected trackUrlChange(url: string) {\r\n if (this.settings.pageTracking.autoTrackVirtualPages && !this.matchesExcludedRoute(url)) {\r\n const clearedUrl = this.clearUrl(url);\r\n let path: string;\r\n if (this.settings.pageTracking.basePath.length) {\r\n path = this.settings.pageTracking.basePath + clearedUrl;\r\n } else {\r\n path = this.tracker.prepareExternalUrl(clearedUrl);\r\n }\r\n this.pageTrack.next({ path });\r\n }\r\n }\r\n\r\n /**\r\n * Use string literals or regular expressions to exclude routes\r\n * from automatic pageview tracking.\r\n *\r\n * @param url location\r\n */\r\n protected matchesExcludedRoute(url: string): boolean {\r\n for (const excludedRoute of this.settings.pageTracking.excludedRoutes) {\r\n const matchesRegex = excludedRoute instanceof RegExp && excludedRoute.test(url);\r\n if (matchesRegex || url.indexOf(excludedRoute as string) !== -1) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Removes id's from tracked route.\r\n * EX: `/project/12981/feature` becomes `/project/feature`\r\n *\r\n * @param url current page path\r\n */\r\n protected clearUrl(url: string): string {\r\n if (\r\n this.settings.pageTracking.clearIds ||\r\n this.settings.pageTracking.clearQueryParams ||\r\n this.settings.pageTracking.clearHash\r\n ) {\r\n return url\r\n .split('/')\r\n .map(part => (this.settings.pageTracking.clearQueryParams ? part.split('?')[0] : part))\r\n .map(part => (this.settings.pageTracking.clearHash ? part.split('#')[0] : part))\r\n .filter(\r\n part =>\r\n !this.settings.pageTracking.clearIds ||\r\n !part.match(this.settings.pageTracking.idsRegExp),\r\n )\r\n .join('/');\r\n }\r\n return url;\r\n }\r\n}\r\n","import { Location } from '@angular/common';\r\nimport { Injectable } from '@angular/core';\r\nimport { NavigationEnd, Router } from '@angular/router';\r\n\r\nimport { delay, filter, map } from 'rxjs/operators';\r\nimport { Observable } from 'rxjs';\r\n\r\nimport { RouterlessTracking, TrackNavigationEnd } from './routerless';\r\n\r\n/**\r\n * Track Route changes for applications using Angular's\r\n * default router\r\n *\r\n * @link https://angular.io/api/router/Router\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class AngularRouterTracking implements RouterlessTracking {\r\n constructor(private router: Router, private location: Location) {}\r\n\r\n trackLocation(settings): Observable<TrackNavigationEnd> {\r\n return this.router.events.pipe(\r\n filter(e => e instanceof NavigationEnd),\r\n filter(() => !settings.developerMode),\r\n map((e: NavigationEnd) => {\r\n return { url: e.urlAfterRedirects };\r\n }),\r\n delay(0),\r\n );\r\n }\r\n\r\n prepareExternalUrl(url: string): string {\r\n return this.location.prepareExternalUrl(url);\r\n }\r\n}\r\n","import { AfterContentInit, Directive, ElementRef, Input, NgModule, Renderer2 } from '@angular/core';\r\nimport { Angulartics2 } from './angulartics2-core';\r\n\r\n@Directive({ selector: '[angulartics2On]' })\r\nexport class Angulartics2On implements AfterContentInit {\r\n // eslint-disable-next-line @angular-eslint/no-input-rename\r\n @Input('angulartics2On') angulartics2On: string;\r\n @Input() angularticsAction: string;\r\n @Input() angularticsCategory: string;\r\n @Input() angularticsLabel: string;\r\n @Input() angularticsValue: string;\r\n @Input() angularticsProperties: any = {};\r\n\r\n constructor(\r\n private elRef: ElementRef,\r\n private angulartics2: Angulartics2,\r\n private renderer: Renderer2,\r\n ) {}\r\n\r\n ngAfterContentInit() {\r\n this.renderer.listen(this.elRef.nativeElement, this.angulartics2On || 'click', (event: Event) =>\r\n this.eventTrack(event),\r\n );\r\n }\r\n\r\n eventTrack(event: Event) {\r\n const action = this.angularticsAction; // || this.inferEventName();\r\n const properties: any = {\r\n ...this.angularticsProperties,\r\n eventType: event.type,\r\n };\r\n\r\n if (this.angularticsCategory) {\r\n properties.category = this.angularticsCategory;\r\n }\r\n if (this.angularticsLabel) {\r\n properties.label = this.angularticsLabel;\r\n }\r\n if (this.angularticsValue) {\r\n properties.value = this.angularticsValue;\r\n }\r\n\r\n this.angulartics2.eventTrack.next({\r\n action,\r\n properties,\r\n });\r\n }\r\n\r\n /*private isCommand() {\r\n return ['a:', 'button:', 'button:button', 'button:submit', 'input:button', 'input:submit'].indexOf(\r\n getDOM().tagName(this.el).toLowerCase() + ':' + (getDOM().type(this.el) || '')) >= 0;\r\n }\r\n\r\n private inferEventName() {\r\n if (this.isCommand()) return getDOM().getText(this.el) || getDOM().getValue(this.el);\r\n return getDOM().getProperty(this.el, 'id') || getDOM().getProperty(this.el, 'name') || getDOM().tagName(this.el);\r\n }*/\r\n}\r\n\r\n@NgModule({\r\n declarations: [Angulartics2On],\r\n exports: [Angulartics2On],\r\n})\r\nexport class Angulartics2OnModule {}\r\n","import { ModuleWithProviders, NgModule } from '@angular/core';\r\n\r\nimport { AngularRouterTracking } from './angular-router';\r\nimport { Angulartics2Settings } from './angulartics2-config';\r\nimport { Angulartics2 } from './angulartics2-core';\r\nimport { ANGULARTICS2_TOKEN } from './angulartics2-token';\r\nimport { Angulartics2On, Angulartics2OnModule } from './angulartics2On';\r\nimport { RouterlessTracking } from './routerless';\r\n\r\n@NgModule({\r\n imports: [Angulartics2OnModule],\r\n exports: [Angulartics2On],\r\n})\r\nexport class Angulartics2Module {\r\n static forRoot(\r\n settings: Partial<Angulartics2Settings> = {},\r\n ): ModuleWithProviders<Angulartics2Module> {\r\n return {\r\n ngModule: Angulartics2Module,\r\n providers: [\r\n { provide: ANGULARTICS2_TOKEN, useValue: { settings } },\r\n { provide: RouterlessTracking, useClass: AngularRouterTracking },\r\n Angulartics2,\r\n ],\r\n };\r\n }\r\n}\r\n","import { ModuleWithProviders, NgModule } from '@angular/core';\r\n\r\nimport {ANGULARTICS2_TOKEN} from './angulartics2-token';\r\nimport {Angulartics2Settings} from './angulartics2-config';\r\nimport {Angulartics2OnModule} from './angulartics2On';\r\nimport {Angulartics2} from './angulartics2-core';\r\nimport {RouterlessTracking} from './routerless';\r\n\r\n@NgModule({\r\n imports: [Angulartics2OnModule],\r\n})\r\nexport class Angulartics2RouterlessModule {\r\n static forRoot(\r\n settings: Partial<Angulartics2Settings> = {}\r\n ): ModuleWithProviders<Angulartics2RouterlessModule> {\r\n return {\r\n ngModule: Angulartics2RouterlessModule,\r\n providers: [\r\n { provide: ANGULARTICS2_TOKEN, useValue: { settings } },\r\n RouterlessTracking,\r\n Angulartics2,\r\n ],\r\n };\r\n }\r\n}\r\n","import { Location } from '@angular/common';\r\nimport { Injectable } from '@angular/core';\r\n\r\nimport { Angulartics2 } from '../../angulartics2-core';\r\n\r\ndeclare const s: any;\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2AdobeAnalytics {\r\n constructor(private angulartics2: Angulartics2, private location: Location) {\r\n this.angulartics2.setUserProperties.subscribe(x => this.setUserProperties(x));\r\n }\r\n\r\n startTracking(): void {\r\n this.angulartics2.pageTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.pageTrack(x.path));\r\n this.angulartics2.eventTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.eventTrack(x.action, x.properties));\r\n }\r\n\r\n pageTrack(path: string) {\r\n if (typeof s !== 'undefined' && s) {\r\n s.clearVars();\r\n s.t({ pageName: path });\r\n }\r\n }\r\n\r\n /**\r\n * Track Event in Adobe Analytics\r\n *\r\n * @param action associated with the event\r\n * @param properties action detials\r\n *\r\n * @link https://marketing.adobe.com/resources/help/en_US/sc/implement/js_implementation.html\r\n */\r\n eventTrack(action: string, properties: any) {\r\n // TODO: make interface\r\n // @property {string} properties.category\r\n // @property {string} properties.label\r\n // @property {number} properties.value\r\n // @property {boolean} properties.noninteraction\r\n if (!properties) {\r\n properties = properties || {};\r\n }\r\n\r\n if (typeof s !== 'undefined' && s) {\r\n if (typeof properties === 'object') {\r\n this.setUserProperties(properties);\r\n }\r\n if (action) {\r\n // if linkName property is passed, use that; otherwise, the action is the linkName\r\n const linkName = properties['linkName'] ? properties['linkName'] : action;\r\n // note that 'this' should refer the link element, but we can't get that in this function. example:\r\n // <a href=\"http://anothersite.com\" onclick=\"s.tl(this,'e','AnotherSite',null)\">\r\n // if disableDelay property is passed, use that to turn off/on the 500ms delay; otherwise, it uses this\r\n const disableDelay = !!properties['disableDelay'] ? true : this;\r\n // if action property is passed, use that; otherwise, the action remains unchanged\r\n if (properties['action']) {\r\n action = properties['action'];\r\n }\r\n this.setPageName();\r\n\r\n if (action.toUpperCase() === 'DOWNLOAD') {\r\n s.tl(disableDelay, 'd', linkName);\r\n } else if (action.toUpperCase() === 'EXIT') {\r\n s.tl(disableDelay, 'e', linkName);\r\n } else {\r\n s.tl(disableDelay, 'o', linkName);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private setPageName() {\r\n const path = this.location.path(true);\r\n const hashNdx = path.indexOf('#');\r\n if (hashNdx > 0 && hashNdx < path.length) {\r\n s.pageName = path.substring(hashNdx + 1);\r\n } else {\r\n s.pageName = path;\r\n }\r\n }\r\n\r\n setUserProperties(properties: any) {\r\n if (typeof s !== 'undefined' && s) {\r\n if (typeof properties === 'object') {\r\n for (const key in properties) {\r\n if (properties.hasOwnProperty(key)) {\r\n s[key] = properties[key];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Title } from '@angular/platform-browser';\r\nimport {\r\n NavigationEnd,\r\n NavigationError,\r\n NavigationStart,\r\n Router,\r\n} from '@angular/router';\r\nimport { filter } from 'rxjs/operators';\r\n\r\nimport { AppInsightsSettings } from '../../angulartics2-config';\r\nimport { Angulartics2 } from '../../angulartics2-core';\r\n\r\ndeclare const appInsights: Microsoft.ApplicationInsights.IAppInsights;\r\n\r\nexport class AppInsightsDefaults implements AppInsightsSettings {\r\n userId = null;\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2AppInsights {\r\n loadStartTime: number = null;\r\n loadTime: number = null;\r\n\r\n metrics: { [name: string]: number } = null;\r\n dimensions: { [name: string]: string } = null;\r\n measurements: { [name: string]: number } = null;\r\n\r\n constructor(\r\n private angulartics2: Angulartics2,\r\n private title: Title,\r\n private router: Router\r\n ) {\r\n if (typeof appInsights === 'undefined') {\r\n console.warn('appInsights not found');\r\n }\r\n\r\n const defaults = new AppInsightsDefaults();\r\n // Set the default settings for this module\r\n this.angulartics2.settings.appInsights = {\r\n ...defaults,\r\n ...this.angulartics2.settings.appInsights,\r\n };\r\n this.angulartics2.setUsername.subscribe((x: string) => this.setUsername(x));\r\n this.angulartics2.setUserProperties.subscribe((x) =>\r\n this.setUserProperties(x)\r\n );\r\n }\r\n\r\n startTracking(): void {\r\n this.angulartics2.pageTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe((x) => this.pageTrack(x.path));\r\n this.angulartics2.eventTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe((x) => this.eventTrack(x.action, x.properties));\r\n this.angulartics2.exceptionTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe((x) => this.exceptionTrack(x));\r\n this.router.events\r\n .pipe(\r\n this.angulartics2.filterDeveloperMode(),\r\n filter((event) => event instanceof NavigationStart)\r\n )\r\n .subscribe((event) => this.startTimer());\r\n\r\n this.router.events\r\n .pipe(\r\n filter(\r\n (event) =>\r\n event instanceof NavigationError || event instanceof NavigationEnd\r\n )\r\n )\r\n .subscribe((error) => this.stopTimer());\r\n }\r\n\r\n startTimer() {\r\n this.loadStartTime = Date.now();\r\n this.loadTime = null;\r\n }\r\n\r\n stopTimer() {\r\n this.loadTime = Date.now() - this.loadStartTime;\r\n this.loadStartTime = null;\r\n }\r\n\r\n /**\r\n * Page Track in Baidu Analytics\r\n *\r\n * @param path - Location 'path'\r\n *\r\n * @link https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#trackpageview\r\n */\r\n pageTrack(path: string) {\r\n appInsights.trackPageView(\r\n this.title.getTitle(),\r\n path,\r\n this.dimensions,\r\n this.metrics,\r\n this.loadTime\r\n );\r\n }\r\n\r\n /**\r\n * Log a user action or other occurrence.\r\n *\r\n * @param name Name to identify this event in the portal.\r\n * @param properties Additional data used to filter events and metrics in the portal. Defaults to empty.\r\n *\r\n * @link https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#trackevent\r\n */\r\n eventTrack(name: string, properties: { [name: string]: string }) {\r\n appInsights.trackEvent(name, properties, this.measurements);\r\n }\r\n\r\n /**\r\n * Exception Track Event in GA\r\n *\r\n * @param properties - Comprised of the mandatory fields 'appId' (string), 'appName' (string) and 'appVersion' (string) and\r\n * optional fields 'fatal' (boolean) and 'description' (string), error\r\n *\r\n * @link https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#trackexception\r\n */\r\n exceptionTrack(properties: any) {\r\n const description =\r\n properties.event || properties.description || properties;\r\n\r\n appInsights.trackException(description);\r\n }\r\n\r\n /**\r\n * @link https://github.com/Microsoft/ApplicationInsights-JS/blob/master/API-reference.md#setauthenticatedusercontext\r\n */\r\n setUsername(userId: string) {\r\n this.angulartics2.settings.appInsights.userId = userId;\r\n appInsights.setAuthenticatedUserContext(userId);\r\n }\r\n\r\n setUserProperties(\r\n properties: Partial<{ userId: string; accountId: string }>\r\n ) {\r\n if (properties.userId) {\r\n this.angulartics2.settings.appInsights.userId = properties.userId;\r\n }\r\n if (properties.accountId) {\r\n appInsights.setAuthenticatedUserContext(\r\n this.angulartics2.settings.appInsights.userId,\r\n properties.accountId\r\n );\r\n } else {\r\n appInsights.setAuthenticatedUserContext(\r\n this.angulartics2.settings.appInsights.userId\r\n );\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nimport { Angulartics2 } from '../../angulartics2-core';\r\n\r\n\r\ndeclare var _hmt: any;\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2BaiduAnalytics {\r\n constructor(private angulartics2: Angulartics2) {\r\n if (typeof _hmt === 'undefined') {\r\n _hmt = [];\r\n } else {\r\n _hmt.push(['_setAutoPageview', false]);\r\n }\r\n this.angulartics2.setUsername\r\n .subscribe((x: string) => this.setUsername(x));\r\n this.angulartics2.setUserProperties\r\n .subscribe((x) => this.setUserProperties(x));\r\n }\r\n\r\n startTracking(): void {\r\n this.angulartics2.pageTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe((x) => this.pageTrack(x.path));\r\n this.angulartics2.eventTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe((x) => this.eventTrack(x.action, x.properties));\r\n }\r\n\r\n /**\r\n * Page Track in Baidu Analytics\r\n *\r\n * @param path Required url 'path'\r\n *\r\n * @link http://tongji.baidu.com/open/api/more?p=ref_trackPageview\r\n */\r\n pageTrack(path: string) {\r\n if (typeof _hmt !== 'undefined' && _hmt) {\r\n _hmt.push(['_trackPageview', path]);\r\n }\r\n }\r\n\r\n /**\r\n * Track Event in Baidu Analytics\r\n *\r\n * @param action Name associated with the event\r\n * @param properties Comprised of:\r\n * - 'category' (string)\r\n * - 'opt_label' (string)\r\n * - 'opt_value' (string)\r\n *\r\n * @link http://tongji.baidu.com/open/api/more?p=ref_trackEvent\r\n */\r\n eventTrack(action: string, properties: any) {\r\n // baidu analytics requires category\r\n if (!properties || !properties.category) {\r\n properties = properties || {};\r\n properties.category = 'Event';\r\n properties.opt_label = 'default';\r\n properties.opt_value = 'default';\r\n }\r\n\r\n if (typeof _hmt !== 'undefined' && _hmt) {\r\n _hmt.push([\r\n '_trackEvent',\r\n properties.category,\r\n action,\r\n properties.opt_label,\r\n properties.opt_value,\r\n ]);\r\n }\r\n }\r\n\r\n setUsername(userId: string) {\r\n // set default custom variables name to 'identity' and 'value'\r\n _hmt.push(['_setCustomVar', 1, 'identity', userId]);\r\n }\r\n\r\n setUserProperties(properties: any) {\r\n _hmt.push(['_setCustomVar', 2, 'user', JSON.stringify(properties)]);\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nimport { Angulartics2 } from '../../angulartics2-core';\r\n\r\ndeclare const fbq: facebook.Pixel.Event;\r\n\r\nconst facebookEventList = [\r\n 'ViewContent',\r\n 'Search',\r\n 'AddToCart',\r\n 'AddToWishlist',\r\n 'InitiateCheckout',\r\n 'AddPaymentInfo',\r\n 'Purchase',\r\n 'Lead',\r\n 'CompleteRegistration',\r\n];\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2Facebook {\r\n constructor(private angulartics2: Angulartics2) { }\r\n\r\n startTracking(): void {\r\n this.angulartics2.eventTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.eventTrack(x.action, x.properties));\r\n }\r\n\r\n /**\r\n * Send interactions to the Pixel, i.e. for event tracking in Pixel\r\n *\r\n * @param action action associated with the event\r\n */\r\n eventTrack(action: string, properties: any = {}) {\r\n if (typeof fbq === 'undefined') {\r\n return;\r\n }\r\n if (facebookEventList.indexOf(action) === -1) {\r\n return fbq('trackCustom', action, properties);\r\n }\r\n return fbq('track', action, properties);\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nimport { Angulartics2 } from '../../angulartics2-core';\r\nimport { GoogleAnalyticsSettings } from '../../angulartics2-config';\r\nimport { UserTimings } from '../../angulartics2-interfaces';\r\n\r\ndeclare var _gaq: GoogleAnalyticsCode;\r\ndeclare var ga: UniversalAnalytics.ga;\r\ndeclare var location: any;\r\n\r\nexport class GoogleAnalyticsDefaults implements GoogleAnalyticsSettings {\r\n additionalAccountNames = [];\r\n userId = null;\r\n transport = '';\r\n anonymizeIp = false;\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2GoogleAnalytics {\r\n dimensionsAndMetrics = [];\r\n settings: Partial<GoogleAnalyticsSettings>;\r\n\r\n constructor(private angulartics2: Angulartics2) {\r\n const defaults = new GoogleAnalyticsDefaults();\r\n // Set the default settings for this module\r\n this.angulartics2.settings.ga = {\r\n ...defaults,\r\n ...this.angulartics2.settings.ga,\r\n };\r\n this.settings = this.angulartics2.settings.ga;\r\n this.angulartics2.setUsername.subscribe((x: string) => this.setUsername(x));\r\n this.angulartics2.setUserProperties.subscribe(x => this.setUserProperties(x));\r\n }\r\n\r\n startTracking(): void {\r\n this.angulartics2.pageTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.pageTrack(x.path));\r\n this.angulartics2.eventTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.eventTrack(x.action, x.properties));\r\n this.angulartics2.exceptionTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.exceptionTrack(x));\r\n this.angulartics2.userTimings\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.userTimings(x));\r\n }\r\n\r\n pageTrack(path: string) {\r\n if (typeof _gaq !== 'undefined' && _gaq) {\r\n _gaq.push(['_trackPageview', path]);\r\n for (const accountName of this.angulartics2.settings.ga.additionalAccountNames) {\r\n _gaq.push([accountName + '._trackPageview', path]);\r\n }\r\n }\r\n if (typeof ga !== 'undefined' && ga) {\r\n if (this.angulartics2.settings.ga.userId) {\r\n ga('set', '&uid', this.angulartics2.settings.ga.userId);\r\n for (const accountName of this.angulartics2.settings.ga.additionalAccountNames) {\r\n ga(accountName + '.set', '&uid', this.angulartics2.settings.ga.userId);\r\n }\r\n }\r\n if (this.angulartics2.settings.ga.anonymizeIp) {\r\n ga('set', 'anonymizeIp', true);\r\n for (const accountName of this.angulartics2.settings.ga.additionalAccountNames) {\r\n ga(accountName + '.set', 'anonymizeIp', true);\r\n }\r\n }\r\n ga('send', 'pageview', path);\r\n for (const accountName of this.angulartics2.settings.ga.additionalAccountNames) {\r\n ga(accountName + '.send', 'pageview', path);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Track Event in GA\r\n *\r\n * @param action Associated with the event\r\n * @param properties Comprised of:\r\n * - category (string) and optional\r\n * - label (string)\r\n * - value (integer)\r\n * - noninteraction (boolean)\r\n *\r\n * @link https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide#SettingUpEventTracking\r\n * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/events\r\n */\r\n eventTrack(action: string, properties: any) {\r\n // Google Analytics requires an Event Category\r\n if (!properties || !properties.category) {\r\n properties = properties || {};\r\n properties.category = 'Event';\r\n }\r\n // GA requires that eventValue be an integer, see:\r\n // https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#eventValue\r\n // https://github.com/luisfarzati/angulartics/issues/81\r\n if (properties.value) {\r\n const parsed = parseInt(properties.value, 10);\r\n properties.value = isNaN(parsed) ? 0 : parsed;\r\n }\r\n\r\n if (typeof ga !== 'undefined') {\r\n const eventOptions = {\r\n eventCategory: properties.category,\r\n eventAction: action,\r\n eventLabel: properties.label,\r\n eventValue: properties.value,\r\n nonInteraction: properties.noninteraction,\r\n page: properties.page || location.hash.substring(1) || location.pathname,\r\n userId: this.angulartics2.settings.ga.userId,\r\n hitCallback: properties.hitCallback,\r\n ...(this.angulartics2.settings.ga.transport && {\r\n transport: this.angulartics2.settings.ga.transport,\r\n }),\r\n };\r\n\r\n // add custom dimensions and metrics\r\n this.setDimensionsAndMetrics(properties);\r\n\r\n ga('send', 'event', eventOptions);\r\n\r\n for (const accountName of this.angulartics2.settings.ga.additionalAccountNames) {\r\n ga(accountName + '.send', 'event', eventOptions);\r\n }\r\n } else if (typeof _gaq !== 'undefined') {\r\n _gaq.push([\r\n '_trackEvent',\r\n properties.category,\r\n action,\r\n properties.label,\r\n properties.value,\r\n properties.noninteraction,\r\n ]);\r\n }\r\n }\r\n\r\n /**\r\n * Exception Track Event in GA\r\n *\r\n * @param properties Comprised of the optional fields:\r\n * - fatal (string)\r\n * - description (string)\r\n *\r\n * @https://developers.google.com/analytics/devguides/collection/analyticsjs/exceptions\r\n *\r\n * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/events\r\n */\r\n exceptionTrack(properties: any) {\r\n if (properties.fatal === undefined) {\r\n console.log('No \"fatal\" provided, sending with fatal=true');\r\n properties.fatal = true;\r\n }\r\n\r\n properties.exDescription = properties.description;\r\n\r\n const eventOptions = {\r\n exFatal: properties.fatal,\r\n exDescription: properties.description,\r\n };\r\n\r\n ga('send', 'exception', eventOptions);\r\n for (const accountName of this.angulartics2.settings.ga.additionalAccountNames) {\r\n ga(accountName + '.send', 'exception', eventOptions);\r\n }\r\n }\r\n\r\n /**\r\n * User Timings Event in GA\r\n *\r\n * @param properties Comprised of the mandatory fields:\r\n * - timingCategory (string)\r\n * - timingVar (string)\r\n * - timingValue (number)\r\n * Properties can also have the optional fields:\r\n * - timingLabel (string)\r\n *\r\n * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings\r\n */\r\n userTimings(properties: UserTimings) {\r\n if (\r\n !properties ||\r\n !properties.timingCategory ||\r\n !properties.timingVar ||\r\n !properties.timingValue\r\n ) {\r\n console.error(\r\n 'Properties timingCategory, timingVar, and timingValue are required to be set.',\r\n );\r\n return;\r\n }\r\n\r\n if (typeof ga !== 'undefined') {\r\n ga('send', 'timing', properties);\r\n for (const accountName of this.angulartics2.settings.ga.additionalAccountNames) {\r\n ga(accountName + '.send', 'timing', properties);\r\n }\r\n }\r\n }\r\n\r\n setUsername(userId: string) {\r\n this.angulartics2.settings.ga.userId = userId;\r\n if (typeof ga === 'undefined') {\r\n return;\r\n }\r\n ga('set', 'userId', userId);\r\n }\r\n\r\n setUserProperties(properties: any) {\r\n this.setDimensionsAndMetrics(properties);\r\n }\r\n\r\n private setDimensionsAndMetrics(properties: any) {\r\n if (typeof ga === 'undefined') {\r\n return;\r\n }\r\n // clean previously used dimensions and metrics that will not be overriden\r\n this.dimensionsAndMetrics.forEach(elem => {\r\n if (!properties.hasOwnProperty(elem)) {\r\n ga('set', elem, undefined);\r\n\r\n this.angulartics2.settings.ga.additionalAccountNames.forEach((accountName: string) => {\r\n ga(`${accountName}.set`, elem, undefined);\r\n });\r\n }\r\n });\r\n this.dimensionsAndMetrics = [];\r\n\r\n // add custom dimensions and metrics\r\n Object.keys(properties).forEach(key => {\r\n if (key.lastIndexOf('dimension', 0) === 0 || key.lastIndexOf('metric', 0) === 0) {\r\n ga('set', key, properties[key]);\r\n\r\n this.angulartics2.settings.ga.additionalAccountNames.forEach((accountName: string) => {\r\n ga(`${accountName}.set`, key, properties[key]);\r\n });\r\n this.dimensionsAndMetrics.push(key);\r\n }\r\n });\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport {\r\n GaEnhancedEcomAction,\r\n GaEnhancedEcomActionFieldObject,\r\n GaEnhancedEcomImpressionFieldObject,\r\n GaEnhancedEcomProductFieldObject,\r\n} from './ga-enhanced-ecom-options';\r\n\r\ndeclare var ga: UniversalAnalytics.ga;\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2GoogleAnalyticsEnhancedEcommerce {\r\n /**\r\n * Add impression in GA enhanced ecommerce tracking\r\n * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-activities\r\n */\r\n ecAddImpression(properties: Partial<GaEnhancedEcomImpressionFieldObject>) {\r\n ga('ec:addImpression', properties);\r\n }\r\n\r\n /**\r\n * Add product in GA enhanced ecommerce tracking\r\n * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce\r\n */\r\n ecAddProduct(product: Partial<GaEnhancedEcomProductFieldObject>) {\r\n ga('ec:addProduct', product);\r\n }\r\n\r\n /**\r\n * Set action in GA enhanced ecommerce tracking\r\n * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce\r\n */\r\n ecSetAction(\r\n action: GaEnhancedEcomAction,\r\n properties: Partial<GaEnhancedEcomActionFieldObject>\r\n ) {\r\n ga('ec:setAction', action, properties);\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nimport { Angulartics2 } from '../../angulartics2-core';\r\nimport { GoogleTagManagerSettings } from '../../angulartics2-config';\r\n\r\ndeclare var dataLayer: any;\r\n\r\nexport class GoogleTagManagerDefaults implements GoogleTagManagerSettings {\r\n userId = null;\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2GoogleTagManager {\r\n constructor(protected angulartics2: Angulartics2) {\r\n // The dataLayer needs to be initialized\r\n if (typeof dataLayer !== 'undefined' && dataLayer) {\r\n dataLayer = (window as any).dataLayer = (window as any).dataLayer || [];\r\n }\r\n const defaults = new GoogleTagManagerDefaults();\r\n // Set the default settings for this module\r\n this.angulartics2.settings.gtm = { ...defaults, ...this.angulartics2.settings.gtm };\r\n this.angulartics2.setUsername.subscribe((x: string) => this.setUsername(x));\r\n }\r\n\r\n startTracking() {\r\n this.angulartics2.pageTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.pageTrack(x.path));\r\n this.angulartics2.eventTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.eventTrack(x.action, x.properties));\r\n this.angulartics2.exceptionTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe((x: any) => this.exceptionTrack(x));\r\n }\r\n\r\n pageTrack(path: string) {\r\n this.pushLayer({\r\n event: 'Page View',\r\n 'content-name': path,\r\n userId: this.angulartics2.settings.gtm.userId,\r\n });\r\n }\r\n\r\n /**\r\n * Send Data Layer\r\n *\r\n * @layer data layer object\r\n */\r\n pushLayer(layer: any) {\r\n if (typeof dataLayer !== 'undefined' && dataLayer) {\r\n dataLayer.push(layer);\r\n }\r\n }\r\n\r\n /**\r\n * Send interactions to the dataLayer, i.e. for event tracking in Google Analytics\r\n *\r\n * @param action associated with the event\r\n */\r\n eventTrack(action: string, properties: any) {\r\n // TODO: make interface\r\n // @param {string} properties.category\r\n // @param {string} [properties.label]\r\n // @param {number} [properties.value]\r\n // @param {boolean} [properties.noninteraction]\r\n // Set a default GTM category\r\n properties = properties || {};\r\n\r\n this.pushLayer({\r\n event: properties.event || 'interaction',\r\n target: properties.category || 'Event',\r\n action,\r\n label: properties.label,\r\n value: properties.value,\r\n interactionType: properties.noninteraction,\r\n userId: this.angulartics2.settings.gtm.userId,\r\n ...properties.gtmCustom,\r\n });\r\n }\r\n\r\n /**\r\n * Exception Track Event in GTM\r\n *\r\n */\r\n exceptionTrack(properties: any) {\r\n // TODO: make interface\r\n // @param {Object} properties\r\n // @param {string} properties.appId\r\n // @param {string} properties.appName\r\n // @param {string} properties.appVersion\r\n // @param {string} [properties.description]\r\n // @param {boolean} [properties.fatal]\r\n if (!properties || !properties.appId || !properties.appName || !properties.appVersion) {\r\n console.error('Must be setted appId, appName and appVersion.');\r\n return;\r\n }\r\n\r\n if (properties.fatal === undefined) {\r\n console.log('No \"fatal\" provided, sending with fatal=true');\r\n properties.exFatal = true;\r\n }\r\n\r\n properties.exDescription = properties.event ? properties.event.stack : properties.description;\r\n\r\n this.eventTrack(\r\n `Exception thrown for ${properties.appName} <${properties.appId}@${properties.appVersion}>`,\r\n {\r\n category: 'Exception',\r\n label: properties.exDescription,\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * Set userId for use with Universal Analytics User ID feature\r\n *\r\n * @param userId used to identify user cross-device in Google Analytics\r\n */\r\n setUsername(userId: string) {\r\n this.angulartics2.settings.gtm.userId = userId;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nimport { UserTimings } from '../../angulartics2-interfaces';\r\nimport { GoogleGlobalSiteTagSettings } from '../../angulartics2-config';\r\nimport { Angulartics2 } from '../../angulartics2-core';\r\nimport { EventGst, UserTimingsGst } from './gst-interfaces';\r\n\r\ndeclare var gtag: any;\r\ndeclare var ga: any;\r\n\r\nexport class GoogleGlobalSiteTagDefaults implements GoogleGlobalSiteTagSettings {\r\n trackingIds: string[] = [];\r\n\r\n constructor() {\r\n if (typeof ga !== 'undefined' && ga) {\r\n // See: https://developers.google.com/analytics/devguides/collection/analyticsjs/ga-object-methods-reference\r\n ga(() => {\r\n ga.getAll().forEach((tracker: any) => {\r\n const id = tracker.get('trackingId');\r\n // If set both in forRoot and HTML page, we want to avoid duplicates\r\n if (id !== undefined && this.trackingIds.indexOf(id) === -1) {\r\n this.trackingIds.push(id);\r\n }\r\n });\r\n });\r\n }\r\n }\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2GoogleGlobalSiteTag {\r\n private dimensionsAndMetrics: { [key: string]: any } = {};\r\n\r\n constructor(protected angulartics2: Angulartics2) {\r\n const defaults = new GoogleGlobalSiteTagDefaults();\r\n // Set the default settings for this module\r\n this.angulartics2.settings.gst = { ...defaults, ...this.angulartics2.settings.gst };\r\n }\r\n\r\n startTracking(): void {\r\n this.angulartics2.pageTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.pageTrack(x.path));\r\n this.angulartics2.eventTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.eventTrack(x.action, x.properties));\r\n this.angulartics2.exceptionTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe((x: any) => this.exceptionTrack(x));\r\n this.angulartics2.userTimings\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.userTimings(this.convertTimings(x)));\r\n this.angulartics2.setUsername\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe((x: string) => this.setUsername(x));\r\n this.angulartics2.setUserProperties\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe((x: any) => this.setUserProperties(x));\r\n }\r\n\r\n /**\r\n * Manually track page view, see:\r\n *\r\n * https://developers.google.com/analytics/devguides/collection/gtagjs/single-page-applications#tracking_virtual_pageviews\r\n *\r\n * @param path relative url\r\n */\r\n pageTrack(path: string) {\r\n if (typeof gtag !== 'undefined' && gtag) {\r\n const params: any = {\r\n page_path: path,\r\n page_location: window.location.protocol + '//' + window.location.host + path,\r\n ...this.dimensionsAndMetrics,\r\n };\r\n\r\n // Custom map must be reset with all config to stay valid.\r\n\r\n if (this.angulartics2.settings.gst.customMap) {\r\n params.custom_map = this.angulartics2.settings.gst.customMap;\r\n }\r\n if (this.angulartics2.settings.gst.userId) {\r\n params.user_id = this.angulartics2.settings.gst.userId;\r\n }\r\n if (this.angulartics2.settings.gst.anonymizeIp) {\r\n params.anonymize_ip = this.angulartics2.settings.gst.anonymizeIp;\r\n }\r\n\r\n for (const id of this.angulartics2.settings.gst.trackingIds) {\r\n gtag('config', id, params);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Send interactions to gtag, i.e. for event tracking in Google Analytics. See:\r\n *\r\n * https://developers.google.com/analytics/devguides/collection/gtagjs/events\r\n *\r\n * @param action associated with the event\r\n */\r\n eventTrack(action: string, properties: Partial<EventGst> = {}) {\r\n this.eventTrackInternal(action, {\r\n event_category: properties.category || 'interaction',\r\n event_label: properties.label,\r\n value: properties.value,\r\n non_interaction: properties.noninteraction,\r\n ...properties.gstCustom,\r\n });\r\n }\r\n\r\n /**\r\n * Exception Track Event in GST. See:\r\n *\r\n * https://developers.google.com/analytics/devguides/collection/gtagjs/exceptions\r\n *\r\n */\r\n exceptionTrack(properties: any) {\r\n // TODO: make interface\r\n // @param {Object} properties\r\n // @param {string} [properties.description]\r\n // @param {boolean} [properties.fatal]\r\n if (properties.fatal === undefined) {\r\n console.log('No \"fatal\" provided, sending with fatal=true');\r\n properties.fatal = true;\r\n }\r\n\r\n properties.exDescription = properties.event ? properties.event.stack : properties.description;\r\n\r\n this.eventTrack('exception', {\r\n gstCustom: {\r\n description: properties.exDescription,\r\n fatal: properties.fatal,\r\n ...properties.gstCustom,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * User Timings Event in GST.\r\n *\r\n * @param properties Comprised of the mandatory fields:\r\n * - name (string)\r\n * - value (number - integer)\r\n * Properties can also have the optional fields:\r\n * - category (string)\r\n * - label (string)\r\n *\r\n * @link https://developers.google.com/analytics/devguides/collection/gtagjs/user-timings\r\n */\r\n userTimings(properties: UserTimingsGst) {\r\n if (!properties) {\r\n console.error('User timings - \"properties\" parameter is required to be set.');\r\n return;\r\n }\r\n\r\n this.eventTrackInternal('timing_complete', {\r\n name: properties.name,\r\n value: properties.value,\r\n event_category: properties.category,\r\n event_label: properties.label,\r\n });\r\n }\r\n\r\n private convertTimings(properties: UserTimings): UserTimingsGst {\r\n return {\r\n name: properties.timingVar,\r\n value: properties.timingValue,\r\n category: properties.timingCategory,\r\n label: properties.timingLabel,\r\n };\r\n }\r\n\r\n setUsername(userId: string | { userId: string | number }) {\r\n this.angulartics2.settings.gst.userId = userId;\r\n if (typeof gtag !== 'undefined' && gtag) {\r\n gtag('set', { user_id: typeof userId === 'string' || !userId ? userId : userId.userId });\r\n }\r\n }\r\n\r\n setUserProperties(properties: any) {\r\n this.setDimensionsAndMetrics(properties);\r\n }\r\n\r\n private setDimensionsAndMetrics(properties: { [key: string]: any }) {\r\n // We want the dimensions and metrics to accumulate, so we merge with previous value\r\n this.dimensionsAndMetrics = {\r\n ...this.dimensionsAndMetrics,\r\n ...properties,\r\n };\r\n\r\n // Remove properties that are null or undefined\r\n Object.keys(this.dimensionsAndMetrics).forEach(key => {\r\n const val = this.dimensionsAndMetrics[key];\r\n if (val === undefined || val === null) {\r\n delete this.dimensionsAndMetrics[key];\r\n }\r\n });\r\n\r\n if (typeof gtag !== 'undefined' && gtag) {\r\n gtag('set', this.dimensionsAndMetrics);\r\n }\r\n }\r\n\r\n private eventTrackInternal(action: string, properties: any = {}) {\r\n this.cleanProperties(properties);\r\n if (typeof gtag !== 'undefined' && gtag) {\r\n gtag('event', action, properties);\r\n }\r\n }\r\n\r\n private cleanProperties(properties: { [key: string]: any }): void {\r\n // GA requires that eventValue be an non-negative integer, see:\r\n // https://developers.google.com/analytics/devguides/collection/gtagjs/events\r\n if (properties.value) {\r\n const parsed = parseInt(properties.value, 10);\r\n properties.value = isNaN(parsed) ? 0 : parsed;\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nimport { Angulartics2 } from '../../angulartics2-core';\r\n\r\ndeclare var _hsq: any;\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2Hubspot {\r\n constructor(private angulartics2: Angulartics2) {\r\n this.angulartics2.setUserProperties.subscribe(x => this.setUserProperties(x));\r\n }\r\n\r\n startTracking(): void {\r\n this.angulartics2.pageTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.pageTrack(x.path));\r\n this.angulartics2.eventTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.eventTrack(x.action, x.properties));\r\n }\r\n\r\n pageTrack(path: string) {\r\n if (typeof _hsq !== 'undefined') {\r\n _hsq.push(['setPath', path]);\r\n _hsq.push(['trackPageView']);\r\n }\r\n }\r\n\r\n eventTrack(action: string, properties: any) {\r\n if (typeof _hsq !== 'undefined') {\r\n _hsq.push(['trackEvent', properties]);\r\n }\r\n }\r\n\r\n setUserProperties(properties: any) {\r\n if (typeof _hsq !== 'undefined') {\r\n _hsq.push(['identify', properties]);\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\n\r\nimport { Angulartics2 } from '../../angulartics2-core';\r\n\r\ndeclare var _kmq: any;\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class Angulartics2Kissmetrics {\r\n constructor(private angulartics2: Angulartics2) {\r\n if (typeof _kmq === 'undefined') {\r\n _kmq = [];\r\n }\r\n this.angulartics2.setUsername.subscribe((x: string) => this.setUsername(x));\r\n this.angulartics2.setUserProperties.subscribe(x => this.setUserProperties(x));\r\n }\r\n\r\n startTracking(): void {\r\n this.angulartics2.pageTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.pageTrack(x.path));\r\n this.angulartics2.eventTrack\r\n .pipe(this.angulartics2.filterDeveloperMode())\r\n .subscribe(x => this.eventTrack(x.action, x.properties));\r\n }\r\n\r\n pageTrack(path: string) {\r\n _kmq.push(['record', 'Pageview', { Page: path }]);\r\n }\r\n\r\n eventTrack(action: s