<commit_before>import { Meteor } from "meteor/meteor";
import { Tracker } from "meteor/tracker";
import { SETTINGS } from "./constants";
import { trackLogins, getUserEmail } from "./meteor-analytics";
import { trackPageWhenReady } from "./helpers";
import analytics from "../vendor/analytics.min.js";

Meteor.startup(() => {
  if (SETTINGS) {
    analytics.initialize(SETTINGS);
    
    // Save reference to original pushState.
    const pushState = window.history.pushState;
    window.history.pushState = function(state) {
      if (typeof window.history.onpushstate == "function") {
        window.history.onpushstate({ title: document.title, referrer: location.href });
      }
      return pushState.apply(window.history, arguments);
    }
    
    window.addEventListener('popstate', function() {
      if (typeof window.history.onpushstate == "function") {
        window.history.onpushstate({ title: document.title, referrer: location.href });
      }
    }, false);
    
    window.history.onpushstate = function({ title, referrer }) {
      // Use defer so it doesnt use the previous location.
      Meteor.defer(() => {
        const page = {
          title,
          referrer,
          path: location.pathname,
          search: location.search,
          url: location.href
        };
        // Track page on analytics
        trackPageWhenReady(page.title, page);
      });
    }
    
  } else {
    console.error("Missing analyticsSettings in Meteor.settings.public");
  }

  if (Package["accounts-base"]) {
    Tracker.autorun(() => {
      userEmail = getUserEmail();
    });
    Tracker.autorun(trackLogins);
  }
});<commit_msg>Refactor router-agnostic code in client/startup.js<commit_after>import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { SETTINGS } from './constants';
import { trackLogins, getUserEmail } from './meteor-analytics';
import { trackPageWhenReady } from './helpers';
import analytics from '../vendor/analytics.min';

const logPageLoad = (title, referrer) => {
  // Use setTimeout so it uses the location from after the route change
  setTimeout(() => {
    const page = {
      title,
      referrer,
      path: location.pathname,
      search: location.search,
      url: location.href,
    };

    // Track page on analytics
    trackPageWhenReady(page.title, page);
  }, 0);
};

const logFirstPageLoad = () => {
  logPageLoad(document.title, document.referrer);
};

const configurePageLoadTracking = () => {
  const fireOnPushState = () => {
    try {
      logPageLoad({ title: document.title, referrer: location.href });
    } catch (e) {
      console.error(e); // eslint-disable-line no-console
    }
  };

  // Save reference to original pushState.
  const originalPushState = window.history.pushState;

  // Wrap original pushState to call new push state function
  // NOTE: this can't be an arrow function!
  window.history.pushState = function okgrowAnalyticsMonkeyPatchedPushState(...args) {
    fireOnPushState();

    // Call original pushState with incoming arguments
    return originalPushState.apply(window.history, args);
  };

  window.addEventListener('popstate', () => {
    fireOnPushState();
  }, false);
};

Meteor.startup(() => {
  if (SETTINGS) {
    analytics.initialize(SETTINGS);
    logFirstPageLoad();
    configurePageLoadTracking();
  } else {
    console.error('Missing analyticsSettings in Meteor.settings.public'); // eslint-disable-line no-console
  }

  if (Package['accounts-base']) {
    Tracker.autorun(() => {
      userEmail = getUserEmail();
    });
    Tracker.autorun(trackLogins);
  }
});
{'fraction_non_alphanumeric': 0.1348438795247306, 'fraction_numerical': 0.00027631942525559546, 'mean_word_length': 3.0628507295173963, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6565782', 'n_tokens_mistral': 1072, 'n_tokens_neox': 1062, 'n_words': 245}