<commit_before>import WebSocket from "../utils/WebSocket.js";
import Keyboard from "../input/Keyboard.js";
import GUIInput from "./GUIInput.js";

let staticGUI;

// STYLES

let style = document.createElement("style");
document.head.appendChild(style);
style.sheet.insertRule(`
  dlib-gui {
    display: block;
    position: absolute;
    resize: horizontal;
    top: 0;
    left: 0;
    width: 250px;
    padding: 5px;
    color: white;
    font-family: monospace;
    max-height: 100%;
    box-sizing: border-box;
    overflow: auto;
  }
`, 0);
style.sheet.insertRule(`
  dlib-gui dlib-guiinput {
    margin: 5px 0;
  }
`, 0);
style.sheet.insertRule(`
  dlib-gui details details {
    margin: 10px;
  }
`, 0);
style.sheet.insertRule(`
  dlib-gui details summary {
    cursor: pointer;
  }
`, 0);
style.sheet.insertRule(`
  dlib-gui details summary:focus {
    outline: none;
  }
`, 0);

// UTILS

function componentToHex(c) {
  let hex = c.toString(16);
  return hex.length == 1 ? "0" + hex : hex;
}

function rgbToHex(r, g, b) {
  return "#" + componentToHex(r * 255) + componentToHex(g * 255) + componentToHex(b * 255);
}

function hexToRgb(hex) {
  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result ? {
    r: parseInt(result[1], 16) / 255,
    g: parseInt(result[2], 16) / 255,
    b: parseInt(result[3], 16) / 255
  } : null;
}

function colorFromHex(color, hex) {
  if (typeof color === "string") {
    return hex;
  }

  let colorValue = hexToRgb(hex);

  if (color.r !== undefined) {
    Object.assign(color, colorValue);
  } else if (color.x !== undefined) {
    [color.x, color.y, color.z] = [colorValue.r, colorValue.g, colorValue.b];
  } else {
    [color[0], color[1], color[2]] = [colorValue.r, colorValue.g, colorValue.b];
  }

  return color;
}

function colorToHex(color) {
  if (typeof color === "string") {
    return color;
  }
  return rgbToHex(
    color.r !== undefined ? color.r : color.x !== undefined ? color.x : color[0],
    color.g !== undefined ? color.g : color.y !== undefined ? color.y : color[1],
    color.b !== undefined ? color.b : color.z !== undefined ? color.z : color[2]
  );
}

function normalizeString(string) {
  return `${string.toLowerCase().replace(/[^\w-]/g, "")}`;
}

function urlHashRegExpFromKey(key) {
  return new RegExp(`([#&]gui/${key}=)([^=&#?]*)`, "g");
}

// GUI

