diff --git a/app/index.tsx b/app/index.tsx index b9ca18abe8..f8104b3d36 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -98,8 +98,7 @@ window.addEventListener("load", async () => { if (!env.GOOGLE_ANALYTICS_ID || !window.ga) { return; } - // https://github.com/googleanalytics/autotrack/issues/137#issuecomment-305890099 - await import("autotrack/autotrack.js"); + await import("~/utils/autotrack"); window.ga("require", "outboundLinkTracker"); window.ga("require", "urlChangeTracker"); window.ga("require", "eventTracker", { diff --git a/app/typings/index.d.ts b/app/typings/index.d.ts index 3f5be08988..38a24f9b2a 100644 --- a/app/typings/index.d.ts +++ b/app/typings/index.d.ts @@ -1,4 +1,4 @@ -declare module "autotrack/autotrack.js"; +declare module "~/utils/autotrack"; declare module "emoji-mart"; diff --git a/app/utils/autotrack.js b/app/utils/autotrack.js new file mode 100644 index 0000000000..6f62ac1ccd --- /dev/null +++ b/app/utils/autotrack.js @@ -0,0 +1,707 @@ +/** + * Vendored from https://github.com/googleanalytics/autotrack (v2.4.1) + * and its dependency https://github.com/philipwalton/dom-utils (v0.9.0) + * + * Copyright 2016 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 + * + * Only the three plugins used by Outline are included: + * - eventTracker + * - outboundLinkTracker + * - urlChangeTracker + * + * The original libraries are no longer maintained. + */ + +/* eslint-disable */ + +// --------------------------------------------------------------------------- +// dom-utils: matches +// --------------------------------------------------------------------------- + +const nativeMatches = + Element.prototype.matches || Element.prototype.webkitMatchesSelector; + +function matchesSelector(element, selector) { + if (typeof selector != "string") { + return false; + } + if (nativeMatches) { + return nativeMatches.call(element, selector); + } + const nodes = element.parentNode.querySelectorAll(selector); + for (let i = 0, node; (node = nodes[i]); i++) { + if (node == element) { + return true; + } + } + return false; +} + +function matches(element, test) { + if (element && element.nodeType == 1 && test) { + if (typeof test == "string" || test.nodeType == 1) { + return element == test || matchesSelector(element, test); + } else if ("length" in test) { + for (let i = 0, item; (item = test[i]); i++) { + if (element == item || matchesSelector(element, item)) { + return true; + } + } + } + } + return false; +} + +// --------------------------------------------------------------------------- +// dom-utils: parents +// --------------------------------------------------------------------------- + +function parents(element) { + const list = []; + while (element && element.parentNode && element.parentNode.nodeType == 1) { + element = element.parentNode; + list.push(element); + } + return list; +} + +// --------------------------------------------------------------------------- +// dom-utils: closest +// --------------------------------------------------------------------------- + +function closest(element, selector, shouldCheckSelf = false) { + if (!(element && element.nodeType == 1 && selector)) { + return; + } + const parentElements = (shouldCheckSelf ? [element] : []).concat( + parents(element) + ); + for (let i = 0, parent; (parent = parentElements[i]); i++) { + if (matches(parent, selector)) { + return parent; + } + } +} + +// --------------------------------------------------------------------------- +// dom-utils: delegate +// --------------------------------------------------------------------------- + +function delegate(ancestor, eventType, selector, callback, opts = {}) { + const listener = function (event) { + let delegateTarget; + + if (opts.composed && typeof event.composedPath == "function") { + const composedPath = event.composedPath(); + for (let i = 0, node; (node = composedPath[i]); i++) { + if (node.nodeType == 1 && matches(node, selector)) { + delegateTarget = node; + } + } + } else { + delegateTarget = closest(event.target, selector, true); + } + + if (delegateTarget) { + callback.call(delegateTarget, event, delegateTarget); + } + }; + + ancestor.addEventListener(eventType, listener, opts.useCapture); + + return { + destroy() { + ancestor.removeEventListener(eventType, listener, opts.useCapture); + }, + }; +} + +// --------------------------------------------------------------------------- +// dom-utils: parseUrl +// --------------------------------------------------------------------------- + +const HTTP_PORT = "80"; +const HTTPS_PORT = "443"; +const DEFAULT_PORT = RegExp(":(" + HTTP_PORT + "|" + HTTPS_PORT + ")$"); + +const anchor = document.createElement("a"); +const urlCache = {}; + +function parseUrl(url) { + url = !url || url == "." ? location.href : url; + + if (urlCache[url]) { + return urlCache[url]; + } + + anchor.href = url; + + if (url.charAt(0) == "." || url.charAt(0) == "/") { + return parseUrl(anchor.href); + } + + let port = + anchor.port == HTTP_PORT || anchor.port == HTTPS_PORT ? "" : anchor.port; + port = port == "0" ? "" : port; + + const host = anchor.host.replace(DEFAULT_PORT, ""); + const origin = anchor.origin ? anchor.origin : anchor.protocol + "//" + host; + const pathname = + anchor.pathname.charAt(0) == "/" ? anchor.pathname : "/" + anchor.pathname; + + return (urlCache[url] = { + hash: anchor.hash, + host, + hostname: anchor.hostname, + href: anchor.href, + origin, + pathname, + port, + protocol: anchor.protocol, + search: anchor.search, + }); +} + +// --------------------------------------------------------------------------- +// dom-utils: getAttributes +// --------------------------------------------------------------------------- + +function getAttributes(element) { + const attrs = {}; + if (!(element && element.nodeType == 1)) { + return attrs; + } + const map = element.attributes; + if (map.length === 0) { + return {}; + } + for (let i = 0, attr; (attr = map[i]); i++) { + attrs[attr.name] = attr.value; + } + return attrs; +} + +// --------------------------------------------------------------------------- +// autotrack: utilities +// --------------------------------------------------------------------------- + +function camelCase(str) { + return str.replace(/[-_]+(\w?)/g, function (_match, p1) { + return p1.toUpperCase(); + }); +} + +function capitalize(str) { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +function createFieldsObj( + defaultFields, + userFields, + tracker, + hitFilter, + target, + event +) { + if (typeof hitFilter == "function") { + const originalBuildHitTask = tracker.get("buildHitTask"); + return { + buildHitTask: (model) => { + model.set(defaultFields, null, true); + model.set(userFields, null, true); + hitFilter(model, target, event); + originalBuildHitTask(model); + }, + }; + } else { + return Object.assign({}, defaultFields, userFields); + } +} + +function getAttributeFields(element, prefix) { + const attributes = getAttributes(element); + const attributeFields = {}; + + Object.keys(attributes).forEach(function (attribute) { + if (attribute.indexOf(prefix) === 0 && attribute != prefix + "on") { + let value = attributes[attribute]; + if (value == "true") { + value = true; + } + if (value == "false") { + value = false; + } + const field = camelCase(attribute.slice(prefix.length)); + attributeFields[field] = value; + } + }); + + return attributeFields; +} + +function withTimeout(callback, wait = 2000) { + let called = false; + const fn = function () { + if (!called) { + called = true; + callback(); + } + }; + setTimeout(fn, wait); + return fn; +} + +// --------------------------------------------------------------------------- +// autotrack: method-chain +// --------------------------------------------------------------------------- + +const methodChainInstances = []; + +function getOrCreateMethodChain(context, methodName) { + let chain = methodChainInstances.filter( + (h) => h.context == context && h.methodName == methodName + )[0]; + + if (!chain) { + chain = createMethodChain(context, methodName); + methodChainInstances.push(chain); + } + return chain; +} + +function createMethodChain(context, methodName) { + const isTask = /Task$/.test(methodName); + const originalMethodReference = isTask + ? context.get(methodName) + : context[methodName]; + + const instance = { + context, + methodName, + isTask, + originalMethodReference, + methodChain: [], + boundMethodChain: [], + wrappedMethod(...args) { + const lastBoundMethod = + instance.boundMethodChain[instance.boundMethodChain.length - 1]; + return lastBoundMethod(...args); + }, + add(overrideMethod) { + this.methodChain.push(overrideMethod); + this.rebindMethodChain(); + }, + remove(overrideMethod) { + const index = this.methodChain.indexOf(overrideMethod); + if (index > -1) { + this.methodChain.splice(index, 1); + if (this.methodChain.length > 0) { + this.rebindMethodChain(); + } else { + this.destroy(); + } + } + }, + rebindMethodChain() { + this.boundMethodChain = []; + for (let method, i = 0; (method = this.methodChain[i]); i++) { + const previousMethod = + this.boundMethodChain[i - 1] || + this.originalMethodReference.bind(this.context); + this.boundMethodChain.push(method(previousMethod)); + } + }, + destroy() { + const index = methodChainInstances.indexOf(this); + if (index > -1) { + methodChainInstances.splice(index, 1); + if (this.isTask) { + this.context.set(this.methodName, this.originalMethodReference); + } else { + this.context[this.methodName] = this.originalMethodReference; + } + } + }, + }; + + if (isTask) { + context.set(methodName, instance.wrappedMethod); + } else { + context[methodName] = instance.wrappedMethod; + } + + return instance; +} + +const MethodChain = { + add(context, methodName, methodOverride) { + getOrCreateMethodChain(context, methodName).add(methodOverride); + }, + remove(context, methodName, methodOverride) { + getOrCreateMethodChain(context, methodName).remove(methodOverride); + }, +}; + +// --------------------------------------------------------------------------- +// autotrack: usage tracking +// --------------------------------------------------------------------------- + +const VERSION = "2.4.1"; +const DEV_ID = "i5iSjo"; +const VERSION_PARAM = "_av"; +const USAGE_PARAM = "_au"; + +const pluginIds = { + EVENT_TRACKER: 2, + OUTBOUND_LINK_TRACKER: 6, + URL_CHANGE_TRACKER: 9, +}; + +const PLUGIN_COUNT = 10; + +function convertHexToBin(hex) { + return parseInt(hex || "0", 16).toString(2); +} + +function convertBinToHex(bin) { + return parseInt(bin || "0", 2).toString(16); +} + +function padZeros(str, len) { + while (str.length < len) { + str = "0" + str; + } + return str; +} + +function flipBitOn(str, index) { + return str.substr(0, index) + 1 + str.substr(index + 1); +} + +function trackPlugin(tracker, pluginIndex) { + const usageHex = tracker.get("&" + USAGE_PARAM); + let usageBin = padZeros(convertHexToBin(usageHex), PLUGIN_COUNT); + usageBin = flipBitOn(usageBin, PLUGIN_COUNT - pluginIndex); + tracker.set("&" + USAGE_PARAM, convertBinToHex(usageBin)); +} + +function trackVersion(tracker) { + tracker.set("&" + VERSION_PARAM, VERSION); +} + +function trackUsage(tracker, plugin) { + trackVersion(tracker); + trackPlugin(tracker, plugin); +} + +// --------------------------------------------------------------------------- +// autotrack: provide (plugin registration) +// --------------------------------------------------------------------------- + +function provide(pluginName, pluginConstructor) { + const gaAlias = window.GoogleAnalyticsObject || "ga"; + window[gaAlias] = + window[gaAlias] || + function (...args) { + (window[gaAlias].q = window[gaAlias].q || []).push(args); + }; + + window.gaDevIds = window.gaDevIds || []; + if (window.gaDevIds.indexOf(DEV_ID) < 0) { + window.gaDevIds.push(DEV_ID); + } + + window[gaAlias]("provide", pluginName, pluginConstructor); + + window.gaplugins = window.gaplugins || {}; + window.gaplugins[capitalize(pluginName)] = pluginConstructor; +} + +// --------------------------------------------------------------------------- +// Plugin: eventTracker +// --------------------------------------------------------------------------- + +class EventTracker { + constructor(tracker, opts) { + trackUsage(tracker, pluginIds.EVENT_TRACKER); + + if (!window.addEventListener) { + return; + } + + const defaultOpts = { + events: ["click"], + fieldsObj: {}, + attributePrefix: "ga-", + }; + + this.opts = Object.assign(defaultOpts, opts); + this.tracker = tracker; + this.handleEvents = this.handleEvents.bind(this); + + const selector = "[" + this.opts.attributePrefix + "on]"; + + this.delegates = {}; + this.opts.events.forEach((event) => { + this.delegates[event] = delegate( + document, + event, + selector, + this.handleEvents, + { composed: true, useCapture: true } + ); + }); + } + + handleEvents(event, element) { + const prefix = this.opts.attributePrefix; + const events = element.getAttribute(prefix + "on").split(/\s*,\s*/); + + if (events.indexOf(event.type) < 0) { + return; + } + + const defaultFields = { transport: "beacon" }; + const attributeFields = getAttributeFields(element, prefix); + const userFields = Object.assign({}, this.opts.fieldsObj, attributeFields); + const hitType = attributeFields.hitType || "event"; + + this.tracker.send( + hitType, + createFieldsObj( + defaultFields, + userFields, + this.tracker, + this.opts.hitFilter, + element, + event + ) + ); + } + + remove() { + Object.keys(this.delegates).forEach((key) => { + this.delegates[key].destroy(); + }); + } +} + +provide("eventTracker", EventTracker); + +// --------------------------------------------------------------------------- +// Plugin: outboundLinkTracker +// --------------------------------------------------------------------------- + +function linkClickWillUnloadCurrentPage(event, link) { + return !( + event.type != "click" || + link.target == "_blank" || + event.metaKey || + event.ctrlKey || + event.shiftKey || + event.altKey || + event.which > 1 + ); +} + +class OutboundLinkTracker { + constructor(tracker, opts) { + trackUsage(tracker, pluginIds.OUTBOUND_LINK_TRACKER); + + if (!window.addEventListener) { + return; + } + + const defaultOpts = { + events: ["click"], + linkSelector: "a, area", + shouldTrackOutboundLink: this.shouldTrackOutboundLink, + fieldsObj: {}, + attributePrefix: "ga-", + }; + + this.opts = Object.assign(defaultOpts, opts); + this.tracker = tracker; + this.handleLinkInteractions = this.handleLinkInteractions.bind(this); + + this.delegates = {}; + this.opts.events.forEach((event) => { + this.delegates[event] = delegate( + document, + event, + this.opts.linkSelector, + this.handleLinkInteractions, + { composed: true, useCapture: true } + ); + }); + } + + handleLinkInteractions(event, link) { + if (this.opts.shouldTrackOutboundLink(link, parseUrl)) { + const href = link.getAttribute("href") || link.getAttribute("xlink:href"); + const url = parseUrl(href); + + const defaultFields = { + transport: "beacon", + eventCategory: "Outbound Link", + eventAction: event.type, + eventLabel: url.href, + }; + + const userFields = Object.assign( + {}, + this.opts.fieldsObj, + getAttributeFields(link, this.opts.attributePrefix) + ); + + const fieldsObj = createFieldsObj( + defaultFields, + userFields, + this.tracker, + this.opts.hitFilter, + link, + event + ); + + if ( + !navigator.sendBeacon && + linkClickWillUnloadCurrentPage(event, link) + ) { + const clickHandler = () => { + window.removeEventListener("click", clickHandler); + + if (!event.defaultPrevented) { + event.preventDefault(); + + const oldHitCallback = fieldsObj.hitCallback; + fieldsObj.hitCallback = withTimeout(function () { + if (typeof oldHitCallback == "function") { + oldHitCallback(); + } + location.href = href; + }); + } + this.tracker.send("event", fieldsObj); + }; + window.addEventListener("click", clickHandler); + } else { + this.tracker.send("event", fieldsObj); + } + } + } + + shouldTrackOutboundLink(link, parseUrlFn) { + const href = link.getAttribute("href") || link.getAttribute("xlink:href"); + const url = parseUrlFn(href); + return ( + url.hostname != location.hostname && url.protocol.slice(0, 4) == "http" + ); + } + + remove() { + Object.keys(this.delegates).forEach((key) => { + this.delegates[key].destroy(); + }); + } +} + +provide("outboundLinkTracker", OutboundLinkTracker); + +// --------------------------------------------------------------------------- +// Plugin: urlChangeTracker +// --------------------------------------------------------------------------- + +function getPath() { + return location.pathname + location.search; +} + +class UrlChangeTracker { + constructor(tracker, opts) { + trackUsage(tracker, pluginIds.URL_CHANGE_TRACKER); + + if (!history.pushState || !window.addEventListener) { + return; + } + + const defaultOpts = { + shouldTrackUrlChange: this.shouldTrackUrlChange, + trackReplaceState: false, + fieldsObj: {}, + hitFilter: null, + }; + + this.opts = Object.assign(defaultOpts, opts); + this.tracker = tracker; + this.path = getPath(); + + this.pushStateOverride = this.pushStateOverride.bind(this); + this.replaceStateOverride = this.replaceStateOverride.bind(this); + this.handlePopState = this.handlePopState.bind(this); + + MethodChain.add(history, "pushState", this.pushStateOverride); + MethodChain.add(history, "replaceState", this.replaceStateOverride); + window.addEventListener("popstate", this.handlePopState); + } + + pushStateOverride(originalMethod) { + return (...args) => { + originalMethod(...args); + this.handleUrlChange(true); + }; + } + + replaceStateOverride(originalMethod) { + return (...args) => { + originalMethod(...args); + this.handleUrlChange(false); + }; + } + + handlePopState() { + this.handleUrlChange(true); + } + + handleUrlChange(historyDidUpdate) { + setTimeout(() => { + const oldPath = this.path; + const newPath = getPath(); + + if ( + oldPath != newPath && + this.opts.shouldTrackUrlChange.call(this, newPath, oldPath) + ) { + this.path = newPath; + this.tracker.set({ + page: newPath, + title: document.title, + }); + + if (historyDidUpdate || this.opts.trackReplaceState) { + const defaultFields = { transport: "beacon" }; + this.tracker.send( + "pageview", + createFieldsObj( + defaultFields, + this.opts.fieldsObj, + this.tracker, + this.opts.hitFilter + ) + ); + } + } + }, 0); + } + + shouldTrackUrlChange(newPath, oldPath) { + return !!(newPath && oldPath); + } + + remove() { + MethodChain.remove(history, "pushState", this.pushStateOverride); + MethodChain.remove(history, "replaceState", this.replaceStateOverride); + window.removeEventListener("popstate", this.handlePopState); + } +} + +provide("urlChangeTracker", UrlChangeTracker); diff --git a/package.json b/package.json index 2708374ccb..144e61a020 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,6 @@ "@vitejs/plugin-react-oxc": "^0.2.3", "addressparser": "^1.0.1", "async-sema": "^3.1.1", - "autotrack": "^2.4.1", "bull": "^4.16.5", "class-validator": "^0.14.4", "command-score": "^0.1.2", diff --git a/yarn.lock b/yarn.lock index 30706f6676..baaf3aea63 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8693,13 +8693,6 @@ __metadata: languageName: node linkType: hard -"amdefine@npm:>=0.0.4": - version: 1.0.1 - resolution: "amdefine@npm:1.0.1" - checksum: 10c0/ba8aa5d4ff5248b2ed067111e72644b36b5b7ae88d9a5a2c4223dddb3bdc9102db67291e0b414f59f12c6479ac6a365886bac72c7965e627cbc732e0962dd1ab - languageName: node - linkType: hard - "ansi-escapes@npm:^4.3.2": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" @@ -8718,13 +8711,6 @@ __metadata: languageName: node linkType: hard -"ansi-regex@npm:^2.0.0": - version: 2.1.1 - resolution: "ansi-regex@npm:2.1.1" - checksum: 10c0/78cebaf50bce2cb96341a7230adf28d804611da3ce6bf338efa7b72f06cc6ff648e29f80cd95e582617ba58d5fdbec38abfeed3500a98bce8381a9daec7c548b - languageName: node - linkType: hard - "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -8739,13 +8725,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^2.2.1": - version: 2.2.1 - resolution: "ansi-styles@npm:2.2.1" - checksum: 10c0/7c68aed4f1857389e7a12f85537ea5b40d832656babbf511cc7ecd9efc52889b9c3e5653a71a6aade783c3c5e0aa223ad4ff8e83c27ac8a666514e6c79068cab - languageName: node - linkType: hard - "ansi-styles@npm:^3.2.1": version: 3.2.1 resolution: "ansi-styles@npm:3.2.1" @@ -8919,26 +8898,6 @@ __metadata: languageName: node linkType: hard -"autotrack@npm:^2.4.1": - version: 2.4.1 - resolution: "autotrack@npm:2.4.1" - dependencies: - chalk: "npm:^1.1.3" - dom-utils: "npm:^0.9.0" - fs-extra: "npm:^3.0.1" - glob: "npm:^7.1.1" - google-closure-compiler-js: "npm:^20170423.0.0" - gzip-size: "npm:^3.0.0" - rollup: "npm:^0.41.4" - rollup-plugin-memory: "npm:^2.0.0" - rollup-plugin-node-resolve: "npm:^3.0.0" - source-map: "npm:^0.5.6" - bin: - autotrack: ./bin/autotrack - checksum: 10c0/669ff38cdb265ce77aef14fadcbde745760799eb1e7a57db094011320113ffc10e5bb3c5d5c45c060d7915f9d360e66e0ec23d9a605148caa93884243aa1bb23 - languageName: node - linkType: hard - "available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" @@ -9560,13 +9519,6 @@ __metadata: languageName: node linkType: hard -"builtin-modules@npm:^2.0.0": - version: 2.0.0 - resolution: "builtin-modules@npm:2.0.0" - checksum: 10c0/e012c47b6add298e23dc2ca7cf12cf330392df176922514c91dce6749266a8ce0457177386c34fa6600d12b1e0166fd46a7aca80616e5df773102235cf85a9a2 - languageName: node - linkType: hard - "bull@npm:^4.16.5": version: 4.16.5 resolution: "bull@npm:4.16.5" @@ -9682,19 +9634,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^1.1.3": - version: 1.1.3 - resolution: "chalk@npm:1.1.3" - dependencies: - ansi-styles: "npm:^2.2.1" - escape-string-regexp: "npm:^1.0.2" - has-ansi: "npm:^2.0.0" - strip-ansi: "npm:^3.0.0" - supports-color: "npm:^2.0.0" - checksum: 10c0/28c3e399ec286bb3a7111fd4225ebedb0d7b813aef38a37bca7c498d032459c265ef43404201d5fbb8d888d29090899c95335b4c0cda13e8b126ff15c541cef8 - languageName: node - linkType: hard - "chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -9920,38 +9859,13 @@ __metadata: languageName: node linkType: hard -"clone-buffer@npm:^1.0.0": - version: 1.0.0 - resolution: "clone-buffer@npm:1.0.0" - checksum: 10c0/d813f4d12651bc4951d5e4869e2076d34ccfc3b23d0aae4e2e20e5a5e97bc7edbba84038356d222c54b25e3a83b5f45e8b637c18c6bd1794b2f1b49114122c50 - languageName: node - linkType: hard - -"clone-stats@npm:^1.0.0": - version: 1.0.0 - resolution: "clone-stats@npm:1.0.0" - checksum: 10c0/bb1e05991e034e1eb104173c25bb652ea5b2b4dad5a49057a857e00f8d1da39de3bd689128a25bab8cbdfbea8ae8f6066030d106ed5c299a7d92be7967c50217 - languageName: node - linkType: hard - -"clone@npm:^2.1.1, clone@npm:^2.1.2": +"clone@npm:^2.1.2": version: 2.1.2 resolution: "clone@npm:2.1.2" checksum: 10c0/ed0601cd0b1606bc7d82ee7175b97e68d1dd9b91fd1250a3617b38d34a095f8ee0431d40a1a611122dcccb4f93295b4fdb94942aa763392b5fe44effa50c2d5e languageName: node linkType: hard -"cloneable-readable@npm:^1.0.0": - version: 1.1.3 - resolution: "cloneable-readable@npm:1.1.3" - dependencies: - inherits: "npm:^2.0.1" - process-nextick-args: "npm:^2.0.0" - readable-stream: "npm:^2.3.5" - checksum: 10c0/52db2904dcfcd117e4e9605b69607167096c954352eff0fcded0a16132c9cfc187b36b5db020bee2dc1b3a968ca354f8b30aef3d8b4ea74e3ea83a81d43e47bb - languageName: node - linkType: hard - "cluster-key-slot@npm:^1.1.0": version: 1.1.2 resolution: "cluster-key-slot@npm:1.1.2" @@ -11286,13 +11200,6 @@ __metadata: languageName: node linkType: hard -"dom-utils@npm:^0.9.0": - version: 0.9.0 - resolution: "dom-utils@npm:0.9.0" - checksum: 10c0/31942e7225e3dbab21c1512934f72cc5d57efe14031c05d2c6a71d46122c3f6df6e32a81d07e1c814149347c76712f81424975193bbcdd254b513ef6d143cfe6 - languageName: node - linkType: hard - "domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" @@ -11382,13 +11289,6 @@ __metadata: languageName: node linkType: hard -"duplexer@npm:^0.1.1": - version: 0.1.2 - resolution: "duplexer@npm:0.1.2" - checksum: 10c0/c57bcd4bdf7e623abab2df43a7b5b23d18152154529d166c1e0da6bee341d84c432d157d7e97b32fecb1bf3a8b8857dd85ed81a915789f550637ed25b8e64fc2 - languageName: node - linkType: hard - "duplexify@npm:^3.5.1": version: 3.7.1 resolution: "duplexify@npm:3.7.1" @@ -11885,7 +11785,7 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": +"escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 @@ -12534,17 +12434,6 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^3.0.1": - version: 3.0.1 - resolution: "fs-extra@npm:3.0.1" - dependencies: - graceful-fs: "npm:^4.1.2" - jsonfile: "npm:^3.0.0" - universalify: "npm:^0.1.0" - checksum: 10c0/ac3a17c9355f80aa250e102dbc4939c50ec83fca49a144bdd432f43deb0a3c07f74ec313feb2b938d6b0c1de9bfb02c2358bc602efeed5174fca692b7d4694f1 - languageName: node - linkType: hard - "fs-extra@npm:^8.0.1, fs-extra@npm:^8.1.0": version: 8.1.0 resolution: "fs-extra@npm:8.1.0" @@ -12886,7 +12775,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.1.1, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0": +"glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -12923,19 +12812,6 @@ __metadata: languageName: node linkType: hard -"google-closure-compiler-js@npm:^20170423.0.0": - version: 20170423.0.0 - resolution: "google-closure-compiler-js@npm:20170423.0.0" - dependencies: - minimist: "npm:^1.2.0" - vinyl: "npm:^2.0.1" - webpack-core: "npm:^0.6.8" - bin: - google-closure-compiler-js: cmd.js - checksum: 10c0/67e3d6cf7bcaacd6c66b69a53465ba4650991f775a1a73b2eeb65849751c4b3ad01033efd8f76e69ae4551489f4cc0cb326a9facbd78224908a2ce3fa9f53365 - languageName: node - linkType: hard - "gopd@npm:^1.0.1, gopd@npm:^1.2.0": version: 1.2.0 resolution: "gopd@npm:1.2.0" @@ -12943,7 +12819,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.8, graceful-fs@npm:^4.2.9": +"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.8, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -12966,15 +12842,6 @@ __metadata: languageName: node linkType: hard -"gzip-size@npm:^3.0.0": - version: 3.0.0 - resolution: "gzip-size@npm:3.0.0" - dependencies: - duplexer: "npm:^0.1.1" - checksum: 10c0/8f4a201c15edab36de0e3ca86d2360b13dfc602b0035cf128e350fda7d5be28b97ab6a8b57dbbe7a071c808fb3557c5f417c3fa947e247d837fcf7fa530e8c6c - languageName: node - linkType: hard - "hachure-fill@npm:^0.5.2": version: 0.5.2 resolution: "hachure-fill@npm:0.5.2" @@ -12982,15 +12849,6 @@ __metadata: languageName: node linkType: hard -"has-ansi@npm:^2.0.0": - version: 2.0.0 - resolution: "has-ansi@npm:2.0.0" - dependencies: - ansi-regex: "npm:^2.0.0" - checksum: 10c0/f54e4887b9f8f3c4bfefd649c48825b3c093987c92c27880ee9898539e6f01aed261e82e73153c3f920fde0db5bf6ebd58deb498ed1debabcb4bc40113ccdf05 - languageName: node - linkType: hard - "has-bigints@npm:^1.0.2": version: 1.1.0 resolution: "has-bigints@npm:1.1.0" @@ -15048,18 +14906,6 @@ __metadata: languageName: node linkType: hard -"jsonfile@npm:^3.0.0": - version: 3.0.1 - resolution: "jsonfile@npm:3.0.1" - dependencies: - graceful-fs: "npm:^4.1.6" - dependenciesMeta: - graceful-fs: - optional: true - checksum: 10c0/159ec98712d5a0f77ddb96ddbde0ecc5fb1108fadab5b85cea18f508be78eabf03a3370b3769112fce1d8772b4e396f81d7c0d378ac5d7955bee5f1330cf1b19 - languageName: node - linkType: hard - "jsonfile@npm:^4.0.0": version: 4.0.0 resolution: "jsonfile@npm:4.0.0" @@ -17180,7 +17026,6 @@ __metadata: "@vitejs/plugin-react-oxc": "npm:^0.2.3" addressparser: "npm:^1.0.1" async-sema: "npm:^3.1.1" - autotrack: "npm:^2.4.1" babel-jest: "npm:^29.7.0" babel-plugin-styled-components: "npm:^2.1.4" babel-plugin-transform-inline-environment-variables: "npm:^0.4.4" @@ -18263,7 +18108,7 @@ __metadata: languageName: node linkType: hard -"process-nextick-args@npm:^2.0.0, process-nextick-args@npm:^2.0.1, process-nextick-args@npm:~2.0.0": +"process-nextick-args@npm:^2.0.1, process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" checksum: 10c0/bec089239487833d46b59d80327a1605e1c5287eaad770a291add7f45fda1bb5e28b38e0e061add0a1d0ee0984788ce74fa394d345eed1c420cacf392c554367 @@ -19026,7 +18871,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.0.0, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.5, readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.0.0, readable-stream@npm:^2.3.3, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -19242,20 +19087,13 @@ __metadata: languageName: node linkType: hard -"remove-trailing-separator@npm:^1.0.1, remove-trailing-separator@npm:^1.1.0": +"remove-trailing-separator@npm:^1.1.0": version: 1.1.0 resolution: "remove-trailing-separator@npm:1.1.0" checksum: 10c0/3568f9f8f5af3737b4aee9e6e1e8ec4be65a92da9cb27f989e0893714d50aa95ed2ff02d40d1fa35e1b1a234dc9c2437050ef356704a3999feaca6667d9e9bfc languageName: node linkType: hard -"replace-ext@npm:^1.0.0": - version: 1.0.1 - resolution: "replace-ext@npm:1.0.1" - checksum: 10c0/9a9c3d68d0d31f20533ed23e9f6990cff8320cf357eebfa56c0d7b63746ae9f2d6267f3321e80e0bffcad854f710fc9a48dbcf7615579d767db69e9cd4a43168 - languageName: node - linkType: hard - "replace-ext@npm:^2.0.0": version: 2.0.0 resolution: "replace-ext@npm:2.0.0" @@ -19349,7 +19187,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.6, resolve@npm:^1.13.1, resolve@npm:^1.22.1, resolve@npm:^1.22.11, resolve@npm:~1.22.1": +"resolve@npm:^1.13.1, resolve@npm:^1.22.1, resolve@npm:^1.22.11, resolve@npm:~1.22.1": version: 1.22.12 resolution: "resolve@npm:1.22.12" dependencies: @@ -19363,7 +19201,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.13.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.11#optional!builtin, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin": +"resolve@patch:resolve@npm%3A^1.13.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.11#optional!builtin, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin": version: 1.22.12 resolution: "resolve@patch:resolve@npm%3A1.22.12#optional!builtin::version=1.22.12&hash=c3c19d" dependencies: @@ -19507,24 +19345,6 @@ __metadata: languageName: node linkType: hard -"rollup-plugin-memory@npm:^2.0.0": - version: 2.0.0 - resolution: "rollup-plugin-memory@npm:2.0.0" - checksum: 10c0/f728e1711a8df25113e71613307933d775a95c2134b2646b5cd1b20b8e4f3e11b30b6b7c28ad74d77a3a586905adfadfd06d9ed4b0e0ee1fb8aeef16d33de4fb - languageName: node - linkType: hard - -"rollup-plugin-node-resolve@npm:^3.0.0": - version: 3.4.0 - resolution: "rollup-plugin-node-resolve@npm:3.4.0" - dependencies: - builtin-modules: "npm:^2.0.0" - is-module: "npm:^1.0.0" - resolve: "npm:^1.1.6" - checksum: 10c0/c4c3f772b3686a547a93aa1e22b91e2598b1f3ca5d493487ce510dfb1ea14e3f69e0186dd915f68421ad18710fff020572ba68a5adacae2ae7326938038ca89e - languageName: node - linkType: hard - "rollup-plugin-stats@npm:1.5.6": version: 1.5.6 resolution: "rollup-plugin-stats@npm:1.5.6" @@ -19563,17 +19383,6 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^0.41.4": - version: 0.41.6 - resolution: "rollup@npm:0.41.6" - dependencies: - source-map-support: "npm:^0.4.0" - bin: - rollup: ./bin/rollup - checksum: 10c0/9e39f62434ce49086ad6bc30adb2e61a0f6bdb8fa69740840f7dbc82bfacf890195213ee88d5c7cbba811fe31d0752980cd25e8b395a5a581389a656546671e7 - languageName: node - linkType: hard - "rollup@npm:^2.79.2": version: 2.79.2 resolution: "rollup@npm:2.79.2" @@ -20275,13 +20084,6 @@ __metadata: languageName: node linkType: hard -"source-list-map@npm:~0.1.7": - version: 0.1.8 - resolution: "source-list-map@npm:0.1.8" - checksum: 10c0/86835e676f6beff053ed2e5b750e37a11fab5ebe5992dd27f12bc024a052ee42ead71471a055b2008adcb8653fa3639da96c9051f2a33d67c0d160b00ddc73ad - languageName: node - linkType: hard - "source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" @@ -20299,15 +20101,6 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:^0.4.0": - version: 0.4.18 - resolution: "source-map-support@npm:0.4.18" - dependencies: - source-map: "npm:^0.5.6" - checksum: 10c0/cd9f0309c1632b1e01a7715a009e0b036d565f3af8930fa8cda2a06aeec05ad1d86180e743b7e1f02cc3c97abe8b6d8de7c3878c2d8e01e86e17f876f7ecf98e - languageName: node - linkType: hard - "source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" @@ -20318,13 +20111,6 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.5.6": - version: 0.5.7 - resolution: "source-map@npm:0.5.7" - checksum: 10c0/904e767bb9c494929be013017380cbba013637da1b28e5943b566031e29df04fba57edf3f093e0914be094648b577372bd8ad247fa98cfba9c600794cd16b599 - languageName: node - linkType: hard - "source-map@npm:^0.6.0, source-map@npm:~0.6.0, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" @@ -20348,15 +20134,6 @@ __metadata: languageName: node linkType: hard -"source-map@npm:~0.4.1": - version: 0.4.4 - resolution: "source-map@npm:0.4.4" - dependencies: - amdefine: "npm:>=0.0.4" - checksum: 10c0/685924f8b0dfb1580c2d12f85b1ba116f1382ed9c4b227d8a15958d39c3e5494ee21c5e3b4a5bf1c6c489041b9dbaeb7cff14dda7ad6458365c665492677f588 - languageName: node - linkType: hard - "sourcemap-codec@npm:^1.4.8": version: 1.4.8 resolution: "sourcemap-codec@npm:1.4.8" @@ -20672,15 +20449,6 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^3.0.0": - version: 3.0.1 - resolution: "strip-ansi@npm:3.0.1" - dependencies: - ansi-regex: "npm:^2.0.0" - checksum: 10c0/f6e7fbe8e700105dccf7102eae20e4f03477537c74b286fd22cfc970f139002ed6f0d9c10d0e21aa9ed9245e0fa3c9275930e8795c5b947da136e4ecb644a70f - languageName: node - linkType: hard - "strip-ansi@npm:^7.0.1": version: 7.1.2 resolution: "strip-ansi@npm:7.1.2" @@ -20803,13 +20571,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^2.0.0": - version: 2.0.0 - resolution: "supports-color@npm:2.0.0" - checksum: 10c0/570e0b63be36cccdd25186350a6cb2eaad332a95ff162fa06d9499982315f2fe4217e69dd98e862fbcd9c81eaff300a825a1fe7bf5cc752e5b84dfed042b0dda - languageName: node - linkType: hard - "supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -21904,20 +21665,6 @@ __metadata: languageName: node linkType: hard -"vinyl@npm:^2.0.1": - version: 2.2.1 - resolution: "vinyl@npm:2.2.1" - dependencies: - clone: "npm:^2.1.1" - clone-buffer: "npm:^1.0.0" - clone-stats: "npm:^1.0.0" - cloneable-readable: "npm:^1.0.0" - remove-trailing-separator: "npm:^1.0.1" - replace-ext: "npm:^1.0.0" - checksum: 10c0/e7073fe5a3e10bbd5a3abe7ccf3351ed1b784178576b09642c08b0ef4056265476610aabd29eabfaaf456ada45f05f4112a35687d502f33aab33b025fc6ec38f - languageName: node - linkType: hard - "vinyl@npm:^3.0.0, vinyl@npm:^3.0.1, vinyl@npm:~3.0.0": version: 3.0.1 resolution: "vinyl@npm:3.0.1" @@ -22161,16 +21908,6 @@ __metadata: languageName: node linkType: hard -"webpack-core@npm:^0.6.8": - version: 0.6.9 - resolution: "webpack-core@npm:0.6.9" - dependencies: - source-list-map: "npm:~0.1.7" - source-map: "npm:~0.4.1" - checksum: 10c0/9d68f45cd9b55ba97793ef466e8acb11286c22b21ec3cdf9fc3881b8ae0afde2b4e765333fa192b57496daa2a0fc96784031ea47a1f3ce6ca99c5a97f910da99 - languageName: node - linkType: hard - "whatwg-encoding@npm:^2.0.0": version: 2.0.0 resolution: "whatwg-encoding@npm:2.0.0"