const GUI_REG_EXP = /([#&]gui=)((%7B|{).*(%7D|}))([&?]*)/;

let DATA = {};
(function() {
  let matches = GUI_REG_EXP.exec(window.location.hash);
  if (matches) {
    let string = matches[2];
    string = string.replace(/”|%E2%80%9D/g, "%22");
    window.location.hash = window.location.hash.replace(GUI_REG_EXP, `$1${string}$5`);
    DATA = JSON.parse(decodeURI(string));
  }
})();

export default class GUI extends HTMLElement {
  static _addStatic() {
    if (staticGUI) {
      return;
    }
    staticGUI = document.createElement("dlib-gui");
    document.body.appendChild(staticGUI);
  }

  static add(...params) {
    GUI._addStatic();
    return staticGUI.add(...params);
  }

  static get element() {
    return staticGUI;
  }

  static get data() {
    return DATA;
  }

  static set visible(value) {
    GUI._addStatic();
    staticGUI.visible = value;
  }

  static get visible() {
    return staticGUI.visible;
  }

  static set open(value) {
    GUI._addStatic();
    staticGUI.open = value;
  }

  static get groups() {
    return staticGUI.groups;
  }

  static get open() {
    return staticGUI.open;
  }

  static get update() {
    return staticGUI.update;
  }

  static set serverUrl(value) {
    GUI._addStatic();
    staticGUI.serverUrl = value;
  }

  constructor({serverUrl} = {}) {
    super();

    this.serverUrl = serverUrl;

    this.groups = new Map();
    this._inputs = new Map();
    this._uids = new Set();

    this._container = document.createElement("details");
    this._container.innerHTML = "GUI";

    this.open = true;
  }

  set serverUrl(value) {
    this._serverUrl = value;

    if(this._webSocket) {
      this._webSocket.removeEventListener("message", this._onWebSocketMessage);
      this._webSocket.close();
      this._webSocket = null;
    }
    if(!this._serverUrl) {
      return;
    }
    this._webSocket = new WebSocket(this._serverUrl);
    this._onWebSocketMessage = (e) => {
      let data = JSON.parse(e.data);
      let input = this._inputs.get(data.uid);
      if(input._client) {
        if(input.type === "button") {
          input.value();
        } else {
          input.value = data.value;
        }
      }
    }
    this._webSocket.addEventListener("message", this._onWebSocketMessage);
  }

  get serverUrl() {
    return this._serverUrl;
  }

  set visible(value) {
    this.style.display = value ? "" : "none";
  }

  get visible() {
    return this.style.visibility === "visible";
  }

  update() {
    for (let input of this._inputs.values()) {
      input.update();
    }
  }

  set open(value) {
    this._container.open = value;
  }

  get open() {
    return this._container.open;
  }

  add(object, key, {type, label = key, id = label, group = "", reload = false, remote = false, client = remote, onChange = () => {
      }, options, max, min, step} = {}) {
    if(object[key] === null || object[key] === undefined) {
      console.error(`GUI: ${id} must be defined.`);
      return;
    }

    let idKey = normalizeString(id);
    let groupKey = normalizeString(group);
    let uid = groupKey ? `${groupKey}/${idKey}` : idKey;

    if(this._uids.has(uid)) {
      console.error(`GUI: An input with id ${id} already exist in the group ${group}`);
      return;
    }

    this._uids.add(uid);

    if(remote && !this.serverUrl) {
      this._serverUrl = `wss://${location.hostname}:80`;
    }

    type = type || (options ? "select" : "");

    if (!type) {
      switch (typeof object[key]) {
        case "boolean":
          type = "checkbox";
          break;
        case "string":
          type = "text";
          break;
        case "function":
          type = "button";
          break;
        default:
          type = typeof object[key];
      }
    }

    if (!this._container.parentNode) {
      this.appendChild(this._container);
    }
    let container = this._container;
    if(group) {
      container = this.groups.get(group);
      if(!container) {
        container = document.createElement("details");
        container.innerHTML = `<summary>${group}</summary>`;
        this.groups.set(group, container);
        this._container.appendChild(container);
      }
    }
    let input = document.createElement("dlib-guiinput");
    input.object = type === "color" ? {
      value: "#000000"
    } : object;
    input.key = type === "color" ? "value" : key;
    input.label = label;
    input.value = (type === "color" ? colorToHex(object[key]) : object[key]);
    input._client = client;
    if (min) {
      input.min = min;
    }
    if (max) {
      input.max = max;
    }
    if (step) {
      input.step = step;
    }
    if (options) {
      input.options = options;
    }
    input.type = type;
    container.appendChild(input);

    const SAVED_VALUE = groupKey && DATA[groupKey] ? DATA[groupKey][idKey] : DATA[idKey];
    if(SAVED_VALUE !== undefined) {
      input.value = SAVED_VALUE;
      if (type === "color") {
        object[key] = colorFromHex(object[key], SAVED_VALUE);
      }
    }

    const onValueChange = (value) => {
      let containerData = groupKey ? DATA[groupKey] : DATA;
      if (!containerData) {
        containerData = DATA[groupKey] = {};
      }
      containerData[idKey] = input.value;

      if (GUI_REG_EXP.test(window.location.hash)) {
        window.location.hash = window.location.hash.replace(GUI_REG_EXP, `$1${encodeURI(JSON.stringify(DATA))}$5`);
      } else {
        let prefix = window.location.hash ? "&" : "#";
        window.location.hash += `${prefix}gui=${encodeURI(JSON.stringify(DATA))}`;
      }

      if(remote && this._webSocket) {
        this._webSocket.send(JSON.stringify({uid, value}));
      }

      if (reload) {
        if (Keyboard.hasKeyDown(Keyboard.SHIFT)) {
          Keyboard.addEventListener("keyup", function reloadLocation() {
            Keyboard.removeEventListener("keyup", reloadLocation);
            window.location.reload();
          });
        } else {
          window.location.reload();
        }
      }

      onChange(value);
    }

    // TODO: Clean here

    if (type === "button") {
      input.addEventListener("click", onValueChange);
    } else {

      let animationFrameId = -1;
      const onValueChangeTmp = () => {
        cancelAnimationFrame(animationFrameId);
        animationFrameId = requestAnimationFrame(() => {
          if (type === "color") {
            onValueChange(colorFromHex(object[key], input.value));
          } else {
            onValueChange(input.value);
          }
        });
      }

      if (type !== "text") {
        input.addEventListener("input", onValueChangeTmp);
      }
      input.addEventListener("change", onValueChangeTmp);
    }

    onChange(object[key]);

    this._inputs.set(uid, input);

    return input;
  }
}

window.customElements.define("dlib-gui", GUI);
<commit_msg>increase gui size a bit<commit_after>import WebSocket from "../utils/WebSocket.js";
import Keyboard from "../input/Keyboard.js";
import GUIInput from "./GUIInput.js";

let staticGUI;

// STYLES

let style = document.createElement("style");
document.head.appendChild(style);
style.sheet.insertRule(`
  dlib-gui {
    display: block;
    position: absolute;
    resize: horizontal;
    top: 0;
    left: 0;
    width: 300px;
    max-width: 100%;
    padding: 5px;
    color: white;
    font-family: monospace;
    max-height: 100%;
    box-sizing: border-box;
    overflow: auto;
  }
`, 0);
style.sheet.insertRule(`
  dlib-gui dlib-guiinput {
    margin: 5px 0;
  }
`, 0);
style.sheet.insertRule(`
  dlib-gui details details {
    margin: 10px;
  }
`, 0);
style.sheet.insertRule(`
  dlib-gui details summary {
    cursor: pointer;
  }
`, 0);
style.sheet.insertRule(`
  dlib-gui details summary:focus {
    outline: none;
  }
`, 0);

// UTILS

function componentToHex(c) {
  let hex = c.toString(16);
  return hex.length == 1 ? "0" + hex : hex;
}

function rgbToHex(r, g, b) {
  return "#" + componentToHex(r * 255) + componentToHex(g * 255) + componentToHex(b * 255);
}

function hexToRgb(hex) {
  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result ? {
    r: parseInt(result[1], 16) / 255,
    g: parseInt(result[2], 16) / 255,
    b: parseInt(result[3], 16) / 255
  } : null;
}

function colorFromHex(color, hex) {
  if (typeof color === "string") {
    return hex;
  }

  let colorValue = hexToRgb(hex);

  if (color.r !== undefined) {
    Object.assign(color, colorValue);
  } else if (color.x !== undefined) {
    [color.x, color.y, color.z] = [colorValue.r, colorValue.g, colorValue.b];
  } else {
    [color[0], color[1], color[2]] = [colorValue.r, colorValue.g, colorValue.b];
  }

  return color;
}

function colorToHex(color) {
  if (typeof color === "string") {
    return color;
  }
  return rgbToHex(
    color.r !== undefined ? color.r : color.x !== undefined ? color.x : color[0],
    color.g !== undefined ? color.g : color.y !== undefined ? color.y : color[1],
    color.b !== undefined ? color.b : color.z !== undefined ? color.z : color[2]
  );
}

function normalizeString(string) {
  return `${string.toLowerCase().replace(/[^\w-]/g, "")}`;
}

function urlHashRegExpFromKey(key) {
  return new RegExp(`([#&]gui/${key}=)([^=&#?]*)`, "g");
}

// GUI

const GUI_REG_EXP = /([#&]gui=)((%7B|{).*(%7D|}))([&?]*)/;

let DATA = {};
(function() {
  let matches = GUI_REG_EXP.exec(window.location.hash);
  if (matches) {
    let string = matches[2];
    string = string.replace(/”|%E2%80%9D/g, "%22");
    window.location.hash = window.location.hash.replace(GUI_REG_EXP, `$1${string}$5`);
    DATA = JSON.parse(decodeURI(string));
  }
})();

export default class GUI extends HTMLElement {
  static _addStatic() {
    if (staticGUI) {
      return;
    }
    staticGUI = document.createElement("dlib-gui");
    document.body.appendChild(staticGUI);
  }

  static add(...params) {
    GUI._addStatic();
    return staticGUI.add(...params);
  }

  static get element() {
    return staticGUI;
  }

  static get data() {
    return DATA;
  }

  static set visible(value) {
    GUI._addStatic();
    staticGUI.visible = value;
  }

  static get visible() {
    return staticGUI.visible;
  }

  static set open(value) {
    GUI._addStatic();
    staticGUI.open = value;
  }

  static get groups() {
    return staticGUI.groups;
  }

  static get open() {
    return staticGUI.open;
  }

  static get update() {
    return staticGUI.update;
  }

  static set serverUrl(value) {
    GUI._addStatic();
    staticGUI.serverUrl = value;
  }

  constructor({serverUrl} = {}) {
    super();

    this.serverUrl = serverUrl;

    this.groups = new Map();
    this._inputs = new Map();
    this._uids = new Set();

    this._container = document.createElement("details");
    this._container.innerHTML = "GUI";

    this.open = true;
  }

  set serverUrl(value) {
    this._serverUrl = value;

    if(this._webSocket) {
      this._webSocket.removeEventListener("message", this._onWebSocketMessage);
      this._webSocket.close();
      this._webSocket = null;
    }
    if(!this._serverUrl) {
      return;
    }
    this._webSocket = new WebSocket(this._serverUrl);
    this._onWebSocketMessage = (e) => {
      let data = JSON.parse(e.data);
      let input = this._inputs.get(data.uid);
      if(input._client) {
        if(input.type === "button") {
          input.value();
        } else {
          input.value = data.value;
        }
      }
    }
    this._webSocket.addEventListener("message", this._onWebSocketMessage);
  }

  get serverUrl() {
    return this._serverUrl;
  }

  set visible(value) {
    this.style.display = value ? "" : "none";
  }

  get visible() {
    return this.style.visibility === "visible";
  }

  update() {
    for (let input of this._inputs.values()) {
      input.update();
    }
  }

  set open(value) {
    this._container.open = value;
  }

  get open() {
    return this._container.open;
  }

  add(object, key, {type, label = key, id = label, group = "", reload = false, remote = false, client = remote, onChange = () => {
      }, options, max, min, step} = {}) {
    if(object[key] === null || object[key] === undefined) {
      console.error(`GUI: ${id} must be defined.`);
      return;
    }

    let idKey = normalizeString(id);
    let groupKey = normalizeString(group);
    let uid = groupKey ? `${groupKey}/${idKey}` : idKey;

    if(this._uids.has(uid)) {
      console.error(`GUI: An input with id ${id} already exist in the group ${group}`);
      return;
    }

    this._uids.add(uid);

    if(remote && !this.serverUrl) {
      this._serverUrl = `wss://${location.hostname}:80`;
    }

    type = type || (options ? "select" : "");

    if (!type) {
      switch (typeof object[key]) {
        case "boolean":
          type = "checkbox";
          break;
        case "string":
          type = "text";
          break;
        case "function":
          type = "button";
          break;
        default:
          type = typeof object[key];
      }
    }

    if (!this._container.parentNode) {
      this.appendChild(this._container);
    }
    let container = this._container;
    if(group) {
      container = this.groups.get(group);
      if(!container) {
        container = document.createElement("details");
        container.innerHTML = `<summary>${group}</summary>`;
        this.groups.set(group, container);
        this._container.appendChild(container);
      }
    }
    let input = document.createElement("dlib-guiinput");
    input.object = type === "color" ? {
      value: "#000000"
    } : object;
    input.key = type === "color" ? "value" : key;
    input.label = label;
    input.value = (type === "color" ? colorToHex(object[key]) : object[key]);
    input._client = client;
    if (min) {
      input.min = min;
    }
    if (max) {
      input.max = max;
    }
    if (step) {
      input.step = step;
    }
    if (options) {
      input.options = options;
    }
    input.type = type;
    container.appendChild(input);

    const SAVED_VALUE = groupKey && DATA[groupKey] ? DATA[groupKey][idKey] : DATA[idKey];
    if(SAVED_VALUE !== undefined) {
      input.value = SAVED_VALUE;
      if (type === "color") {
        object[key] = colorFromHex(object[key], SAVED_VALUE);
      }
    }

    const onValueChange = (value) => {
      let containerData = groupKey ? DATA[groupKey] : DATA;
      if (!containerData) {
        containerData = DATA[groupKey] = {};
      }
      containerData[idKey] = input.value;

      if (GUI_REG_EXP.test(window.location.hash)) {
        window.location.hash = window.location.hash.replace(GUI_REG_EXP, `$1${encodeURI(JSON.stringify(DATA))}$5`);
      } else {
        let prefix = window.location.hash ? "&" : "#";
        window.location.hash += `${prefix}gui=${encodeURI(JSON.stringify(DATA))}`;
      }

      if(remote && this._webSocket) {
        this._webSocket.send(JSON.stringify({uid, value}));
      }

      if (reload) {
        if (Keyboard.hasKeyDown(Keyboard.SHIFT)) {
          Keyboard.addEventListener("keyup", function reloadLocation() {
            Keyboard.removeEventListener("keyup", reloadLocation);
            window.location.reload();
          });
        } else {
          window.location.reload();
        }
      }

      onChange(value);
    }

    // TODO: Clean here

    if (type === "button") {
      input.addEventListener("click", onValueChange);
    } else {

      let animationFrameId = -1;
      const onValueChangeTmp = () => {
        cancelAnimationFrame(animationFrameId);
        animationFrameId = requestAnimationFrame(() => {
          if (type === "color") {
            onValueChange(colorFromHex(object[key], input.value));
          } else {
            onValueChange(input.value);
          }
        });
      }

      if (type !== "text") {
        input.addEventListener("input", onValueChangeTmp);
      }
      input.addEventListener("change", onValueChangeTmp);
    }

    onChange(object[key]);

    this._inputs.set(uid, input);

    return input;
  }
}

window.customElements.define("dlib-gui", GUI);
<|endoftext|>


<commit_before>/*
 * Module for tracking standardized analytics.
 */

var _gaq = _gaq || [];

var ANALYTICS = (function () {

    // Global time tracking variables
    var slideStartTime =  new Date();
    var timeOnLastSlide = null;

    /*
     * Google Analytics
     */
    var setupGoogle = function() {
        _gaq.push(['_setAccount', APP_CONFIG.GOOGLE_ANALYTICS.ACCOUNT_ID]);
        _gaq.push(['_setDomainName', APP_CONFIG.GOOGLE_ANALYTICS.DOMAIN]);
        //_gaq.push(['_setCustomVar', 1, 'BC', '', 3]);
        _gaq.push(['_setCustomVar', 2, 'Topics', APP_CONFIG.GOOGLE_ANALYTICS.TOPICS, 3]);
        //_gaq.push(['_setCustomVar', 3, 'Program ID', '', 3]);
        //_gaq.push(['_setCustomVar', 3, 'Localization', '', 1]);
        _gaq.push(['_setCustomVar', 4, 'OrgID', '1', 3]);
        _gaq.push(['_setCustomVar', 5, 'Page Types', '1', 3]);

        var orientation = 'portrait';

        if (window.orientation == 90 || window.orientation == -90) {
            orientation = 'landscape';
        }

        _gaq.push(['_setCustomVar', 6, 'Orientation', orientation, 3]);

        var viewportSize = $(window).width();
        var viewportGrouping = '1760 and higher';

        if (viewportSize < 481) {
            viewportGrouping = '0 - 480';
        } else if (viewportSize < 768) {
            viewportGrouping = '481 - 767';
        } else if (viewportSize < 1000) {
            viewportGrouping = '768 - 999';
        } else if (viewportSize < 1201) {
            viewportGrouping = '1000 - 1200';
        } else if (viewportSize < 1760) {
            viewportGrouping = '1201 - 1759';
        }

        _gaq.push(['_setCustomVar', 7, 'Viewport Size', viewportGrouping, 3]);

        if (typeof window.devicePixelRatio !== 'undefined' && window.devicePixelRatio >= 1.5) {
            _gaq.push(['_setCustomVar', 10, 'High Density Displays', 'High', 2]);
        } else {
            _gaq.push(['_setCustomVar', 10, 'High Density Displays', 'Low', 2]);
        }

        if ('ontouchstart' in document.documentElement) {
            _gaq.push(['_setCustomVar', 11, 'Touch screens', 'Touch', 2]);
        } else {
            _gaq.push(['_setCustomVar', 11, 'Touch screens', 'Traditional', 2]);
        }

        _gaq.push(['_trackPageview']);

        (function() {
            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
        })();
    }

    /*
     * Comscore
     */
    var setupComscore = function() {
        var _comscore = _comscore || [];
        _comscore.push({ c1: "2", c2: "17691522" });

        (function() {
            var s = document.createElement("script"), el = document.getElementsByTagName("script")[0]; s.async = true;
            s.src = (document.location.protocol == "https:" ? "https://sb" : "http://b") + ".scorecardresearch.com/beacon.js";
            el.parentNode.insertBefore(s, el);
        })();
    }

    /*
     * Nielson
     */
    var setupNielson = function() {
        (function () {
            var d = new Image(1, 1);
            d.onerror = d.onload = function () { d.onerror = d.onload = null; };
            d.src = ["//secure-us.imrworldwide.com/cgi-bin/m?ci=us-803244h&cg=0&cc=1&si=", escape(window.location.href), "&rp=", escape(document.referrer), "&ts=compact&rnd=", (new Date()).getTime()].join('');
        })();
    }

    /*
     * Chartbeat
     */
    var setupChartbeat = function() {
        var _sf_async_config={};
        /** CONFIGURATION START **/
        _sf_async_config.uid = 18888;
        _sf_async_config.domain = "npr.org";
        /** CONFIGURATION END **/
        (function(){
            function loadChartbeat() {
                window._sf_endpt=(new Date()).getTime();
                var e = document.createElement("script");
                e.setAttribute("language", "javascript");
                e.setAttribute("type", "text/javascript");
                e.setAttribute("src",
                    (("https:" == document.location.protocol) ?
                     "https://a248.e.akamai.net/chartbeat.download.akamai.com/102508/" :
                     "http://static.chartbeat.com/") +
                    "js/chartbeat.js");
                document.body.appendChild(e);
            }
            var oldonload = window.onload;
            window.onload = (typeof window.onload != "function") ?
                loadChartbeat : function() { oldonload(); loadChartbeat(); };
        })();
    }

    var setupAll = function() {
        setupGoogle();
        setupComscore();
        setupNielson();
        setupChartbeat();
    }

    /*
     * Event tracking.
     */
    var trackEvent = function(eventName, label, value, custom1, custom2) {
        var args = ['_trackEvent', APP_CONFIG.PROJECT_SLUG];

        args.push(eventName);

        if (label) {
            args.push(label);
        } else if (value || custom1 || custom2) {
            args.push('');
        }

        if (value) {
            args.push(value);
        } else if (custom1 || custom2) {
            args.push(0);
        }

        if (custom1) {
            args.push(custom1)
        } else if (custom2) {
            args.push('');
        }

        if (custom2) {
            args.push(custom2);
        }

        _gaq.push(args);
    }

    // SHARING

    var openShareDiscuss = function() {
        trackEvent('open-share-discuss');
    }

    var closeShareDiscuss = function() {
        trackEvent('close-share-discuss');
    }

    var clickTweet = function(location) {
        trackEvent('tweet', location);
    }

    var clickFacebook = function(location) {
        trackEvent('facebook', location);
    }

    var clickEmail = function(location) {
        trackEvent('email', location);
    }

    var postComment = function() {
        trackEvent('new-comment');
    }

    var actOnFeaturedTweet = function(action, tweet_url) {
        trackEvent('featured-tweet-action', action, null, tweet_url);
    }

    var actOnFeaturedFacebook = function(action, post_url) {
        trackEvent('featured-facebook-action', action, null, post_url);
    }

    var copySummary = function() {
        trackEvent('summary-copied');
    }

    // NAVIGATION
    var usedKeyboardNavigation = false;

    var useKeyboardNavigation = function() {
        if (!usedKeyboardNavigation) {
            trackEvent('keyboard-nav');
            usedKeyboardNavigation = true;
        }
    }

    var completeTwentyFivePercent =  function() {
        trackEvent('completion', '0.25');
    }

    var completeFiftyPercent =  function() {
        trackEvent('completion', '0.5');
    }

    var completeSeventyFivePercent =  function() {
        trackEvent('completion', '0.75');
    }

    var completeOneHundredPercent =  function() {
        trackEvent('completion', '1');
    }

    var startFullscreen = function() {
        trackEvent('fullscreen-start');
    }

    var stopFullscreen = function() {
        trackEvent('fullscreen-stop');
    }

    var begin = function(location) {
        trackEvent('begin', location);
    }

    var readyChromecast = function() {
        trackEvent('chromecast-ready');
    }

    var startChromecast = function() {
        trackEvent('chromecast-start');
    }

    var stopChromecast = function() {
        trackEvent('chromecast-stop');
    }

    // SLIDES

    var exitSlide = function(slide_index, last_slide_exit_event) {
        var currentTime = new Date();
        timeOnLastSlide = Math.abs(currentTime - slideStartTime);
        slideStartTime = currentTime;
        trackEvent('slide-exit', slide_index, timeOnLastSlide, last_slide_exit_event);
    }

    return {
        'setupAll': setupAll,
        'trackEvent': trackEvent,
        'openShareDiscuss': openShareDiscuss,
        'closeShareDiscuss': closeShareDiscuss,
        'clickTweet': clickTweet,
        'clickFacebook': clickFacebook,
        'clickEmail': clickEmail,
        'postComment': postComment,
        'actOnFeaturedTweet': actOnFeaturedTweet,
        'actOnFeaturedFacebook': actOnFeaturedFacebook,
        'copySummary': copySummary,
        'useKeyboardNavigation': useKeyboardNavigation,
        'completeTwentyFivePercent': completeTwentyFivePercent,
        'completeFiftyPercent': completeFiftyPercent,
        'completeSeventyFivePercent': completeSeventyFivePercent,
        'completeOneHundredPercent': completeOneHundredPercent,
        'exitSlide': exitSlide,
        'startFullscreen': startFullscreen,
        'stopFullscreen': stopFullscreen,
        'begin': begin,
        'readyChromecast': readyChromecast,
        'startChromecast': startChromecast,
        'stopChromecast': stopChromecast
    };
}());

ANALYTICS.setupAll();
<commit_msg>Fix chartbeat, provisionally.<commit_after>/*
 * Module for tracking standardized analytics.
 */

var _gaq = _gaq || [];
var _sf_async_config={};

var ANALYTICS = (function () {

    // Global time tracking variables
    var slideStartTime =  new Date();
    var timeOnLastSlide = null;

    /*
     * Google Analytics
     */
    var setupGoogle = function() {
        _gaq.push(['_setAccount', APP_CONFIG.GOOGLE_ANALYTICS.ACCOUNT_ID]);
        _gaq.push(['_setDomainName', APP_CONFIG.GOOGLE_ANALYTICS.DOMAIN]);
        //_gaq.push(['_setCustomVar', 1, 'BC', '', 3]);
        _gaq.push(['_setCustomVar', 2, 'Topics', APP_CONFIG.GOOGLE_ANALYTICS.TOPICS, 3]);
        //_gaq.push(['_setCustomVar', 3, 'Program ID', '', 3]);
        //_gaq.push(['_setCustomVar', 3, 'Localization', '', 1]);
        _gaq.push(['_setCustomVar', 4, 'OrgID', '1', 3]);
        _gaq.push(['_setCustomVar', 5, 'Page Types', '1', 3]);

        var orientation = 'portrait';

        if (window.orientation == 90 || window.orientation == -90) {
            orientation = 'landscape';
        }

        _gaq.push(['_setCustomVar', 6, 'Orientation', orientation, 3]);

        var viewportSize = $(window).width();
        var viewportGrouping = '1760 and higher';

        if (viewportSize < 481) {
            viewportGrouping = '0 - 480';
        } else if (viewportSize < 768) {
            viewportGrouping = '481 - 767';
        } else if (viewportSize < 1000) {
            viewportGrouping = '768 - 999';
        } else if (viewportSize < 1201) {
            viewportGrouping = '1000 - 1200';
        } else if (viewportSize < 1760) {
            viewportGrouping = '1201 - 1759';
        }

        _gaq.push(['_setCustomVar', 7, 'Viewport Size', viewportGrouping, 3]);

        if (typeof window.devicePixelRatio !== 'undefined' && window.devicePixelRatio >= 1.5) {
            _gaq.push(['_setCustomVar', 10, 'High Density Displays', 'High', 2]);
        } else {
            _gaq.push(['_setCustomVar', 10, 'High Density Displays', 'Low', 2]);
        }

        if ('ontouchstart' in document.documentElement) {
            _gaq.push(['_setCustomVar', 11, 'Touch screens', 'Touch', 2]);
        } else {
            _gaq.push(['_setCustomVar', 11, 'Touch screens', 'Traditional', 2]);
        }

        _gaq.push(['_trackPageview']);

        (function() {
            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
        })();
    }

    /*
     * Comscore
     */
    var setupComscore = function() {
        var _comscore = _comscore || [];
        _comscore.push({ c1: "2", c2: "17691522" });

        (function() {
            var s = document.createElement("script"), el = document.getElementsByTagName("script")[0]; s.async = true;
            s.src = (document.location.protocol == "https:" ? "https://sb" : "http://b") + ".scorecardresearch.com/beacon.js";
            el.parentNode.insertBefore(s, el);
        })();
    }

    /*
     * Nielson
     */
    var setupNielson = function() {
        (function () {
            var d = new Image(1, 1);
            d.onerror = d.onload = function () { d.onerror = d.onload = null; };
            d.src = ["//secure-us.imrworldwide.com/cgi-bin/m?ci=us-803244h&cg=0&cc=1&si=", escape(window.location.href), "&rp=", escape(document.referrer), "&ts=compact&rnd=", (new Date()).getTime()].join('');
        })();
    }

    /*
     * Chartbeat
     */
    var setupChartbeat = function() {
        /** CONFIGURATION START **/
        _sf_async_config.uid = 18888;
        _sf_async_config.domain = "npr.org";
        /** CONFIGURATION END **/
        (function(){
            function loadChartbeat() {
                window._sf_endpt=(new Date()).getTime();
                var e = document.createElement("script");
                e.setAttribute("language", "javascript");
                e.setAttribute("type", "text/javascript");
                e.setAttribute("src",
                    (("https:" == document.location.protocol) ?
                     "https://a248.e.akamai.net/chartbeat.download.akamai.com/102508/" :
                     "http://static.chartbeat.com/") +
                    "js/chartbeat.js");
                document.body.appendChild(e);
            }
            var oldonload = window.onload;
            window.onload = (typeof window.onload != "function") ?
                loadChartbeat : function() { oldonload(); loadChartbeat(); };
        })();
    }

    var setupAll = function() {
        setupGoogle();
        setupComscore();
        setupNielson();
        setupChartbeat();
    }

    /*
     * Event tracking.
     */
    var trackEvent = function(eventName, label, value, custom1, custom2) {
        var args = ['_trackEvent', APP_CONFIG.PROJECT_SLUG];

        args.push(eventName);

        if (label) {
            args.push(label);
        } else if (value || custom1 || custom2) {
            args.push('');
        }

        if (value) {
            args.push(value);
        } else if (custom1 || custom2) {
            args.push(0);
        }

        if (custom1) {
            args.push(custom1)
        } else if (custom2) {
            args.push('');
        }

        if (custom2) {
            args.push(custom2);
        }

        _gaq.push(args);
    }

    // SHARING

    var openShareDiscuss = function() {
        trackEvent('open-share-discuss');
    }

    var closeShareDiscuss = function() {
        trackEvent('close-share-discuss');
    }

    var clickTweet = function(location) {
        trackEvent('tweet', location);
    }

    var clickFacebook = function(location) {
        trackEvent('facebook', location);
    }

    var clickEmail = function(location) {
        trackEvent('email', location);
    }

    var postComment = function() {
        trackEvent('new-comment');
    }

    var actOnFeaturedTweet = function(action, tweet_url) {
        trackEvent('featured-tweet-action', action, null, tweet_url);
    }

    var actOnFeaturedFacebook = function(action, post_url) {
        trackEvent('featured-facebook-action', action, null, post_url);
    }

    var copySummary = function() {
        trackEvent('summary-copied');
    }

    // NAVIGATION
    var usedKeyboardNavigation = false;

    var useKeyboardNavigation = function() {
        if (!usedKeyboardNavigation) {
            trackEvent('keyboard-nav');
            usedKeyboardNavigation = true;
        }
    }

    var completeTwentyFivePercent =  function() {
        trackEvent('completion', '0.25');
    }

    var completeFiftyPercent =  function() {
        trackEvent('completion', '0.5');
    }

    var completeSeventyFivePercent =  function() {
        trackEvent('completion', '0.75');
    }

    var completeOneHundredPercent =  function() {
        trackEvent('completion', '1');
    }

    var startFullscreen = function() {
        trackEvent('fullscreen-start');
    }

    var stopFullscreen = function() {
        trackEvent('fullscreen-stop');
    }

    var begin = function(location) {
        trackEvent('begin', location);
    }

    var readyChromecast = function() {
        trackEvent('chromecast-ready');
    }

    var startChromecast = function() {
        trackEvent('chromecast-start');
    }

    var stopChromecast = function() {
        trackEvent('chromecast-stop');
    }

    // SLIDES

    var exitSlide = function(slide_index, last_slide_exit_event) {
        var currentTime = new Date();
        timeOnLastSlide = Math.abs(currentTime - slideStartTime);
        slideStartTime = currentTime;
        trackEvent('slide-exit', slide_index, timeOnLastSlide, last_slide_exit_event);
    }

    return {
        'setupAll': setupAll,
        'trackEvent': trackEvent,
        'openShareDiscuss': openShareDiscuss,
        'closeShareDiscuss': closeShareDiscuss,
        'clickTweet': clickTweet,
        'clickFacebook': clickFacebook,
        'clickEmail': clickEmail,
        'postComment': postComment,
        'actOnFeaturedTweet': actOnFeaturedTweet,
        'actOnFeaturedFacebook': actOnFeaturedFacebook,
        'copySummary': copySummary,
        'useKeyboardNavigation': useKeyboardNavigation,
        'completeTwentyFivePercent': completeTwentyFivePercent,
        'completeFiftyPercent': completeFiftyPercent,
        'completeSeventyFivePercent': completeSeventyFivePercent,
        'completeOneHundredPercent': completeOneHundredPercent,
        'exitSlide': exitSlide,
        'startFullscreen': startFullscreen,
        'stopFullscreen': stopFullscreen,
        'begin': begin,
        'readyChromecast': readyChromecast,
        'startChromecast': startChromecast,
        'stopChromecast': stopChromecast
    };
}());

ANALYTICS.setupAll();
<|endoftext|>


<commit_before>var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var minifyHtml = require('gulp-minify-html');

var dev_folder = "./public/dev/";
var build_folder = "./public/build/";

var paths = {
    "dev": {
        "styles": [
            dev_folder + "static/styles/**/*.css",
            dev_folder + "static/styles/**/*.scss",
        ],
        "scripts": [
            dev_folder + "static/scripts/**/*.js",
        ],
        "views": [
            dev_folder + "views/**/*.html",
        ],
        "ext": [
            dev_folder + "ext/**/*.*",
        ]
    },
    "build": {
        "styles": build_folder + "static/styles",
        "scripts": build_folder + "static/scripts",
        "libs": build_folder + "static/libs",
        "views": build_folder + "views",
        "ext": build_folder
    }
};

gulp.task('styles', function () {
    gulp
        .src(paths.dev.styles)
        .pipe(sass({
            outputStyle: 'compressed'
        }).on('error', sass.logError))
        .pipe(gulp.dest(paths.build.styles));
});

gulp.task('scripts', function () {
    gulp
        .src(paths.dev.scripts)
        .pipe(uglify())
        .pipe(gulp.dest(paths.build.scripts));
});

gulp.task('libs', function () {
    gulp
        .src([
            '../../node_modules/jquery/dist/jquery.min.js',
            '../../node_modules/jquery-pjax/jquery.pjax.js',
            '../../node_modules/highlightjs/highlight.pack.min.js',
            '../../node_modules/nprogress/nprogress.js',
            '../../node_modules/moment/min/moment.min.js',
            '../../node_modules/marked/marked.min.js',
            '../../node_modules/chart.js/Chart.min.js'
        ])
        .pipe(concat('djacket-libs.js'))
        .pipe(uglify())
        .pipe(gulp.dest(paths.build.libs));

    gulp
        .src([
            '../../node_modules/font-awesome/css/font-awesome.min.css',
            '../../node_modules/devicons/css/devicons.min.css',
            '../../node_modules/nprogress/nprogress.css',
            '../../node_modules/highlightjs/styles/monokai-sublime.css'
        ])
        .pipe(concat('djacket-libs.css'))
        .pipe(sass({
            outputStyle: 'compressed'
        }).on('error', sass.logError))
        .pipe(gulp.dest(paths.build.libs));
});

gulp.task('views', function () {
    gulp
        .src(paths.dev.views)
        .pipe(minifyHtml({empty: true}))
        .pipe(gulp.dest(paths.build.views));
});

gulp.task('ext', function () {
    gulp
        .src(paths.dev.ext)
        .pipe(gulp.dest(paths.build.ext))
})

gulp.task('watch', function () {
    gulp.watch([paths.dev.styles, paths.dev.scripts, paths.dev.views], ['styles', 'scripts', 'views']);
});

gulp.task('default', ['compile', 'watch']);    // Default task is for watching development folder for any changes.

gulp.task('compile', ['styles', 'scripts', 'libs', 'views', 'ext']);   // Compile task will run all necessary tasks for frontend.
<commit_msg>destination for ext building folder in gulpfile fixed.<commit_after>var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var minifyHtml = require('gulp-minify-html');

var dev_folder = "./public/dev/";
var build_folder = "./public/build/";

var paths = {
    "dev": {
        "styles": [
            dev_folder + "static/styles/**/*.css",
            dev_folder + "static/styles/**/*.scss",
        ],
        "scripts": [
            dev_folder + "static/scripts/**/*.js",
        ],
        "views": [
            dev_folder + "views/**/*.html",
        ],
        "ext": [
            dev_folder + "ext/**/*.*",
        ]
    },
    "build": {
        "styles": build_folder + "static/styles",
        "scripts": build_folder + "static/scripts",
        "libs": build_folder + "static/libs",
        "views": build_folder + "views",
        "ext": build_folder + "static"
    }
};

gulp.task('styles', function () {
    gulp
        .src(paths.dev.styles)
        .pipe(sass({
            outputStyle: 'compressed'
        }).on('error', sass.logError))
        .pipe(gulp.dest(paths.build.styles));
});

gulp.task('scripts', function () {
    gulp
        .src(paths.dev.scripts)
        .pipe(uglify())
        .pipe(gulp.dest(paths.build.scripts));
});

gulp.task('libs', function () {
    gulp
        .src([
            '../../node_modules/jquery/dist/jquery.min.js',
            '../../node_modules/jquery-pjax/jquery.pjax.js',
            '../../node_modules/highlightjs/highlight.pack.min.js',
            '../../node_modules/nprogress/nprogress.js',
            '../../node_modules/moment/min/moment.min.js',
            '../../node_modules/marked/marked.min.js',
            '../../node_modules/chart.js/Chart.min.js'
        ])
        .pipe(concat('djacket-libs.js'))
        .pipe(uglify())
        .pipe(gulp.dest(paths.build.libs));

    gulp
        .src([
            '../../node_modules/font-awesome/css/font-awesome.min.css',
            '../../node_modules/devicons/css/devicons.min.css',
            '../../node_modules/nprogress/nprogress.css',
            '../../node_modules/highlightjs/styles/monokai-sublime.css'
        ])
        .pipe(concat('djacket-libs.css'))
        .pipe(sass({
            outputStyle: 'compressed'
        }).on('error', sass.logError))
        .pipe(gulp.dest(paths.build.libs));
});

gulp.task('views', function () {
    gulp
        .src(paths.dev.views)
        .pipe(minifyHtml({empty: true}))
        .pipe(gulp.dest(paths.build.views));
});

gulp.task('ext', function () {
    gulp
        .src(paths.dev.ext)
        .pipe(gulp.dest(paths.build.ext))
})

gulp.task('watch', function () {
    gulp.watch([paths.dev.styles, paths.dev.scripts, paths.dev.views], ['styles', 'scripts', 'views']);
});

gulp.task('default', ['compile', 'watch']);    // Default task is for watching development folder for any changes.

gulp.task('compile', ['styles', 'scripts', 'libs', 'views', 'ext']);   // Compile task will run all necessary tasks for frontend.
<|endoftext|>


<commit_before>/*globals requireJS*/
/* jshint node:true */

/**
 * @author kecso / https://github.com/kecso
 */

global.TESTING = true;
global.WebGMEGlobal = {};

process.env.NODE_ENV = 'test';

//adding a local storage class to the global Namespace
var WebGME = require('../webgme'),
    gmeConfig = require('../config'),
    getGmeConfig = function () {
        'use strict';
        // makes sure that for each request it returns with a unique object and tests will not interfere
        if (!gmeConfig) {
            // if some tests are deleting or unloading the config
            gmeConfig = require('../config');
        }
        return JSON.parse(JSON.stringify(gmeConfig));
    },

    Commit = requireJS('common/storage/commit'),
    Local = requireJS('common/storage/local'),
    Cache = requireJS('common/storage/cache'),
    Logger = require('../src/server/logger'),
    logger = Logger.create('gme:test', {
        //patterns: ['gme:test:*cache'],
        transports: [{
            transportType: 'Console',
            options: {
                level: 'error',
                colorize: true,
                timestamp: true,
                prettyPrint: true,
                handleExceptions: true, // ignored by default when you create the logger, see the logger.create function
                exitOnError: false,
                depth: 2,
                debugStdout: true
            }
        }]
    }, false),
    Storage = function (options) {
        'use strict';
        options.logger = options.logger || logger.fork('storage');
        return new Commit(new Local(options || {}), options || {});
    },
    StorageWithCache = function (options) {
        'use strict';
        options.logger = options.logger || logger.fork('storage');
        return new Commit(new Cache(new Local(options || {}), options || {}), options || {});
    },
    generateKey = requireJS('common/util/key'),

    GMEAuth = require('../src/server/middleware/auth/gmeauth'),
    SessionStore = require('../src/server/middleware/auth/sessionstore'),

    ExecutorClient = requireJS('common/executor/ExecutorClient'),
    BlobClient = requireJS('blob/BlobClient'),
    openContext = requireJS('common/util/opencontext'),

    should = require('chai').should(),
    expect = require('chai').expect,

    superagent = require('superagent'),
    mongodb = require('mongodb'),
    Q = require('q'),
    fs = require('fs'),
    rimraf = require('rimraf'),
    childProcess = require('child_process');

//TODO globally used functions to implement
function loadJsonFile(path) {
    'use strict';
    //TODO decide if throwing an exception is fine or we should handle it
    return JSON.parse(fs.readFileSync(path, 'utf8'));
}
function importProject(parameters, done) {
    'use strict';
    //TODO should return a result object with storage + project + core + root + commitHash + branchName objects }
    //TODO by default it should create a localStorage and put the project there

    var result = {
            storage: {},
            root: {},
            commitHash: '',
            branchName: 'master',
            project: {},
            core: {}
        },
        contextParam = {};
    /*
     parameters:
     storage - a storage object, where the project should be created (if not given and mongoUri is not defined we
     create a new local one and use it
     filePath - the filePath, where we can find the project
     jsonProject - already loaded project
     projectName - the name of the project
     branchName - the branch name where we should import
     -*-*-*-*-*-*-yet-to-come-*-*-*-*-*-
     mongoUri - if the storage is not given, then we will create one to this given mongoDB
     clear - if set we will first delete the whole project from the storage or drop the collection from the mongoDB
     */

    /*
     result
     storage - the opened storage object (either mongoDB or local one)
     project - the project object pointing to the created project
     core - a core object created to use the project object
     branchName - the name of the created branch
     commitHash - the hash of the final commit
     root - the loaded final root node object
     jsonProject - the loaded project
     */

    //TODO should be written in promise style
    if (!parameters.jsonProject) {
        expect(typeof parameters.filePath).to.equal('string');
        result.jsonProject = loadJsonFile(parameters.filePath);
    } else {
        result.jsonProject = parameters.jsonProject;
    }

    expect(typeof parameters.projectName).to.equal('string');

    result.branchName = parameters.branchName || 'master';

    if (parameters.storage) {
        result.storage = parameters.storage;
    } else {
        if (!parameters.mongoUri) {
            result.storage = new Storage({
                globConf: parameters.gmeConfig,
                logger: logger.fork('storage')
            });
        } else {
            throw new Error('mongoUri option is not implemented yet.');
        }
    }

    contextParam = {
        projectName: parameters.projectName,
        overwriteProject: true,
        branchName: result.BranchName
    };

    openContext(result.storage, parameters.gmeConfig, logger, contextParam, function (err, context) {
        if (err) {
            done(err);
            return;
        }
        result.project = context.project;
        result.core = context.core;
        result.root = context.rootNode;

        WebGME.serializer.import(result.core,
            result.root,
            result.jsonProject,
            function (err) {
                if (err) {
                    done(err);
                    return;
                }
                result.core.persist(result.root, function (err) {
                    if (err) {
                        done(err);
                        return;
                    }

                    result.project.makeCommit(
                        [],
                        result.core.getHash(result.root),
                        'importing project',
                        function (err, id) {
                            if (err) {
                                done(err);
                                return;
                            }
                            result.commitHash = id;
                            result.project.getBranchNames(function (err, names) {
                                var oldHash = '';
                                if (err) {
                                    done(err);
                                    return;
                                }

                                if (names && names[result.branchName]) {
                                    oldHash = names[result.branchName];
                                }
                                //TODO check the branch naming... probably need to add some layer to the local storage
                                result.project.setBranchHash(result.branchName,
                                    oldHash,
                                    result.commitHash,
                                    function (err) {
                                        done(err, result);
                                    });
                            });
                        });
                });
            });
    });
}

function saveChanges(parameters, done) {
    'use strict';
    expect(typeof parameters.project).to.equal('object');
    expect(typeof parameters.core).to.equal('object');
    expect(typeof parameters.rootNode).to.equal('object');

    parameters.core.persist(parameters.rootNode, function (err) {
        var newRootHash;
        if (err) {
            done(err);
            return;
        }

        newRootHash = parameters.core.getHash(parameters.rootNode);
        parameters.project.makeCommit([], newRootHash, 'create empty project', function (err, commitHash) {
            if (err) {
                done(err);
                return;
            }

            parameters.project.setBranchHash(parameters.branchName || 'master', '', commitHash, function (err) {
                if (err) {
                    done(err);
                    return;
                }
                done(null, newRootHash, commitHash);
            });
        });
    });
}

function checkWholeProject(/*parameters, done*/) {
    //TODO this should export the given project and check against a file or a jsonObject to be deeply equal
}

function exportProject(/*parameters, done*/) {
    //TODO gives back a jsonObject which is the export of the project
    //should work with project object, or mongoUri as well
    //in case of mongoUri it should open the connection before and close after - or just simply use the exportCLI
}

function deleteProject(/*parameters, done*/) {
    //TODO should work with storage object and mongoUri although probably we only need to delete if we use mongo
}

WebGME.addToRequireJsPaths(gmeConfig);

// This is for the client side test-cases (only add paths here!)
requireJS.config({
    paths: {
        js: 'client/js',
        ' /socket.io/socket.io.js': 'socketio-client',
        underscore: 'client/lib/underscore/underscore-min'
    }
});

module.exports = {
    getGmeConfig: getGmeConfig,

    WebGME: WebGME,
    Storage: Storage,
    StorageWithCache: StorageWithCache,
    Logger: Logger,
    // test logger instance, used by all tests and only tests
    logger: logger,
    generateKey: generateKey,

    GMEAuth: GMEAuth,
    SessionStore: SessionStore,

    ExecutorClient: ExecutorClient,
    BlobClient: BlobClient,

    requirejs: requireJS,
    Q: Q,
    fs: fs,
    superagent: superagent,
    mongodb: mongodb,
    rimraf: rimraf,
    childProcess: childProcess,

    should: should,
    expect: expect,

    loadJsonFile: loadJsonFile,
    importProject: importProject,
    checkWholeProject: checkWholeProject,
    exportProject: exportProject,
    deleteProject: deleteProject,
    saveChanges: saveChanges,
    openContext: openContext
};
<commit_msg>Disable winston exception handling during tests.<commit_after>/*globals requireJS*/
/* jshint node:true */

/**
 * @author kecso / https://github.com/kecso
 */

global.TESTING = true;
global.WebGMEGlobal = {};

process.env.NODE_ENV = 'test';

//adding a local storage class to the global Namespace
var WebGME = require('../webgme'),
    gmeConfig = require('../config'),
    getGmeConfig = function () {
        'use strict';
        // makes sure that for each request it returns with a unique object and tests will not interfere
        if (!gmeConfig) {
            // if some tests are deleting or unloading the config
            gmeConfig = require('../config');
        }
        return JSON.parse(JSON.stringify(gmeConfig));
    },

    Commit = requireJS('common/storage/commit'),
    Local = requireJS('common/storage/local'),
    Cache = requireJS('common/storage/cache'),
    Logger = require('../src/server/logger'),
    logger = Logger.create('gme:test', {
        //patterns: ['gme:test:*cache'],
        transports: [{
            transportType: 'Console',
            options: {
                level: 'error',
                colorize: true,
                timestamp: true,
                prettyPrint: true,
                //handleExceptions: true, // ignored by default when you create the logger, see the logger.create function
                //exitOnError: false,
                depth: 2,
                debugStdout: true
            }
        }]
    }, false),
    Storage = function (options) {
        'use strict';
        options.logger = options.logger || logger.fork('storage');
        return new Commit(new Local(options || {}), options || {});
    },
    StorageWithCache = function (options) {
        'use strict';
        options.logger = options.logger || logger.fork('storage');
        return new Commit(new Cache(new Local(options || {}), options || {}), options || {});
    },
    generateKey = requireJS('common/util/key'),

    GMEAuth = require('../src/server/middleware/auth/gmeauth'),
    SessionStore = require('../src/server/middleware/auth/sessionstore'),

    ExecutorClient = requireJS('common/executor/ExecutorClient'),
    BlobClient = requireJS('blob/BlobClient'),
    openContext = requireJS('common/util/opencontext'),

    should = require('chai').should(),
    expect = require('chai').expect,

    superagent = require('superagent'),
    mongodb = require('mongodb'),
    Q = require('q'),
    fs = require('fs'),
    rimraf = require('rimraf'),
    childProcess = require('child_process');

//TODO globally used functions to implement
function loadJsonFile(path) {
    'use strict';
    //TODO decide if throwing an exception is fine or we should handle it
    return JSON.parse(fs.readFileSync(path, 'utf8'));
}
function importProject(parameters, done) {
    'use strict';
    //TODO should return a result object with storage + project + core + root + commitHash + branchName objects }
    //TODO by default it should create a localStorage and put the project there

    var result = {
            storage: {},
            root: {},
            commitHash: '',
            branchName: 'master',
            project: {},
            core: {}
        },
        contextParam = {};
    /*
     parameters:
     storage - a storage object, where the project should be created (if not given and mongoUri is not defined we
     create a new local one and use it
     filePath - the filePath, where we can find the project
     jsonProject - already loaded project
     projectName - the name of the project
     branchName - the branch name where we should import
     -*-*-*-*-*-*-yet-to-come-*-*-*-*-*-
     mongoUri - if the storage is not given, then we will create one to this given mongoDB
     clear - if set we will first delete the whole project from the storage or drop the collection from the mongoDB
     */

    /*
     result
     storage - the opened storage object (either mongoDB or local one)
     project - the project object pointing to the created project
     core - a core object created to use the project object
     branchName - the name of the created branch
     commitHash - the hash of the final commit
     root - the loaded final root node object
     jsonProject - the loaded project
     */

    //TODO should be written in promise style
    if (!parameters.jsonProject) {
        expect(typeof parameters.filePath).to.equal('string');
        result.jsonProject = loadJsonFile(parameters.filePath);
    } else {
        result.jsonProject = parameters.jsonProject;
    }

    expect(typeof parameters.projectName).to.equal('string');

    result.branchName = parameters.branchName || 'master';

    if (parameters.storage) {
        result.storage = parameters.storage;
    } else {
        if (!parameters.mongoUri) {
            result.storage = new Storage({
                globConf: parameters.gmeConfig,
                logger: logger.fork('storage')
            });
        } else {
            throw new Error('mongoUri option is not implemented yet.');
        }
    }

    contextParam = {
        projectName: parameters.projectName,
        overwriteProject: true,
        branchName: result.BranchName
    };

    openContext(result.storage, parameters.gmeConfig, logger, contextParam, function (err, context) {
        if (err) {
            done(err);
            return;
        }
        result.project = context.project;
        result.core = context.core;
        result.root = context.rootNode;

        WebGME.serializer.import(result.core,
            result.root,
            result.jsonProject,
            function (err) {
                if (err) {
                    done(err);
                    return;
                }
                result.core.persist(result.root, function (err) {
                    if (err) {
                        done(err);
                        return;
                    }

                    result.project.makeCommit(
                        [],
                        result.core.getHash(result.root),
                        'importing project',
                        function (err, id) {
                            if (err) {
                                done(err);
                                return;
                            }
                            result.commitHash = id;
                            result.project.getBranchNames(function (err, names) {
                                var oldHash = '';
                                if (err) {
                                    done(err);
                                    return;
                                }

                                if (names && names[result.branchName]) {
                                    oldHash = names[result.branchName];
                                }
                                //TODO check the branch naming... probably need to add some layer to the local storage
                                result.project.setBranchHash(result.branchName,
                                    oldHash,
                                    result.commitHash,
                                    function (err) {
                                        done(err, result);
                                    });
                            });
                        });
                });
            });
    });
}

function saveChanges(parameters, done) {
    'use strict';
    expect(typeof parameters.project).to.equal('object');
    expect(typeof parameters.core).to.equal('object');
    expect(typeof parameters.rootNode).to.equal('object');

    parameters.core.persist(parameters.rootNode, function (err) {
        var newRootHash;
        if (err) {
            done(err);
            return;
        }

        newRootHash = parameters.core.getHash(parameters.rootNode);
        parameters.project.makeCommit([], newRootHash, 'create empty project', function (err, commitHash) {
            if (err) {
                done(err);
                return;
            }

            parameters.project.setBranchHash(parameters.branchName || 'master', '', commitHash, function (err) {
                if (err) {
                    done(err);
                    return;
                }
                done(null, newRootHash, commitHash);
            });
        });
    });
}

function checkWholeProject(/*parameters, done*/) {
    //TODO this should export the given project and check against a file or a jsonObject to be deeply equal
}

function exportProject(/*parameters, done*/) {
    //TODO gives back a jsonObject which is the export of the project
    //should work with project object, or mongoUri as well
    //in case of mongoUri it should open the connection before and close after - or just simply use the exportCLI
}

function deleteProject(/*parameters, done*/) {
    //TODO should work with storage object and mongoUri although probably we only need to delete if we use mongo
}

WebGME.addToRequireJsPaths(gmeConfig);

// This is for the client side test-cases (only add paths here!)
requireJS.config({
    paths: {
        js: 'client/js',
        ' /socket.io/socket.io.js': 'socketio-client',
        underscore: 'client/lib/underscore/underscore-min'
    }
});

module.exports = {
    getGmeConfig: getGmeConfig,

    WebGME: WebGME,
    Storage: Storage,
    StorageWithCache: StorageWithCache,
    Logger: Logger,
    // test logger instance, used by all tests and only tests
    logger: logger,
    generateKey: generateKey,

    GMEAuth: GMEAuth,
    SessionStore: SessionStore,

    ExecutorClient: ExecutorClient,
    BlobClient: BlobClient,

    requirejs: requireJS,
    Q: Q,
    fs: fs,
    superagent: superagent,
    mongodb: mongodb,
    rimraf: rimraf,
    childProcess: childProcess,

    should: should,
    expect: expect,

    loadJsonFile: loadJsonFile,
    importProject: importProject,
    checkWholeProject: checkWholeProject,
    exportProject: exportProject,
    deleteProject: deleteProject,
    saveChanges: saveChanges,
    openContext: openContext
};
<|endoftext|>


<commit_before>import {map} from 'event-stream';
import promisify from 'es6-promisify';
import path from 'path';
import through from 'through2';

import {getNewVersion} from './version-helper';
import {getAllComponents} from './git-helper';

const exec = promisify(require('child_process').exec);
const read = promisify(require('vinyl-file').read);

export async function componentsWithChanges() {
  return await getAllComponents();
}

function packageNameOf(componentPath) {
  if (componentPath.match(/src\/pivotal-ui\/components\//)) {
    return `pui-css-${path.basename(componentPath)}`;
  }
  else if (componentPath.match(/src\/pivotal-ui-react\//)) {
    return `pui-react-${path.basename(componentPath)}`;
  }
  else if (componentPath === './') {
    return 'pivotal-ui-root-package';
  }
  else {
    console.error(`Unknown componentPath ${componentPath}`);
    throw new Error(`Unknown componentPath ${componentPath}`);
  }
}

async function componentsDependentOn(componentPath) {
  const command = `git grep --files-with-matches ${packageNameOf(componentPath)} src/pivotal-ui-react/*/package.json src/pivotal-ui/components/*/package.json package.json`;
  try {
    return (await exec(command)).trim().split('\n')
      .map((filename) => path.dirname(filename) + path.sep);
  }
  catch(error) {
    if (error.code === 1) { // git grep returns no results
      return [];
    }
    throw error;
  }
}

export function componentsToUpdate() {
  const componentsToLookThrough = [];
  const componentsToUpdate = {};

  return through.obj(
    function(componentWithChanges, encoding, callback) {
      componentsToLookThrough.push(componentWithChanges.toString());
      componentsToUpdate[componentWithChanges] = [];
      callback();
    },

    async function(callback) {
      try {
        let component;
        while (Boolean(component = componentsToLookThrough.shift())) {
          for (const dependentComponent of (await componentsDependentOn(component))) {
            if (!componentsToUpdate[dependentComponent]) {
              componentsToLookThrough.push(dependentComponent);
              componentsToUpdate[dependentComponent] = [];
            }
            componentsToUpdate[dependentComponent].push(packageNameOf(component));
          }
        }

        for (component of Object.keys(componentsToUpdate)) {
          this.push({
            component: component,
            dependencies: componentsToUpdate[component]
          });
        }
        callback();
      }
      catch(error) {
        console.error(error.stack);
        callback(error);
      }
    }
  );
}

export function updatePackageJsons() {
  return map(async ({component, dependencies}, callback) => {
    try {
      const packageJsonPath = path.join(component, 'package.json');
      const packageJsonFile = await read(packageJsonPath);
      const packageJsonContents = JSON.parse(packageJsonFile.contents.toString());

      const version = getNewVersion();
      packageJsonContents.version = version;
      for (let dependency of dependencies) {
        packageJsonContents.dependencies[dependency] = `^${version}`;
      }

      packageJsonFile.contents = new Buffer(JSON.stringify(packageJsonContents, null, 2));
      callback(null, packageJsonFile);
    } catch(error) {
      console.error(error.stack);
      callback(error);
    }
  });
}
<commit_msg>Use = instead of ^ for package versions<commit_after>import {map} from 'event-stream';
import promisify from 'es6-promisify';
import path from 'path';
import through from 'through2';

import {getNewVersion} from './version-helper';
import {getAllComponents} from './git-helper';

const exec = promisify(require('child_process').exec);
const read = promisify(require('vinyl-file').read);

export async function componentsWithChanges() {
  return await getAllComponents();
}

function packageNameOf(componentPath) {
  if (componentPath.match(/src\/pivotal-ui\/components\//)) {
    return `pui-css-${path.basename(componentPath)}`;
  }
  else if (componentPath.match(/src\/pivotal-ui-react\//)) {
    return `pui-react-${path.basename(componentPath)}`;
  }
  else if (componentPath === './') {
    return 'pivotal-ui-root-package';
  }
  else {
    console.error(`Unknown componentPath ${componentPath}`);
    throw new Error(`Unknown componentPath ${componentPath}`);
  }
}

async function componentsDependentOn(componentPath) {
  const command = `git grep --files-with-matches ${packageNameOf(componentPath)} src/pivotal-ui-react/*/package.json src/pivotal-ui/components/*/package.json package.json`;
  try {
    return (await exec(command)).trim().split('\n')
      .map((filename) => path.dirname(filename) + path.sep);
  }
  catch(error) {
    if (error.code === 1) { // git grep returns no results
      return [];
    }
    throw error;
  }
}

export function componentsToUpdate() {
  const componentsToLookThrough = [];
  const componentsToUpdate = {};

  return through.obj(
    function(componentWithChanges, encoding, callback) {
      componentsToLookThrough.push(componentWithChanges.toString());
      componentsToUpdate[componentWithChanges] = [];
      callback();
    },

    async function(callback) {
      try {
        let component;
        while (Boolean(component = componentsToLookThrough.shift())) {
          for (const dependentComponent of (await componentsDependentOn(component))) {
            if (!componentsToUpdate[dependentComponent]) {
              componentsToLookThrough.push(dependentComponent);
              componentsToUpdate[dependentComponent] = [];
            }
            componentsToUpdate[dependentComponent].push(packageNameOf(component));
          }
        }

        for (component of Object.keys(componentsToUpdate)) {
          this.push({
            component: component,
            dependencies: componentsToUpdate[component]
          });
        }
        callback();
      }
      catch(error) {
        console.error(error.stack);
        callback(error);
      }
    }
  );
}

export function updatePackageJsons() {
  return map(async ({component, dependencies}, callback) => {
    try {
      const packageJsonPath = path.join(component, 'package.json');
      const packageJsonFile = await read(packageJsonPath);
      const packageJsonContents = JSON.parse(packageJsonFile.contents.toString());

      const version = getNewVersion();
      packageJsonContents.version = version;
      for (let dependency of dependencies) {
        packageJsonContents.dependencies[dependency] = `=${version}`;
      }

      packageJsonFile.contents = new Buffer(JSON.stringify(packageJsonContents, null, 2));
      callback(null, packageJsonFile);
    } catch(error) {
      console.error(error.stack);
      callback(error);
    }
  });
}
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Utils = require('../../renderer/webgl/Utils');

/**
 * Renders this Game Object with the WebGL Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method Phaser.Tilemaps.DynamicTilemapLayer#renderWebGL
 * @since 3.0.0
 * @private
 *
 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
 * @param {Phaser.Tilemaps.DynamicTilemapLayer} src - The Game Object being rendered in this call.
 * @param {number} interpolationPercentage - Reserved for future use and custom pipelines.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 */
var DynamicTilemapLayerWebGLRenderer = function (renderer, src, interpolationPercentage, camera)
{
    src.cull(camera);

    var renderTiles = src.culledTiles;
    var tileCount = renderTiles.length;
    var alpha = camera.alpha * src.alpha;

    if (tileCount === 0 || alpha <= 0)
    {
        return;
    }

    var gidMap = src.gidMap;
    var pipeline = src.pipeline;

    var getTint = Utils.getTintAppendFloatAlphaAndSwap;

    var scrollFactorX = src.scrollFactorX;
    var scrollFactorY = src.scrollFactorY;

    var x = src.x;
    var y = src.y;

    var sx = src.scaleX;
    var sy = src.scaleY;

    var tilesets = src.tileset;

    //  Loop through each tileset in this layer, drawing just the tiles that are in that set each time
    //  Doing it this way around allows us to batch tiles using the same tileset
    for (var c = 0; c < tilesets.length; c++)
    {
        var currentSet = tilesets[c];
        var texture = currentSet.glTexture;

        for (var i = 0; i < tileCount; i++)
        {
            var tile = renderTiles[i];

            var tileset = gidMap[tile.index];

            if (tileset !== currentSet)
            {
                //  Skip tiles that aren't in this set
                continue;
            }

            var tileTexCoords = tileset.getTileTextureCoordinates(tile.index);

            if (tileTexCoords === null)
            {
                continue;
            }

            var frameWidth = 0;
            var frameHeight = 0;

            if (src.layer.orientation === 'isometric')
            {
                // we use the tileset width and height because in isometric maps the tileset's height is often different from the tilemap's.
                frameWidth = tileset.tileWidth;
                frameHeight = tileset.tileHeight;
            }
            else
            {
                frameWidth = tile.width;
                frameHeight = tile.height;
            }

            var frameX = tileTexCoords.x;
            var frameY = tileTexCoords.y;

            var tw = frameWidth * 0.5;
            var th = frameHeight * 0.5;

            var tint = getTint(tile.tint, alpha * tile.alpha);

            pipeline.batchTexture(
                src,
                texture,
                texture.width, texture.height,
                x + ((tw + tile.pixelX) * sx), y + ((th + tile.pixelY) * sy),
                frameWidth, frameHeight,
                sx, sy,
                tile.rotation,
                tile.flipX, tile.flipY,
                scrollFactorX, scrollFactorY,
                tw, th,
                frameX, frameY, frameWidth, frameHeight,
                tint, tint, tint, tint, false,
                0, 0,
                camera,
                null,
                true
            );
        }
    }
};

module.exports = DynamicTilemapLayerWebGLRenderer;
<commit_msg>Update DynamicTilemapLayerWebGLRenderer.js<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Utils = require('../../renderer/webgl/Utils');

/**
 * Renders this Game Object with the WebGL Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method Phaser.Tilemaps.DynamicTilemapLayer#renderWebGL
 * @since 3.0.0
 * @private
 *
 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
 * @param {Phaser.Tilemaps.DynamicTilemapLayer} src - The Game Object being rendered in this call.
 * @param {number} interpolationPercentage - Reserved for future use and custom pipelines.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 */
var DynamicTilemapLayerWebGLRenderer = function (renderer, src, interpolationPercentage, camera)
{
    src.cull(camera);

    var renderTiles = src.culledTiles;
    var tileCount = renderTiles.length;
    var alpha = camera.alpha * src.alpha;

    if (tileCount === 0 || alpha <= 0)
    {
        return;
    }

    var gidMap = src.gidMap;
    var pipeline = src.pipeline;

    var getTint = Utils.getTintAppendFloatAlphaAndSwap;

    var scrollFactorX = src.scrollFactorX;
    var scrollFactorY = src.scrollFactorY;

    var x = src.x;
    var y = src.y;

    var sx = src.scaleX;
    var sy = src.scaleY;

    var tilesets = src.tileset;

    //  Loop through each tileset in this layer, drawing just the tiles that are in that set each time
    //  Doing it this way around allows us to batch tiles using the same tileset
    for (var c = 0; c < tilesets.length; c++)
    {
        var currentSet = tilesets[c];
        var texture = currentSet.glTexture;

        for (var i = 0; i < tileCount; i++)
        {
            var tile = renderTiles[i];

            var tileset = gidMap[tile.index];

            if (tileset !== currentSet)
            {
                //  Skip tiles that aren't in this set
                continue;
            }

            var tileTexCoords = tileset.getTileTextureCoordinates(tile.index);

            if (tileTexCoords === null)
            {
                continue;
            }

            var frameWidth = 0;
            var frameHeight = 0;

            if (src.layer.orientation === 'isometric')
            {
                // we use the tileset width and height because in isometric maps the tileset's height is often different from the tilemap's.
                frameWidth = tileset.tileWidth;
                frameHeight = tileset.tileHeight;
            }
            else
            {
                frameWidth = tile.width;
                frameHeight = tile.height;
            }

            var frameX = tileTexCoords.x;
            var frameY = tileTexCoords.y;

            var tw = frameWidth * 0.5;
            var th = frameHeight * 0.5;

            var tint = getTint(tile.tint, alpha * tile.alpha);

            pipeline.batchTexture(
                src,
                texture,
                texture.width, texture.height,
                x + ((tw + tile.pixelX) * sx), y + ((th + tile.pixelY) * sy),
                frameWidth, frameHeight,
                sx, sy,
                tile.rotation,
                tile.flipX, tile.flipY,
                scrollFactorX, scrollFactorY,
                tw, th,
                frameX, frameY, frameWidth, frameHeight,
                tint, tint, tint, tint, false,
                0, 0,
                camera,
                null,
                true
            );
        }
    }
};

module.exports = DynamicTilemapLayerWebGLRenderer;
<|endoftext|>


<commit_before>'use stict';

var execSync = require('child_process').execSync;
var fs = require('fs');
var chalk = require('chalk');
var readPkg = require('read-pkg-up').sync;
var semver = require('semver');
var stripEof = require('strip-eof');

module.exports = {
	capitalize: function (str) {
		return str.charAt(0).toUpperCase() + str.slice(1);
	},

	checkDirectory: function (dir) {
		try {
			fs.statSync(dir);
		} catch (err) {
			this.error('no such file or directory: ' + dir, 1);
		}

		if (!fs.statSync(dir).isDirectory()) {
			this.error('not a directory: ' + dir, 1);
		}
	},

	checkGitExec: function () {
		this.exec('git --version', {stdio: 'ignore'}, 'Missing required executable: git');
	},

	checkGitRepo: function () {
		this.log('Checking if "' + chalk.cyan(process.cwd()) + '" is a Git repository ...');
		this.exec('git rev-parse', {stdio: ['ignore', 'ignore', 'pipe']});
	},

	error: function (msg, code) {
		var err = chalk.red.bold;
		console.log(err(msg));
		console.log(err('Aborting.'));
		process.exit(code);
	},

	exec: function (cmd, opts, msg) {
		try {
			var rs = execSync(cmd, opts);
			return rs && stripEof(rs).toString();
		} catch (err) {
			this.error(msg || stripEof(err.stderr).toString().split(/\r?\n/)[0], err.status || 1);
		}
	},

	format: function (commits) {
		return commits.map(function (commit) {
			return '  * ' + commit;
		}).join('\n') + '\n\n';
	},

	getHeader: function (header, release) {
		header = header || '@RELEASE / @DATE\n==================\n\n';
		return header
			.replace('@RELEASE', release)
			.replace('@DATE', this.today());
	},

	getHomePage: function () {
		var originUrl = this.exec('git config --get remote.origin.url');
		var regex = /^git@[^:]+:[^\/]+\/.+/i;

		if (regex.test(originUrl)) {
			originUrl = originUrl
				.replace(':', '/')
				.replace('git@', 'https://');
		}

		return originUrl.replace('.git', '/');
	},

	getLog: function (commitish, format) {
		var rs;
		var tag;
		format = format || '%s';

		if (!commitish) {
			tag = this.getTag();
			commitish = tag && tag + '..HEAD';
		}

		this.log('Getting the list of commits...');

		rs = this.exec('git log ' + commitish + ' --no-merges --pretty=format:"' + format + '"',
					{stdio: ['ignore', 'pipe', 'pipe']});
		if (!rs) {
			this.error('No commits found', 1);
		}

		return rs;
	},

	getTag: function () {
		var commithash;
		try {
			commithash = execSync('git rev-list --tags --max-count=1',
						{stdio: ['ignore', 'pipe', 'ignore']});
		} catch (err) {
			return '';
		}

		return this.exec('git describe --tags ' + commithash);
	},

	getVersion: function (release) {
		if (release) {
			if (semver.valid(release) === null) {
				this.warn('"' + release + '" is not valid semver. Using the one in `package.json`.\n');
			} else {
				return release;
			}
		}

		var pkg = readPkg().pkg;
		var version = pkg ? pkg.version : 'x.x.x';
		return version.replace('-pre', '');
	},

	log: function (msg) {
		if (!this.verbose) {
			return;
		}

		console.log(msg || '');
	},

	section: function (sect) {
		this.log();
		this.log(chalk.blue.bold('→ ') + chalk.magenta(sect));
		this.log();
	},

	today: function () {
		return new Date().toISOString().replace(/T.+/, '');
	},

	warn: function (msg) {
		console.log(chalk.yellow('WARN: ' + msg));
	}
};
<commit_msg>Suppress `xo/no-process-exit` rule<commit_after>'use stict';

var execSync = require('child_process').execSync;
var fs = require('fs');
var chalk = require('chalk');
var readPkg = require('read-pkg-up').sync;
var semver = require('semver');
var stripEof = require('strip-eof');

module.exports = {
	capitalize: function (str) {
		return str.charAt(0).toUpperCase() + str.slice(1);
	},

	checkDirectory: function (dir) {
		try {
			fs.statSync(dir);
		} catch (err) {
			this.error('no such file or directory: ' + dir, 1);
		}

		if (!fs.statSync(dir).isDirectory()) {
			this.error('not a directory: ' + dir, 1);
		}
	},

	checkGitExec: function () {
		this.exec('git --version', {stdio: 'ignore'}, 'Missing required executable: git');
	},

	checkGitRepo: function () {
		this.log('Checking if "' + chalk.cyan(process.cwd()) + '" is a Git repository ...');
		this.exec('git rev-parse', {stdio: ['ignore', 'ignore', 'pipe']});
	},

	error: function (msg, code) {
		var err = chalk.red.bold;
		console.log(err(msg));
		console.log(err('Aborting.'));
		/* eslint xo/no-process-exit: 0 */
		process.exit(code);
	},

	exec: function (cmd, opts, msg) {
		try {
			var rs = execSync(cmd, opts);
			return rs && stripEof(rs).toString();
		} catch (err) {
			this.error(msg || stripEof(err.stderr).toString().split(/\r?\n/)[0], err.status || 1);
		}
	},

	format: function (commits) {
		return commits.map(function (commit) {
			return '  * ' + commit;
		}).join('\n') + '\n\n';
	},

	getHeader: function (header, release) {
		header = header || '@RELEASE / @DATE\n==================\n\n';
		return header
			.replace('@RELEASE', release)
			.replace('@DATE', this.today());
	},

	getHomePage: function () {
		var originUrl = this.exec('git config --get remote.origin.url');
		var regex = /^git@[^:]+:[^\/]+\/.+/i;

		if (regex.test(originUrl)) {
			originUrl = originUrl
				.replace(':', '/')
				.replace('git@', 'https://');
		}

		return originUrl.replace('.git', '/');
	},

	getLog: function (commitish, format) {
		var rs;
		var tag;
		format = format || '%s';

		if (!commitish) {
			tag = this.getTag();
			commitish = tag && tag + '..HEAD';
		}

		this.log('Getting the list of commits...');

		rs = this.exec('git log ' + commitish + ' --no-merges --pretty=format:"' + format + '"',
					{stdio: ['ignore', 'pipe', 'pipe']});
		if (!rs) {
			this.error('No commits found', 1);
		}

		return rs;
	},

	getTag: function () {
		var commithash;
		try {
			commithash = execSync('git rev-list --tags --max-count=1',
						{stdio: ['ignore', 'pipe', 'ignore']});
		} catch (err) {
			return '';
		}

		return this.exec('git describe --tags ' + commithash);
	},

	getVersion: function (release) {
		if (release) {
			if (semver.valid(release) === null) {
				this.warn('"' + release + '" is not valid semver. Using the one in `package.json`.\n');
			} else {
				return release;
			}
		}

		var pkg = readPkg().pkg;
		var version = pkg ? pkg.version : 'x.x.x';
		return version.replace('-pre', '');
	},

	log: function (msg) {
		if (!this.verbose) {
			return;
		}

		console.log(msg || '');
	},

	section: function (sect) {
		this.log();
		this.log(chalk.blue.bold('→ ') + chalk.magenta(sect));
		this.log();
	},

	today: function () {
		return new Date().toISOString().replace(/T.+/, '');
	},

	warn: function (msg) {
		console.log(chalk.yellow('WARN: ' + msg));
	}
};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2020 Nike, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React from 'react'
import { Component } from 'react'
import * as headerActions from '../../actions/headerActions'
import * as authActions from '../../actions/authenticationActions'
import './Header.scss'
import '../../assets/images/cerberus-logo-narrow-off-white.svg'
import * as modalActions from '../../actions/modalActions'
import ViewTokenModal from '../ViewTokenModal/ViewTokenModal'
import { push } from 'connected-react-router';

export default class Header extends Component {

    render() {
        return (

Cerberus

                    <UserBox userName={this.props.userName}
                             displayUserContextMenu={this.props.displayUserContextMenu}
                             dispatch={this.props.dispatch}
                             cerberusAuthToken={this.props.cerberusAuthToken}
                             isAdmin={this.props.isAdmin}/>

        )
    }
}

class UserBox extends Component {

    constructor(props) {
        super(props)

        this.handleMouseClickUserName = function() {
            this.props.dispatch(headerActions.mouseOverUsername())
        }.bind(this)

        this.handleMouseLeaveUserMenuContext = function() {
            this.props.dispatch(headerActions.mouseOutUsername())
        }.bind(this)

        this.handleMouseClickViewToken = function() {
            this.props.dispatch(modalActions.pushModal(<ViewTokenModal />))
        }.bind(this)

        this.handleMouseClickLogout = function() {
            this.props.dispatch(authActions.logoutUser(this.props.cerberusAuthToken))
        }.bind(this)
    }

    render() {
        let isAdmin = this.props.isAdmin

        return (

{this.props.userName}

                    {isAdmin &&
 {push('/admin/sdb-metadata')}}>SDB Summary
}

View Token

Logout

        )
    }
}
<commit_msg>fix: admin metadata dashboard issue<commit_after>/*
 * Copyright (c) 2020 Nike, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React from 'react'
import { Component } from 'react'
import * as headerActions from '../../actions/headerActions'
import * as authActions from '../../actions/authenticationActions'
import './Header.scss'
import '../../assets/images/cerberus-logo-narrow-off-white.svg'
import * as modalActions from '../../actions/modalActions'
import ViewTokenModal from '../ViewTokenModal/ViewTokenModal'
import { push } from 'connected-react-router';

export default class Header extends Component {

    render() {
        return (

Cerberus

                    <UserBox userName={this.props.userName}
                             displayUserContextMenu={this.props.displayUserContextMenu}
                             dispatch={this.props.dispatch}
                             cerberusAuthToken={this.props.cerberusAuthToken}
                             isAdmin={this.props.isAdmin}/>

        )
    }
}

class UserBox extends Component {

    constructor(props) {
        super(props)

        this.handleMouseClickUserName = function() {
            this.props.dispatch(headerActions.mouseOverUsername())
        }.bind(this)

        this.handleMouseLeaveUserMenuContext = function() {
            this.props.dispatch(headerActions.mouseOutUsername())
        }.bind(this)

        this.handleMouseClickSdbSummary = function() {
            this.props.dispatch(push('/admin/sdb-metadata'))
        }.bind(this)

        this.handleMouseClickViewToken = function() {
            this.props.dispatch(modalActions.pushModal(<ViewTokenModal />))
        }.bind(this)

        this.handleMouseClickLogout = function() {
            this.props.dispatch(authActions.logoutUser(this.props.cerberusAuthToken))
        }.bind(this)
    }

    render() {
        let isAdmin = this.props.isAdmin

        return (

{this.props.userName}

                    {isAdmin &&
SDB Summary
}

View Token

Logout

        )
    }
}
<|endoftext|>


<commit_before>/*!
 * angular-katex v0.8.1
 * https://github.com/tfoxy/angular-katex
 *
 * Copyright 2015 Tomás Fox
 * Released under the MIT license
 */
!function(){"use strict";function e(){return"undefined"!=typeof renderMathInElement?renderMathInElement:void 0}function n(e,n){var t={$get:function(){return t},defaultOptions:{},errorElement:'',errorHandler:function(e,n,r){var a=angular.element(t.errorElement);a.text(e),r.children().remove(),r.append(a)},render:function(n,r,a,o){try{var i=a||t.defaultOptions;e.render(r||"",n[0],i)}catch(u){o(u,r,n)}},autoRender:function(e,r,a){try{var o=r||t.defaultOptions;n(e[0],o)}catch(i){a(i,null,e)}}};return t}function t(e,n){return{restrict:"AE",compile:function(t,r){var i=a(n,r),u=o(n,r,e);if("katexAutoRender"in r)e.autoRender(t,i,u);else{var c=r.katex||t.text();e.render(t,c,i,u)}}}}function r(e){return{restrict:"A",link:function(n,t,r){var i=o(n,r,e);n.$watch(r.katexBind,function(o){var u=a(n,r);"katexAutoRender"in r?(t.text(o),e.autoRender(t,u,i)):e.render(t,o,u,i)})}}}function a(e,n){var t=n.katexOptions;return t&&e.$eval(t)}function o(e,n,t){return"katexOnError"in n?function(t,r,a){e.$eval(n.katexOnError,{$err:t,$expr:r,$setText:function(e){a.text(e)}})}:t.errorHandler}angular.module("katex",[]).constant("katex",katex).constant("renderMathInElement",e()).provider("katexConfig",n).directive("katex",t).directive("katexBind",r),n.$inject=["katex","renderMathInElement"],t.$inject=["katexConfig","$rootScope"],r.$inject=["katexConfig"]}();<commit_msg>Minify<commit_after>/*!
 * angular-katex v0.9.0
 * https://github.com/tfoxy/angular-katex
 *
 * Copyright 2015 Tomás Fox
 * Released under the MIT license
 */
!function(){"use strict";function e(){return"undefined"!=typeof renderMathInElement?renderMathInElement:void 0}function n(e,n){function t(e,n){var t=angular.extend({},i.defaultOptions);return"options"in n&&angular.extend(t,e.$eval(n.options)),"katexOptions"in n&&angular.extend(t,e.$eval(n.katexOptions)),"displayMode"in n&&angular.extend(t,{displayMode:!0}),t}function r(e,n){return"onError"in n||"katexOnError"in n?function(t,r,i){e.$eval(n.onError||n.katexOnError,{$err:t,$expr:r,$setText:function(e){i.text(e)}})}:i.errorHandler}var i={$get:function(){return i},defaultOptions:{},errorElement:'',errorHandler:function(e,n,t){var r=angular.element(i.errorElement);r.text(e),t.children().remove(),t.append(r)},render:function(n,i,a,o){try{var u=t(a,o);e.render(i||"",n[0],u)}catch(d){r(a,o)(d,i,n)}},autoRender:function(e,i,a){try{var o=t(i,a);n(e[0],o)}catch(u){r(i,a)(u,null,e)}}};return i}function t(e,n){function t(t,a){if("bind"in a)return r;var o;if("expr"in a||a.katex)o=a.expr||a.katex,i(n,a)&&(o=angular.element("
"+o+"
").html());else{if("autoRender"in a||"katexAutoRender"in a)return void e.autoRender(t,n,a);o=i(n,a)?t.html():t.text()}e.render(t,o,n,a)}function r(n,t,r){"autoRender"in r||"katexAutoRender"in r?n.$watch(r.bind,function(i){a(n,r)?t.text(i):t.html(i),e.autoRender(t,n,r)}):n.$watch(r.bind,function(i){e.render(t,i,n,r)})}return{restrict:"AE",compile:t}}function r(e){return{restrict:"A",link:function(n,t,r){n.$watch(r.katexBind,function(i){"autoRender"in r||"katexAutoRender"in r?(t.text(i),e.autoRender(t,n,r)):e.render(t,i,n,r)})}}}function i(e,n){return"htmlMode"in n&&(!n.htmlMode||e.$eval(n.htmlMode))}function a(e,n){return"htmlMode"in n&&!e.$eval(n.htmlMode)}angular.module("katex",[]).constant("katex",katex).constant("renderMathInElement",e()).provider("katexConfig",n).directive("katex",t).directive("katexBind",r),n.$inject=["katex","renderMathInElement"],t.$inject=["katexConfig","$rootScope"],r.$inject=["katexConfig"]}();<|endoftext|>