<commit_before>// 13 colors
export const COLORS = [
  "red",
  "orange",
  "yellow",
  "olive",
  "green",
  "teal",
  "blue",
  "violet",
  "purple",
  "pink",
  "brown",
  "grey",
  "black"
];

export const SECTIONS = [
  "Top",
  "About",
  //'Portfolio',
  "Resume"
  // 'Work', 'Education', 'Skills',
];

export const BASIC = {
  name: "louis",
  tagline: "❤愛 ☮life ✋敬重",
  taglineUrl: "https://en.wikipedia.org/wiki/Hacker_culture",
  about: "I teach bots to steal jobs and make games for the retired.",
  email: "lgvichy@gmail.com",
  logo: "id/icon-white.png",
  url: "https://louisgv.github.io/"
};

export const PHOTO = {
  normal: "id/selfid.jpg",
  normalInverted: "id/selfid-inverted.jpg",
  small: "id/selfid-small.jpg",
  smallInverted: "id/selfid-small-inverted.jpg"
};

export const CONTACT = {
  email: {
    icon: "envelope",
    color: COLORS[6],
    value: "lgvichy@gmail.com"
  },
  location: {
    icon: "globe",
    color: COLORS[5],
    name: "Seattle, Washington",
    url: "https://en.wikipedia.org/wiki/Seattle"
  }
};

export const HOBBIES = [
  {
    name: "Hacking on cutting edge technology",
    color: "orange",
    icon: "terminal",
    url: "https://louisgv.github.io/dev/www/index.html#/"
  },
  {
    name: "Reading research paper",
    color: "yellow",
    icon: "sticky note",
    url: "https://arxiv.org/"
  },
  {
    name: "Listening to scientific podcast",
    color: "olive",
    icon: "podcast",
    url: "https://twit.tv/shows/floss-weekly"
  },
  {
    name: "Kick-boxing",
    color: "green",
    icon: "grab",
    url: "https://en.wikipedia.org/wiki/Kickboxing"
  }
];

export const INTERESTS = [
  {
    name: "Robotic Automation",
    color: COLORS[11],
    icon: "radio",
    url: "https://en.wikipedia.org/wiki/Robotic_automation_software"
  },
  {
    name: "Life Extension",
    color: COLORS[10],
    icon: "power",
    url: "https://en.wikipedia.org/wiki/Life_extension"
  },
  {
    name: "Machine Learning",
    color: COLORS[9],
    icon: "linkify",
    url: "https://lmgtfy.com/?s=d&q=Machine+learning"
  },
  {
    name: "Decentralization",
    color: COLORS[8],
    icon: "unlinkify",
    url: "https://lmgtfy.com/?s=d&q=Decentralization"
  },
  {
    name: "Entertainment",
    color: COLORS[7],
    icon: "game",
    url: "https://lmgtfy.com/?s=d&q=Entertainment"
  }
];

export const SOCIALS = [
  {
    name: "tweet",
    color: COLORS[5],
    icon: "twitter",
    url: "https://twitter.com/litbid",
    uid: "lidbid"
  },
  {
    name: "biz",
    color: COLORS[6],
    icon: "linkedin",
    url: "https://www.linkedin.com/in/louisgv/",
    uid: "louisgv"
  },
  {
    name: "art",
    color: COLORS[7],
    icon: "instagram",
    url: "https://www.instagram.com/lgvichy/",
    uid: "lgvichy"
  },
  {
    name: "code",
    color: COLORS[8],
    icon: "github",
    url: "https://github.com/louisgv/",
    uid: "louisgv"
  }
];

export const WORK_SAMPLES = [
  {
    label: "networking",
    name: "HyperProxy",
    color: COLORS[0],
    url: "https://goonism.github.io/hyperproxy/"
  },
  {
    label: "production",
    name: "Janus",
    color: COLORS[1],
    url: "https://louisgv.itch.io/jhc"
  },
  {
    label: "visualization",
    name: "Pattar",
    color: COLORS[2],
    url: "https://louisgv.github.io/pattar/"
  }
];

export const PORTFOLIOS = [
  {
    name: "SmartLook Web",
    type: "Web Application",
    color: COLORS[0],
    description: "TurboTax's real-time customer support feature",
    technology: "ES6, React.js, CSS, Glance",
    image: "project/smartlook_mobile.gif",
    role: "Lead Front-end Engineer",
    license: "PROPRIETARY",
    status: "In production, TurboTax 2016",
    url: "https://www.youtube.com/watch?v=E19Znq9EDZ0"
  },
  {
    name: "Cryptoville",
    type: "Web Application",
    color: COLORS[1],
    description: "Decentralized market making platform for agriculture",
    license: "MIT",
    role: "Core Contributor",
    technology: "React.js, Lisk",
    image: "project/cryptoville.gif",
    status: "Opensource Project",
    url: "https://www.crypto-ville.herokuapp.com"
  },
  {
    name: "JanusLauncher",
    type: "Mobile Application",
    color: COLORS[2],
    description:
      "An Android launcher with hand written letter recognition capability for quick app browsing",
    role: "Author",
    license: "MIT",
    technology:
      "Kotlin, Android Studio Canary, TensorFlow, Jupyter Notebook, EMNIST database",
    image: "project/janusLauncher.gif",
    status: "Opensource Project",
    url: "https://github.com/louisgv/janusLauncher"
  },
  {
    name: "VegaHub",
    type: "Hybrid Application",
    color: COLORS[3],
    description:
      "A hybrid mobile application used to control any robot implementing Cumulonimbus's ROS bridge",
    role: "Lead Front-end Engineer",
    license: "PROPRIETARY",
    status: "N/A",
    technology:
      "Google Mobile Kit (Bluetooth module), Firebase, Ionic, Cordova, CrossWalk, ES5, SASS",
    image: "project/vegahub.gif",
    url: "https://clnb.io/vega/"
  }
];

export const RESUME = {
  // "embedded": "https://docs.google.com/document/d/e/2PACX-1vT9bDNvMitcORMx7nmL0-zOwDkTPMRZXuwR8OwN0j_1A1IMqm9hX4X5zY7_a27Os_CSGGnCJPkHwVYp/pub?embedded=true",
  embedded:
    "https://docs.google.com/document/d/1_UE4yS3lA81l3HdBwhKABcKXAJIO0HyDkcaOxNAjJPs/preview",
  external:
    "https://docs.google.com/document/d/1_UE4yS3lA81l3HdBwhKABcKXAJIO0HyDkcaOxNAjJPs/edit?usp=sharing"
};

export const REFERENCES = [
  {
    url: "https://reactjs.org/",
    name: "React.js"
  },
  {
    url: "https://react.semantic-ui.com/",
    name: "Semantic-ui"
  },
  {
    url: "https://github.com/negomi/react-burger-menu/",
    name: "react-burger-menu"
  },
  {
    url: "https://github.com/oliviertassinari/react-swipeable-views",
    name: "react-swipeable-views"
  }
];

export const LICENSE = {
  name: "MIT License",
  url: "https://en.wikipedia.org/wiki/MIT_License"
};
<commit_msg>fix up insta link<commit_after>// 13 colors
export const COLORS = [
  "red",
  "orange",
  "yellow",
  "olive",
  "green",
  "teal",
  "blue",
  "violet",
  "purple",
  "pink",
  "brown",
  "grey",
  "black",
];

export const SECTIONS = [
  "Top",
  "About",
  //'Portfolio',
  "Resume",
  // 'Work', 'Education', 'Skills',
];

export const BASIC = {
  name: "louis",
  tagline: "❤愛 ☮life ✋敬重",
  taglineUrl: "https://en.wikipedia.org/wiki/Hacker_culture",
  about: "I teach bots to steal jobs and make games for the retired.",
  email: "lgvichy@gmail.com",
  logo: "id/icon-white.png",
  url: "https://louisgv.github.io/",
};

export const PHOTO = {
  normal: "id/selfid.jpg",
  normalInverted: "id/selfid-inverted.jpg",
  small: "id/selfid-small.jpg",
  smallInverted: "id/selfid-small-inverted.jpg",
};

export const CONTACT = {
  email: {
    icon: "envelope",
    color: COLORS[6],
    value: "louis@plasmo.com",
  },
  location: {
    icon: "globe",
    color: COLORS[5],
    name: "Seattle, Washington",
    url: "https://en.wikipedia.org/wiki/Seattle",
  },
};

export const HOBBIES = [
  {
    name: "Hacking on cutting edge technology",
    color: "orange",
    icon: "terminal",
    url: "https://louisgv.github.io/dev/www/index.html#/",
  },
  {
    name: "Reading research paper",
    color: "yellow",
    icon: "sticky note",
    url: "https://arxiv.org/",
  },
  {
    name: "Listening to scientific podcast",
    color: "olive",
    icon: "podcast",
    url: "https://twit.tv/shows/floss-weekly",
  },
  {
    name: "Kick-boxing",
    color: "green",
    icon: "grab",
    url: "https://en.wikipedia.org/wiki/Kickboxing",
  },
];

export const INTERESTS = [
  {
    name: "Robotic Automation",
    color: COLORS[11],
    icon: "radio",
    url: "https://en.wikipedia.org/wiki/Robotic_automation_software",
  },
  {
    name: "Life Extension",
    color: COLORS[10],
    icon: "power",
    url: "https://en.wikipedia.org/wiki/Life_extension",
  },
  {
    name: "Machine Learning",
    color: COLORS[9],
    icon: "linkify",
    url: "https://lmgtfy.com/?s=d&q=Machine+learning",
  },
  {
    name: "Decentralization",
    color: COLORS[8],
    icon: "unlinkify",
    url: "https://lmgtfy.com/?s=d&q=Decentralization",
  },
  {
    name: "Entertainment",
    color: COLORS[7],
    icon: "game",
    url: "https://lmgtfy.com/?s=d&q=Entertainment",
  },
];

export const SOCIALS = [
  {
    name: "tweet",
    color: COLORS[5],
    icon: "twitter",
    url: "https://twitter.com/litbid",
    uid: "lidbid",
  },
  {
    name: "biz",
    color: COLORS[6],
    icon: "linkedin",
    url: "https://www.linkedin.com/in/louisgv/",
    uid: "louisgv",
  },
  {
    name: "art",
    color: COLORS[7],
    icon: "instagram",
    url: "https://www.instagram.com/louis.g.v/",
    uid: "lgvichy",
  },
  {
    name: "code",
    color: COLORS[8],
    icon: "github",
    url: "https://github.com/louisgv/",
    uid: "louisgv",
  },
];

export const WORK_SAMPLES = [
  {
    label: "networking",
    name: "HyperProxy",
    color: COLORS[0],
    url: "https://goonism.github.io/hyperproxy/",
  },
  {
    label: "production",
    name: "Janus",
    color: COLORS[1],
    url: "https://louisgv.itch.io/jhc",
  },
  {
    label: "visualization",
    name: "Pattar",
    color: COLORS[2],
    url: "https://louisgv.github.io/pattar/",
  },
];

export const PORTFOLIOS = [
  {
    name: "SmartLook Web",
    type: "Web Application",
    color: COLORS[0],
    description: "TurboTax's real-time customer support feature",
    technology: "ES6, React.js, CSS, Glance",
    image: "project/smartlook_mobile.gif",
    role: "Lead Front-end Engineer",
    license: "PROPRIETARY",
    status: "In production, TurboTax 2016",
    url: "https://www.youtube.com/watch?v=E19Znq9EDZ0",
  },
  {
    name: "Cryptoville",
    type: "Web Application",
    color: COLORS[1],
    description: "Decentralized market making platform for agriculture",
    license: "MIT",
    role: "Core Contributor",
    technology: "React.js, Lisk",
    image: "project/cryptoville.gif",
    status: "Opensource Project",
    url: "https://www.crypto-ville.herokuapp.com",
  },
  {
    name: "JanusLauncher",
    type: "Mobile Application",
    color: COLORS[2],
    description:
      "An Android launcher with hand written letter recognition capability for quick app browsing",
    role: "Author",
    license: "MIT",
    technology:
      "Kotlin, Android Studio Canary, TensorFlow, Jupyter Notebook, EMNIST database",
    image: "project/janusLauncher.gif",
    status: "Opensource Project",
    url: "https://github.com/louisgv/janusLauncher",
  },
  {
    name: "VegaHub",
    type: "Hybrid Application",
    color: COLORS[3],
    description:
      "A hybrid mobile application used to control any robot implementing Cumulonimbus's ROS bridge",
    role: "Lead Front-end Engineer",
    license: "PROPRIETARY",
    status: "N/A",
    technology:
      "Google Mobile Kit (Bluetooth module), Firebase, Ionic, Cordova, CrossWalk, ES5, SASS",
    image: "project/vegahub.gif",
    url: "https://clnb.io/vega/",
  },
];

export const RESUME = {
  // "embedded": "https://docs.google.com/document/d/e/2PACX-1vT9bDNvMitcORMx7nmL0-zOwDkTPMRZXuwR8OwN0j_1A1IMqm9hX4X5zY7_a27Os_CSGGnCJPkHwVYp/pub?embedded=true",
  embedded:
    "https://docs.google.com/document/d/1_UE4yS3lA81l3HdBwhKABcKXAJIO0HyDkcaOxNAjJPs/preview",
  external:
    "https://docs.google.com/document/d/1_UE4yS3lA81l3HdBwhKABcKXAJIO0HyDkcaOxNAjJPs/edit?usp=sharing",
};

export const REFERENCES = [
  {
    url: "https://reactjs.org/",
    name: "React.js",
  },
  {
    url: "https://react.semantic-ui.com/",
    name: "Semantic-ui",
  },
  {
    url: "https://github.com/negomi/react-burger-menu/",
    name: "react-burger-menu",
  },
  {
    url: "https://github.com/oliviertassinari/react-swipeable-views",
    name: "react-swipeable-views",
  },
];

export const LICENSE = {
  name: "MIT License",
  url: "https://en.wikipedia.org/wiki/MIT_License",
};
<|endoftext|>


<commit_before>alert.volume(input.volume);
alert(input.sound);
output.volume = input.volume;
<commit_msg>rename input. to $.<commit_after>alert.volume($.volume);
alert($.sound);
output.volume = $.volume;
<|endoftext|>


<commit_before>const get = require('./get.js');
const parser = require('./parser.js');
const util = require('./util/util.js');

const DFLT_OPTS = {
  userAgent: '*',
  allowOnNeutral: true,
};

function Robots(opts) {
  this.robotsCache = {};
  this.opts = Object.assign(DFLT_OPTS, {
    userAgent: opts.userAgent.toLowerCase(),
    allowOnNeutral: opts.allowOnNeutral,
  });

  this.getRecordsForAgent = () => {
    const key = this.active;
    const domainBots = this.robotsCache[key] || {};
    const ourBotInBots = this.opts.userAgent in domainBots;
    const otherBots = '*' in domainBots;
    if (ourBotInBots) {
      return domainBots[this.opts.userAgent];
    } else if (otherBots) {
      return domainBots['*'];
    }
    return false;
  };

  this.canVisit = (url, botGroup) => {
    const allow = util.applyRecords(url, botGroup.allow);
    const disallow = util.applyRecords(url, botGroup.disallow);
    const maxSpecificityAllow = util.maxSpecificity(allow);
    const maxSpecificityDisallow = util.maxSpecificity(disallow);
    const noAllows = allow.length === 0 && disallow.length > 0;
    const noDisallows = allow.length > 0 && disallow.length === 0;
    if (noDisallows || (maxSpecificityAllow > maxSpecificityDisallow)) {
      return true;
    } else if (noAllows || (maxSpecificityAllow < maxSpecificityDisallow)) {
      return false;
    }
    return this.opts.allowOnNeutral;
  };
}

Robots.prototype.parseRobots = function parseRobots(url, string) {
  const formattedLink = util.formatLink(url);
  this.robotsCache[formattedLink] = parser(string);
  this.active = formattedLink;
};

Robots.prototype.isCached = function robotsExist(domain) {
  return util.formatLink(domain) in this.robotsCache;
};

Robots.prototype.fetch = function addRobots(link) {
  const formattedLink = util.formatLink(link);
  const robotsLink = `${formattedLink}/robots.txt`;
  return get(robotsLink)
    .then((data) => {
      this.robotsCache[formattedLink] = parser(data);
      this.active = link;
    });
};

// @TODO rework to be cleaner
Robots.prototype.canCrawl = function allowed(url) {
  if (!this.isCached(url)) {
    return this.fetch(url)
      .then(() => this.canCrawlSync(url));
  }
  return Promise.resolve(this.canCrawlSync(url));
};

Robots.prototype.useRobotsFor = function useRobots(url) {
  const link = util.formatLink(url);
  if (link in this.robotsCache) {
    this.active = link;
    return Promise.resolve();
  }
  return this.fetch(url);
};

Robots.prototype.getSitemaps = function getSitemaps() {
  return Promise.resolve(this.getSitemapsSync());
};

Robots.prototype.getCrawlDelay = function getCrawlDelay() {
  return Promise.resolve(this.getCrawlDelaySync());
};

Robots.prototype.canCrawlSync = function canFetch(url) {
  // Get the parsed robotsCache.txt for this domain.
  const botGroup = this.getRecordsForAgent();
  // Conditional allow, our bot or the * user agent is in the robotsCache.txt
  if (botGroup) {
    return this.canVisit(url, botGroup);
  }
  // Robots txt exists doesn't have any rules for our bot or *, therefore full allow.
  return true;
};

Robots.prototype.getSitemapsSync = function getSitemaps() {
  const botRecords = this.robotsCache[this.active];
  return botRecords ? botRecords.sitemaps : [];
};

Robots.prototype.getCrawlDelaySync = function getCrawlDelay() {
  const botRecords = this.getRecordsForAgent();
  return botRecords ? botRecords.crawlDelay : 0;
};

Robots.prototype.setUserAgent = function setUserAgent(agent) {
  this.opts.userAgent = agent.toLowerCase();
};

Robots.prototype.setAllowOnNeutral = function setAllowOnNeutral(allow) {
  this.opts.allowOnNeutral = allow;
};

module.exports = Robots;
<commit_msg>Fixed bug where link wasn't allowed if no rules applied.<commit_after>const get = require('./get.js');
const parser = require('./parser.js');
const util = require('./util/util.js');

const DFLT_OPTS = {
  userAgent: '*',
  allowOnNeutral: true,
};

function Robots(opts = {}) {
  this.robotsCache = {};
  this.opts = {
    userAgent: opts.userAgent ? opts.userAgent.toLowerCase() : DFLT_OPTS.userAgent,
    allowOnNeutral: opts.allowOnNeutral ? opts.allowOnNeutral : DFLT_OPTS.allowOnNeutral,
  };

  this.getRecordsForAgent = () => {
    const key = this.active;
    const domainBots = this.robotsCache[key] || {};
    const ourBotInBots = this.opts.userAgent in domainBots;
    const otherBots = '*' in domainBots;
    if (ourBotInBots) {
      return domainBots[this.opts.userAgent];
    } else if (otherBots) {
      return domainBots['*'];
    }
    return false;
  };

  this.canVisit = (url, botGroup) => {
    const allow = util.applyRecords(url, botGroup.allow);
    const disallow = util.applyRecords(url, botGroup.disallow);
    const maxSpecificityAllow = util.maxSpecificity(allow);
    const maxSpecificityDisallow = util.maxSpecificity(disallow);
    const noAllows = allow.length === 0 && disallow.length > 0;
    const noDisallows = allow.length > 0 && disallow.length === 0;

    // No rules for allow or disallow apply, therefore full allow.
    if (noAllows && noDisallows) {
      return true;
    }

    if (noDisallows || (maxSpecificityAllow > maxSpecificityDisallow)) {
      return true;
    } else if (noAllows || (maxSpecificityAllow < maxSpecificityDisallow)) {
      return false;
    }
    return this.opts.allowOnNeutral;
  };
}

Robots.prototype.parseRobots = function parseRobots(url, string) {
  const formattedLink = util.formatLink(url);
  this.robotsCache[formattedLink] = parser(string);
  this.active = formattedLink;
};

Robots.prototype.isCached = function robotsExist(domain) {
  return util.formatLink(domain) in this.robotsCache;
};

Robots.prototype.fetch = function addRobots(link) {
  const formattedLink = util.formatLink(link);
  const robotsLink = `${formattedLink}/robots.txt`;
  return get(robotsLink)
    .then((data) => {
      this.robotsCache[formattedLink] = parser(data);
      this.active = link;
    });
};

// @TODO rework to be cleaner
Robots.prototype.canCrawl = function allowed(url) {
  if (!this.isCached(url)) {
    return this.fetch(url)
      .then(() => this.canCrawlSync(url));
  }
  return Promise.resolve(this.canCrawlSync(url));
};

Robots.prototype.useRobotsFor = function useRobots(url) {
  const link = util.formatLink(url);
  if (link in this.robotsCache) {
    this.active = link;
    return Promise.resolve();
  }
  return this.fetch(url);
};

Robots.prototype.getSitemaps = function getSitemaps() {
  return Promise.resolve(this.getSitemapsSync());
};

Robots.prototype.getCrawlDelay = function getCrawlDelay() {
  return Promise.resolve(this.getCrawlDelaySync());
};

Robots.prototype.canCrawlSync = function canFetch(url) {
  // Get the parsed robotsCache.txt for this domain.
  const botGroup = this.getRecordsForAgent();
  // Conditional allow, our bot or the * user agent is in the robotsCache.txt
  if (botGroup) {
    return this.canVisit(url, botGroup);
  }
  // Robots txt exists doesn't have any rules for our bot or *, therefore full allow.
  return true;
};

Robots.prototype.getSitemapsSync = function getSitemaps() {
  const botRecords = this.robotsCache[this.active];
  return botRecords ? botRecords.sitemaps : [];
};

Robots.prototype.getCrawlDelaySync = function getCrawlDelay() {
  const botRecords = this.getRecordsForAgent();
  return botRecords ? botRecords.crawlDelay : 0;
};

Robots.prototype.setUserAgent = function setUserAgent(agent) {
  this.opts.userAgent = agent.toLowerCase();
};

Robots.prototype.setAllowOnNeutral = function setAllowOnNeutral(allow) {
  this.opts.allowOnNeutral = allow;
};

module.exports = Robots;
<|endoftext|>


<commit_before>Rickshaw.namespace('Rickshaw.Graph.RangeSlider');

Rickshaw.Graph.RangeSlider = Rickshaw.Class.create({

	initialize: function(args) {

		var element = this.element = args.element;
		var graph = this.graph = args.graph;

		this.slideCallbacks = [];

		this.build();

		graph.onUpdate( function() { this.update() }.bind(this) );
	},

	build: function() {

		var element = this.element;
		var graph = this.graph;
		var $ = jQuery;

		var domain = graph.dataDomain();
		var self = this;

		$( function() {
			$(element).slider( {
				range: true,
				min: domain[0],
				max: domain[1],
				values: [
					domain[0],
					domain[1]
				],
				slide: function( event, ui ) {

					if (ui.values[1] <= ui.values[0]) return;

					graph.window.xMin = ui.values[0];
					graph.window.xMax = ui.values[1];
					graph.update();

					var domain = graph.dataDomain();

					// if we're at an extreme, stick there
					if (domain[0] == ui.values[0]) {
						graph.window.xMin = undefined;
					}

					if (domain[1] == ui.values[1]) {
						graph.window.xMax = undefined;
					}

					self.slideCallbacks.forEach(function(callback) {
						callback(graph, graph.window.xMin, graph.window.xMax);
					});
				}
			} );
		} );

		$(element)[0].style.width = graph.width + 'px';

	},

	update: function() {

		var element = this.element;
		var graph = this.graph;
		var $ = jQuery;

		var values = $(element).slider('option', 'values');

		var domain = graph.dataDomain();

		$(element).slider('option', 'min', domain[0]);
		$(element).slider('option', 'max', domain[1]);

		if (graph.window.xMin == null) {
			values[0] = domain[0];
		}
		if (graph.window.xMax == null) {
			values[1] = domain[1];
		}

		$(element).slider('option', 'values', values);
	},

	onSlide: function(callback) {
		this.slideCallbacks.push(callback);
	}
});

<commit_msg>RangeSlider: Resize when original graph changes width<commit_after>Rickshaw.namespace('Rickshaw.Graph.RangeSlider');

Rickshaw.Graph.RangeSlider = Rickshaw.Class.create({

	initialize: function(args) {

		var element = this.element = args.element;
		var graph = this.graph = args.graph;

		this.slideCallbacks = [];

		this.build();

		graph.onUpdate( function() { this.update() }.bind(this) );
	},

	build: function() {

		var element = this.element;
		var graph = this.graph;
		var $ = jQuery;

		var domain = graph.dataDomain();
		var self = this;

		$( function() {
			$(element).slider( {
				range: true,
				min: domain[0],
				max: domain[1],
				values: [
					domain[0],
					domain[1]
				],
				slide: function( event, ui ) {

					if (ui.values[1] <= ui.values[0]) return;

					graph.window.xMin = ui.values[0];
					graph.window.xMax = ui.values[1];
					graph.update();

					var domain = graph.dataDomain();

					// if we're at an extreme, stick there
					if (domain[0] == ui.values[0]) {
						graph.window.xMin = undefined;
					}

					if (domain[1] == ui.values[1]) {
						graph.window.xMax = undefined;
					}

					self.slideCallbacks.forEach(function(callback) {
						callback(graph, graph.window.xMin, graph.window.xMax);
					});
				}
			} );
		} );

		graph.onConfigure(this.configure.bind(this));
		this.configure();

	},

	configure: function() {
		this.element.style.width = this.graph.width + 'px';
	},

	update: function() {

		var element = this.element;
		var graph = this.graph;
		var $ = jQuery;

		var values = $(element).slider('option', 'values');

		var domain = graph.dataDomain();

		$(element).slider('option', 'min', domain[0]);
		$(element).slider('option', 'max', domain[1]);

		if (graph.window.xMin == null) {
			values[0] = domain[0];
		}
		if (graph.window.xMax == null) {
			values[1] = domain[1];
		}

		$(element).slider('option', 'values', values);
	},

	onSlide: function(callback) {
		this.slideCallbacks.push(callback);
	}
});

<|endoftext|>


<commit_before>// TODO refactor this code into a UI and non-UI part.

var CHANNEL = "#orbited"
var IRC_SERVER = 'irc.freenode.net'
var IRC_PORT = 6667

var nickname = null;
var users = {};

var irc = new IRCClient();
var log = getIrcLogger("Chat");

var connect = function () {
  $('#signin_popup, #absorb_clicks').hide();
  $('#chatbox_input').focus();
  $('#chatbox_input').val('')

  nickname = $("#nickname").val();

  function parseName(identity) {
    // TODO remove privileges from name head.
    return identity.split("!", 1)[0];
  }
  irc.onACTION = function(command) {
      var messagediv = $('

');
      var sender = parseName(command.prefix);
      messagediv.addClass("action");
      var target = command.args[0];
      var message = command.args.slice(1).join(" ")

      if (sender == nickname)
        messagediv.addClass("self");

      if (isSubstring(nickname, message))
        messagediv.addClass("mentioned");

      messagediv.html('' + sender + ' ' +
                      sanitize(message))
                .appendTo("#chathistory");
    scrollDown();
  }
  irc.onCTCP = function(command) {
    var messagediv = $('

');
    messagediv.addClass("ctcp");
    message = command.args.slice(1).join(" ")
    var sender = parseName(command.prefix);
    messagediv.
       html('' + sender + '(CTCP): ' + sanitize(message)).
       appendTo("#chathistory");
    scrollDown();
  }
  irc.onPRIVMSG = function(command) {
    var sender = parseName(command.prefix);
    var target = command.args[0];
    var message = command.args[1];

    var messagediv = $('

');

    if (message.charCodeAt(0) == 1) {
      // This is an CTCP request.

      // NB: the embedded CTCP requests is:
      //        \x01<request>[ <arg>]+\x01
      //     eg:
      //      when we type "/me waves", we receive the following message:
      //        \x01ACTION waves\x01
      //     eg:
      //      after we connect, the freenode networks sends:
      //        \x01VERSION\x01
      // See http://www.invlogic.com/irc/ctcp.html
      // NB: CTCP draft talks about quoting but it does not actually
      //      define it.
      var args = message.slice(1, message.length - 1).split(' ');
      var request = args.shift();
      if (request == "ACTION") {
        message = args.join(" ");
        messagediv.addClass("action");
      } else {
        message = request + " " + args.join(" ");
        messagediv.addClass("ctcp");
      }
    }

    if (sender == nickname)
      messagediv.addClass("self");

    if (target == nickname)
      messagediv.addClass("private");

    if (isSubstring(nickname, message))
      messagediv.addClass("mentioned");

    messagediv.html('' + sender + ': ' +
                    sanitize(message))
      .appendTo("#chathistory");
    scrollDown();
  };
  irc.onTOPIC = function(command) {
    // See http://tools.ietf.org/html/rfc2812#section-3.2.4
    // Args: <channel> [ <topic> ]

    var channel = command.args[0];
    if (channel != CHANNEL)
      return;

    var topic = command.args[1];

    var user = parseName(command.prefix);
    $("

").
        html('' + user + ' changed the topic to: ' + sanitize(topic)).
        appendTo("#chathistory");
  };
  irc.onresponse = function(command) {
    var responseCode = parseInt(command.type);

    if (responseCode == 332) {
      // """
      // 331 RPL_NOTOPIC
      //     <target> <channel> :No topic is set
      // 332 RPL_TOPIC
      //     <target> <channel> :<topic>
      //
      // When sending a TOPIC message to determine the
      // channel topic, one of two replies is sent.  If
      // the topic is set, RPL_TOPIC is sent back else
      // RPL_NOTOPIC.
      // """ -- rfc2812

      var channel = command.args[1];
      if (channel != CHANNEL)
        return;

      var topic = command.args[2];

      $("

").
        html("Channel topic is: " + sanitize(topic)).
        appendTo("#chathistory");
    } else if (responseCode == 353) {
      // 353 is the code for RPL_NAMEREPLY.

      // The args are:
      //
      // """
      //   <target> ( "=" / "*" / "@" ) <channel>
      //    :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )
      //
      //   - "@" is used for secret channels, "*" for private
      //     channels, and "=" for others (public channels).
      // """ -- rfc2812

      var channel = command.args[2];
      if (channel != CHANNEL)
        return;

      var partialUserList = command.args[3].split(' ');
      for (var i = 0, l = partialUserList.length; i < l; ++i) {
        var name = $.trim(partialUserList[i]);
        if (name == "" || users[name])
          continue;
        addName(name);
      }
    } else if (responseCode == 366) {
      // 366 is the code for RPL_ENDOFNAMES.

      fillUserList();

      $("

").
        html("Joined " + CHANNEL + " channel.").
        appendTo("#chathistory");
      scrollDown();
    }
  };
  irc.onopen = function() {
    irc.nick(nickname);
    irc.ident(nickname, '8 *', nickname);
    irc.join(CHANNEL);

    // Once we have joined, don't leave without warning the user
    window.onbeforeunload = function() {
      return 'Are you sure you want to quit and lose the chat connection?';
    };
    $(window).unload(function() {
        hardquit();
//      quit();
    })
  }
  irc.onclose = function() {
    log.debug("closed...");
  };
  irc.onNICK = function(command) {
    // See http://tools.ietf.org/html/rfc2812#section-3.1.2
    var previousNick = parseName(command.prefix);
    var newNick = command.args[0];
    userRenamed(previousNick, newNick);
  };
  // TODO implement onNOTICE...
  irc.onJOIN = function(command) {
    var joiner = parseName(command.prefix);

    addName(joiner);
    fillUserList();

    $("

")
      .html("" + joiner + ' has joined ' + CHANNEL)
      .appendTo("#chathistory");
    scrollDown();
  }
  irc.onPART = function(command) {
    var leaver = parseName(command.prefix);
    var message = command.args.join(" ");

    $("

")
      .html("" + leaver + ' left ' + CHANNEL +
            (message ? ' (“' + sanitize(message) + '”)' : ''))
      .appendTo("#chathistory");
    scrollDown();

    removeName(leaver);
  }
  irc.onQUIT = function(command) {
    var quitter = parseName(command.prefix);
    var message = command.args.join(" ");

    $("

")
      .html("" + quitter + ' quit' +
            (message ? ' (“' + sanitize(message) + '”)' : ''))
      .appendTo("#chathistory");
    scrollDown();

    removeName(quitter);
  }

  irc.connect(IRC_SERVER, IRC_PORT);
};

var chat = function () {
  msg = $('#chatbox_input').val();
  irc.privmsg(CHANNEL, msg);
  $('#chatbox_input').val('');
  // the IRC server will not echo our message back, so simulate a send.
  irc.onPRIVMSG({prefix:nickname,type:'PRIVMSG',args:[CHANNEL, msg]});
}
var hardquit = function() {
    irc.reset();
}
var quit = function () {
  // XXX sometimes the quit reason is not seen when we quit...
  //     probably because the browser is immediately closed
  //     without waiting for socket flush?
  irc.quit();
}

// TODO enable the nick change code.
// function nickChanged(newnick) {
//     userRenamed(nickname, newnick);
//     nickname = newnick;
// }

function userRenamed(oldname, newname) {
  $("

")
    .html("" + oldname + " is now known as " +
          "" + newname + "")
    .appendTo("#chathistory");
  scrollDown();

  $(".user_list .user#user_" + oldname)
    .attr("id", "user_" + newname)
    .html(newname);
}

var user_priviledges = function (name) {
  var privs_symbols = {"@":"admin", "%":"subadmin", "+":"voice"};
  if (name[0] in privs_symbols) {
    return privs_symbols[name[0]];
  } else {
    return "";
  };
};

var addName = function (name) {
  // XXX this MUST remove the nick privileges from name (eg: because
  //     these prefixes are not sent when the user changed his nick,
  //     etc).
  var priviledges = user_priviledges(name);
  users[name] = {"privs":priviledges};
  $('
' + name + '
')
    .addClass(priviledges)
    .appendTo("#user_list");
};

var removeName = function (name) {
  delete users[name];
  $(".user_list #user_" + name).remove()
};

var fillUserList = function () {
  $('.user_list').empty();
  //alert("test");
  var list = [];
  for (var user in users) {
    list.push(user);
  };
  list.sort()
  for (var i=0; i < list.length; i++) {
    var user = list[i];
    privs = users[user]['privs'];
    $('
' + user + '
')
      .addClass(privs)
      .appendTo("#user_list");
  };
};

var scrollDown = function () {
  var box = document.getElementById('chathistory');
  box.scrollTop = box.scrollHeight;
}

var isSubstring = function (sub, str) {
  // case insensitive substring test
  return str.toLowerCase().indexOf(sub.toLowerCase()) >= 0;
};

var sanitize = (function(str) {
  // See http://bigdingus.com/2007/12/29/html-escaping-in-javascript/
  var MAP = {
    '&': '&',
    '<': '<',
    '>': '>',
    '"': '"',
    "'": '''
  };
  var repl = function(c) { return MAP[c]; };
  return function(s) {
    return s.replace(/[&<>'"]/g, repl);
  };
})();

// function infoMessage(message) {
//   $("

")
//     .html(message)
//     .appendTo("#chathistory");
//   scrollDown();
// };
<commit_msg>Auto rename with _ when nickname is taken<commit_after>// TODO refactor this code into a UI and non-UI part.

var CHANNEL = "#orbited"
var IRC_SERVER = 'irc.freenode.net'
var IRC_PORT = 6667

var nickname = null;
var users = {};

var irc = new IRCClient();
var log = getIrcLogger("Chat");

var connect = function () {
  $('#signin_popup, #absorb_clicks').hide();
  $('#chatbox_input').focus();
  $('#chatbox_input').val('')

  nickname = $("#nickname").val();

  function parseName(identity) {
    // TODO remove privileges from name head.
    return identity.split("!", 1)[0];
  }
  irc.onACTION = function(command) {
      var messagediv = $('

');
      var sender = parseName(command.prefix);
      messagediv.addClass("action");
      var target = command.args[0];
      var message = command.args.slice(1).join(" ")

      if (sender == nickname)
        messagediv.addClass("self");

      if (isSubstring(nickname, message))
        messagediv.addClass("mentioned");

      messagediv.html('' + sender + ' ' +
                      sanitize(message))
                .appendTo("#chathistory");
    scrollDown();
  }
  irc.onCTCP = function(command) {
    var messagediv = $('

');
    messagediv.addClass("ctcp");
    message = command.args.slice(1).join(" ")
    var sender = parseName(command.prefix);
    messagediv.
       html('' + sender + '(CTCP): ' + sanitize(message)).
       appendTo("#chathistory");
    scrollDown();
  }
  irc.onPRIVMSG = function(command) {
    var sender = parseName(command.prefix);
    var target = command.args[0];
    var message = command.args[1];

    var messagediv = $('

');

    if (message.charCodeAt(0) == 1) {
      // This is an CTCP request.

      // NB: the embedded CTCP requests is:
      //        \x01<request>[ <arg>]+\x01
      //     eg:
      //      when we type "/me waves", we receive the following message:
      //        \x01ACTION waves\x01
      //     eg:
      //      after we connect, the freenode networks sends:
      //        \x01VERSION\x01
      // See http://www.invlogic.com/irc/ctcp.html
      // NB: CTCP draft talks about quoting but it does not actually
      //      define it.
      var args = message.slice(1, message.length - 1).split(' ');
      var request = args.shift();
      if (request == "ACTION") {
        message = args.join(" ");
        messagediv.addClass("action");
      } else {
        message = request + " " + args.join(" ");
        messagediv.addClass("ctcp");
      }
    }

    if (sender == nickname)
      messagediv.addClass("self");

    if (target == nickname)
      messagediv.addClass("private");

    if (isSubstring(nickname, message))
      messagediv.addClass("mentioned");

    messagediv.html('' + sender + ': ' +
                    sanitize(message))
      .appendTo("#chathistory");
    scrollDown();
  };
  irc.onTOPIC = function(command) {
    // See http://tools.ietf.org/html/rfc2812#section-3.2.4
    // Args: <channel> [ <topic> ]

    var channel = command.args[0];
    if (channel != CHANNEL)
      return;

    var topic = command.args[1];

    var user = parseName(command.prefix);
    $("

").
        html('' + user + ' changed the topic to: ' + sanitize(topic)).
        appendTo("#chathistory");
  };
irc.onerror = function(command) {
    self.logger.debug('onerror', command)
    var responseCode = parseInt(command.type);
    if (responseCode == 431 || responseCode == 432 || responseCode == 433) {
    // 431     ERR_NONICKNAMEGIVEN
    // 432     ERR_ERRONEUSNICKNAME
    // 433     ERR_NICKNAMEINUSE
        nickname += '_'
        irc.nick(nickname)
        self.onUsernameTaken();
    }

  irc.onresponse = function(command) {
    var responseCode = parseInt(command.type);

    if (responseCode == 332) {
      // """
      // 331 RPL_NOTOPIC
      //     <target> <channel> :No topic is set
      // 332 RPL_TOPIC
      //     <target> <channel> :<topic>
      //
      // When sending a TOPIC message to determine the
      // channel topic, one of two replies is sent.  If
      // the topic is set, RPL_TOPIC is sent back else
      // RPL_NOTOPIC.
      // """ -- rfc2812

      var channel = command.args[1];
      if (channel != CHANNEL)
        return;

      var topic = command.args[2];

      $("

").
        html("Channel topic is: " + sanitize(topic)).
        appendTo("#chathistory");
    } else if (responseCode == 353) {
      // 353 is the code for RPL_NAMEREPLY.

      // The args are:
      //
      // """
      //   <target> ( "=" / "*" / "@" ) <channel>
      //    :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )
      //
      //   - "@" is used for secret channels, "*" for private
      //     channels, and "=" for others (public channels).
      // """ -- rfc2812

      var channel = command.args[2];
      if (channel != CHANNEL)
        return;

      var partialUserList = command.args[3].split(' ');
      for (var i = 0, l = partialUserList.length; i < l; ++i) {
        var name = $.trim(partialUserList[i]);
        if (name == "" || users[name])
          continue;
        addName(name);
      }
    } else if (responseCode == 366) {
      // 366 is the code for RPL_ENDOFNAMES.

      fillUserList();

      $("

").
        html("Joined " + CHANNEL + " channel.").
        appendTo("#chathistory");
      scrollDown();
    }
  };

  irc.onopen = function() {
    irc.nick(nickname);
    irc.ident(nickname, '8 *', nickname);
    irc.join(CHANNEL);

    // Once we have joined, don't leave without warning the user
    window.onbeforeunload = function() {
      return 'Are you sure you want to quit and lose the chat connection?';
    };
    $(window).unload(function() {
        hardquit();
//      quit();
    })
  }
  irc.onclose = function() {
    log.debug("closed...");
  };
  irc.onNICK = function(command) {
    // See http://tools.ietf.org/html/rfc2812#section-3.1.2
    var previousNick = parseName(command.prefix);
    var newNick = command.args[0];
    userRenamed(previousNick, newNick);
  };
  // TODO implement onNOTICE...
  irc.onJOIN = function(command) {
    var joiner = parseName(command.prefix);

    addName(joiner);
    fillUserList();

    $("

")
      .html("" + joiner + ' has joined ' + CHANNEL)
      .appendTo("#chathistory");
    scrollDown();
  }
  irc.onPART = function(command) {
    var leaver = parseName(command.prefix);
    var message = command.args.join(" ");

    $("

")
      .html("" + leaver + ' left ' + CHANNEL +
            (message ? ' (“' + sanitize(message) + '”)' : ''))
      .appendTo("#chathistory");
    scrollDown();

    removeName(leaver);
  }

  irc.onQUIT = function(command) {
    var quitter = parseName(command.prefix);
    var message = command.args.join(" ");

    $("

")
      .html("" + quitter + ' quit' +
            (message ? ' (“' + sanitize(message) + '”)' : ''))
      .appendTo("#chathistory");
    scrollDown();

    removeName(quitter);
  }

  irc.connect(IRC_SERVER, IRC_PORT);
};

var chat = function () {
  msg = $('#chatbox_input').val();
  irc.privmsg(CHANNEL, msg);
  $('#chatbox_input').val('');
  // the IRC server will not echo our message back, so simulate a send.
  irc.onPRIVMSG({prefix:nickname,type:'PRIVMSG',args:[CHANNEL, msg]});
}
var hardquit = function() {
    irc.reset();
}
var quit = function () {
  // XXX sometimes the quit reason is not seen when we quit...
  //     probably because the browser is immediately closed
  //     without waiting for socket flush?
  irc.quit();
}

// TODO enable the nick change code.
// function nickChanged(newnick) {
//     userRenamed(nickname, newnick);
//     nickname = newnick;
// }

function userRenamed(oldname, newname) {
  $("

")
    .html("" + oldname + " is now known as " +
          "" + newname + "")
    .appendTo("#chathistory");
  scrollDown();

  $(".user_list .user#user_" + oldname)
    .attr("id", "user_" + newname)
    .html(newname);
}

var user_priviledges = function (name) {
  var privs_symbols = {"@":"admin", "%":"subadmin", "+":"voice"};
  if (name[0] in privs_symbols) {
    return privs_symbols[name[0]];
  } else {
    return "";
  };
};

var addName = function (name) {
  // XXX this MUST remove the nick privileges from name (eg: because
  //     these prefixes are not sent when the user changed his nick,
  //     etc).
  var priviledges = user_priviledges(name);
  users[name] = {"privs":priviledges};
  $('
' + name + '
')
    .addClass(priviledges)
    .appendTo("#user_list");
};

var removeName = function (name) {
  delete users[name];
  $(".user_list #user_" + name).remove()
};

var fillUserList = function () {
  $('.user_list').empty();
  //alert("test");
  var list = [];
  for (var user in users) {
    list.push(user);
  };
  list.sort()
  for (var i=0; i < list.length; i++) {
    var user = list[i];
    privs = users[user]['privs'];
    $('
' + user + '
')
      .addClass(privs)
      .appendTo("#user_list");
  };
};

var scrollDown = function () {
  var box = document.getElementById('chathistory');
  box.scrollTop = box.scrollHeight;
}

var isSubstring = function (sub, str) {
  // case insensitive substring test
  return str.toLowerCase().indexOf(sub.toLowerCase()) >= 0;
};

var sanitize = (function(str) {
  // See http://bigdingus.com/2007/12/29/html-escaping-in-javascript/
  var MAP = {
    '&': '&',
    '<': '<',
    '>': '>',
    '"': '"',
    "'": '''
  };
  var repl = function(c) { return MAP[c]; };
  return function(s) {
    return s.replace(/[&<>'"]/g, repl);
  };
})();

// function infoMessage(message) {
//   $("

")
//     .html(message)
//     .appendTo("#chathistory");
//   scrollDown();
// };
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { ThemeContext as IconThemeContext } from 'grommet-icons';

import ThemeContext from '../../contexts/ThemeContext';
import ResponsiveContext from '../../contexts/ResponsiveContext';
import baseTheme from '../../themes/vanilla';
import { colorIsDark, deepMerge } from '../../utils';
import { withIconTheme } from '../hocs';

import StyledGrommet from './StyledGrommet';
import doc from './doc';

class Grommet extends Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    const { iconTheme, theme } = nextProps;
    const { theme: stateTheme, themeProp, iconThemeProp } = prevState;

    let nextTheme;
    if (theme && (theme !== themeProp || iconTheme !== iconThemeProp)) {
      nextTheme = deepMerge(baseTheme, theme);
    } else if (!theme && (themeProp || !stateTheme)) {
      nextTheme = baseTheme;
    }

    if (nextTheme) {
      const color = nextTheme.global.colors.background;
      const dark = color ? colorIsDark(color) : false;
      const lightIconTheme = deepMerge(iconTheme, nextTheme.icon);
      const iconThemes = {
        dark: deepMerge(lightIconTheme, {
          color: nextTheme.global.colors.darkBackground.text,
        }),
        light: lightIconTheme,
      };
      return {
        theme: {
          ...nextTheme,
          dark,
          icon: dark ? iconThemes.dark : iconThemes.light,
          iconThemes,
        },
        themeProp: theme,
        iconThemeProp: iconTheme,
      };
    }
    return null;
  }

  state = {}

  componentDidMount() {
    window.addEventListener('resize', this.onResize);
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.onResize);
  }

  onResize = () => {
    const { theme, responsive } = this.state;
    if (window.innerWidth > theme.global.breakpoints.narrow) {
      if (responsive !== 'wide') {
        this.setState({ responsive: 'wide' });
      }
    } else if (responsive !== 'narrow') {
      this.setState({ responsive: 'narrow' });
    }
  }

  render() {
    const { children, ...rest } = this.props;
    delete rest.theme;
    const { responsive, theme } = this.state;

    return (
      <ThemeContext.Provider value={theme}>
        <IconThemeContext.Provider value={theme.icon}>
          <ResponsiveContext.Provider value={responsive}>
            <StyledGrommet {...rest} theme={theme}>
              {children}
            </StyledGrommet>
          </ResponsiveContext.Provider>
        </IconThemeContext.Provider>
      </ThemeContext.Provider>
    );
  }
}

if (process.env.NODE_ENV !== 'production') {
  doc(Grommet);
}

export default withIconTheme(Grommet);
<commit_msg>Fixed an issue with ResponsiveContext<commit_after>import React, { Component } from 'react';
import { ThemeContext as IconThemeContext } from 'grommet-icons';

import ThemeContext from '../../contexts/ThemeContext';
import ResponsiveContext from '../../contexts/ResponsiveContext';
import baseTheme from '../../themes/vanilla';
import { colorIsDark, deepMerge } from '../../utils';
import { withIconTheme } from '../hocs';

import StyledGrommet from './StyledGrommet';
import doc from './doc';

class Grommet extends Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    const { iconTheme, theme } = nextProps;
    const { theme: stateTheme, themeProp, iconThemeProp } = prevState;

    let nextTheme;
    if (theme && (theme !== themeProp || iconTheme !== iconThemeProp)) {
      nextTheme = deepMerge(baseTheme, theme);
    } else if (!theme && (themeProp || !stateTheme)) {
      nextTheme = baseTheme;
    }

    if (nextTheme) {
      const color = nextTheme.global.colors.background;
      const dark = color ? colorIsDark(color) : false;
      const lightIconTheme = deepMerge(iconTheme, nextTheme.icon);
      const iconThemes = {
        dark: deepMerge(lightIconTheme, {
          color: nextTheme.global.colors.darkBackground.text,
        }),
        light: lightIconTheme,
      };
      return {
        theme: {
          ...nextTheme,
          dark,
          icon: dark ? iconThemes.dark : iconThemes.light,
          iconThemes,
        },
        themeProp: theme,
        iconThemeProp: iconTheme,
      };
    }
    return null;
  }

  state = {}

  componentDidMount() {
    window.addEventListener('resize', this.onResize);
    this.onResize();
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.onResize);
  }

  onResize = () => {
    const { theme, responsive } = this.state;
    if (window.innerWidth > theme.global.breakpoints.narrow) {
      if (responsive !== 'wide') {
        this.setState({ responsive: 'wide' });
      }
    } else if (responsive !== 'narrow') {
      this.setState({ responsive: 'narrow' });
    }
  }

  render() {
    const { children, ...rest } = this.props;
    delete rest.theme;
    const { responsive, theme } = this.state;

    return (
      <ThemeContext.Provider value={theme}>
        <IconThemeContext.Provider value={theme.icon}>
          <ResponsiveContext.Provider value={responsive}>
            <StyledGrommet {...rest} theme={theme}>
              {children}
            </StyledGrommet>
          </ResponsiveContext.Provider>
        </IconThemeContext.Provider>
      </ThemeContext.Provider>
    );
  }
}

if (process.env.NODE_ENV !== 'production') {
  doc(Grommet);
}

export default withIconTheme(Grommet);
<|endoftext|>


<commit_before>var React = require('react');
var Link = require('react-router').Link

var SideNav = React.createClass({

  componentDidMount () {
    $(".button-collapse").sideNav({
      menuWidth: 200,
      closeOnClick: true
    });
  },

  render: function(){
    var navArray = this.props.navArray;
    var NavItems = navArray.map(function(elem) {
      return (
<Link to={elem.url}>{elem.name}{elem.icon}</Link>
);
    });

    return (

<Link to='/' className="logo-our">{this.props.interface}</Link>

            {NavItems}

<Link to='/' className="logo-our">{this.props.interface}</Link>

            {NavItems}

    );
  }
});

module.exports = SideNav;
<commit_msg>fixed side nav<commit_after>var React = require('react');
var Link = require('react-router').Link;

var SideNav = React.createClass({

  componentDidMount () {
    $(".button-collapse").sideNav({
      closeOnClick: true
    });
  },

  render: function(){
    var navArray = this.props.navArray;
    var NavItems = navArray.map(function(elem) {
      return (
<Link to={elem.url}>{elem.name}{elem.icon}</Link>
);
    });

    return (

<Link to='/' className="logo-our">{this.props.interface}</Link>

            {NavItems}

<Link to='/' className="logo-our">{this.props.interface}</Link>

            {NavItems}

    );
  }
});

module.exports = SideNav;
<|endoftext|>


<commit_before>
import React from 'react';

import VerticalScrollbar from './vertical-scrollbar.js';
import HorizontalScrollbar from './horizontal-scrollbar.js';

require('../../sass/_Scrollbar.sass')

class ScrollWrapper extends React.Component {

  constructor() {
    super();
    this.state = {
      ready: false,
      scrollY: null,
      scrollX: null,
      top: 0,
      left: 0,
      scrollAreaHeight: null,
      scrollAreaWidth: null,
      scrollWrapperHeight: null,
      scrollWrapperWidth: null,
      verticalHeight: null,
      vMovement: 0,
      hMovement: 0,
      dragging: false,
      start: { y: 0, x: 0}
    }
  }

  render(){

    return(

      <div
        onClick={ this.calculateSize.bind(this) }
        className={ "react-scrollbar__wrapper" + ( this.props.className ? " " + this.props.className : "" ) }
        ref="scrollWrapper"
        style={this.props.style}
          >

        <div
          className={ "react-scrollbar__area" + ( this.state.dragging ? ' ' : ' react-scrollbar-transition') }
          ref="scrollArea"
          onWheel={ this.scroll.bind(this) }
          onTouchStart={ this.startDrag.bind(this) }
          onTouchMove={ this.onDrag.bind(this) }
          onTouchEnd={ this.stopDrag.bind(this) }
          style={{ marginTop: this.state.top * -1 +'px', marginLeft: this.state.left * -1 +'px' }} >

          { this.props.children }

          { this.state.ready ?

            <VerticalScrollbar
              area={{ height: this.state.scrollAreaHeight }}
              wrapper={{ height: this.state.scrollWrapperHeight }}
              scrolling={ this.state.vMovement }
              draggingFromParent={ this.state.dragging }
              onChangePosition={ this.handleChangePosition.bind(this) }
              onDragging={ this.handleScrollbarDragging.bind(this) }
              onStopDrag={ this.handleScrollbarStopDrag.bind(this) } />

          : null }

          { this.state.ready ?

            <HorizontalScrollbar
              area={{ width: this.state.scrollAreaWidth }}
              wrapper={{ width: this.state.scrollWrapperWidth }}
              scrolling={ this.state.hMovement }
              draggingFromParent={ this.state.dragging }
              onChangePosition={ this.handleChangePosition.bind(this) }
              onDragging={ this.handleScrollbarDragging.bind(this) }
              onStopDrag={ this.handleScrollbarStopDrag.bind(this) } />

          : null }

        </div>
      </div>

    )

  }

  scroll(e){
    e.preventDefault()

    // Make sure the content height is not changed
    this.calculateSize(() => {
      // Set the wheel step
      let num = this.props.speed

      // DOM events
      let shifted = e.shiftKey
      let scrollY = e.deltaY > 0 ? num : -(num)
      let scrollX = e.deltaX > 0 ? num : -(num)

      // Fix Mozilla Shifted Wheel~
      if(shifted && e.deltaX == 0) scrollX = e.deltaY > 0 ? num : -(num)

      // Next Value
      let nextY = this.state.top + scrollY
      let nextX = this.state.left + scrollX

      // Is it Scrollable?
      let canScrollY = this.state.scrollAreaHeight > this.state.scrollWrapperHeight
      let canScrollX = this.state.scrollAreaWidth > this.state.scrollWrapperWidth

      // Vertical Scrolling
      if(canScrollY && !shifted) this.normalizeVertical(nextY)

      // Horizontal Scrolling
      if(shifted && canScrollX) this.normalizeHorizontal(nextX)
    })

  }

  // DRAG EVENT JUST FOR TOUCH DEVICE~
  startDrag(e){
    e.preventDefault()
    e.stopPropagation()

    e = e.changedTouches ? e.changedTouches[0] : e

    // Make sure the content height is not changed
    this.calculateSize(() => {
      // Prepare to drag
      this.setState({
        dragging: true,
        start: { y: e.pageY, x: e.pageX }
      })
    })

  }

  onDrag(e){

    if(this.state.dragging){

      e.preventDefault()
      e = e.changedTouches ? e.changedTouches[0] : e

      // Invers the Movement
      let yMovement = this.state.start.y - e.pageY
      let xMovement = this.state.start.x - e.pageX

      // Update the last e.page
      this.setState({ start: { y: e.pageY, x: e.pageX } })

      // The next Vertical Value will be
      let nextY = this.state.top + yMovement
      let nextX = this.state.left + xMovement

      this.normalizeVertical(nextY)
      this.normalizeHorizontal(nextX)

    }

  }

  stopDrag(e){
    this.setState({ dragging: false })
  }

  normalizeVertical(next){

    // Vertical Scrolling
    let lowerEnd = this.state.scrollAreaHeight - this.state.scrollWrapperHeight

    // Max Scroll Down
    if(next > lowerEnd) next = lowerEnd

    // Max Scroll Up
    else if(next < 0) next = 0

    // Update the Vertical Value
    this.setState({
      top: next,
      vMovement: next / this.state.scrollAreaHeight * 100
    })
  }

  normalizeHorizontal(next){
    // Horizontal Scrolling
    let rightEnd = this.state.scrollAreaWidth - this.state.scrollWrapperWidth

    // Max Scroll Right
    if(next > rightEnd) next = rightEnd;

    // Max Scroll Right
    else if(next < 0) next = 0

    // Update the Horizontal Value
    this.setState({
      left: next,
      hMovement: next / this.state.scrollAreaWidth * 100
    })
  }

  handleChangePosition(movement, orientation){
    // Make sure the content height is not changed
    this.calculateSize(() => {
      // Convert Percentage to Pixel
      let next = movement / 100
      if( orientation == 'vertical' ) this.normalizeVertical( next * this.state.scrollAreaHeight )
      if( orientation == 'horizontal' ) this.normalizeHorizontal( next * this.state.scrollAreaWidth )
    })
  }

  handleScrollbarDragging(){
    this.setState({ dragging: true })
  }

  handleScrollbarStopDrag(){
    this.setState({ dragging: false })
  }

  getSize(){
    // The Elements
    let $scrollArea = this.refs.scrollArea
    let $scrollWrapper = this.refs.scrollWrapper

    // Get new Elements Size
    let elementSize = {
      // Scroll Area Height and Width
      scrollAreaHeight: $scrollArea.children[0].clientHeight,
      scrollAreaWidth: $scrollArea.children[0].clientWidth,

      // Scroll Wrapper Height and Width
      scrollWrapperHeight: $scrollWrapper.clientHeight,
      scrollWrapperWidth: $scrollWrapper.clientWidth,
    }

    return elementSize
  }

  calculateSize(cb){
    let elementSize = this.getSize()

    if( elementSize.scrollWrapperHeight != this.state.scrollWrapperHeight ||
        elementSize.scrollWrapperWidth != this.state.scrollWrapperWidth ||
        elementSize.scrollAreaHeight != this.state.scrollAreaHeight ||
        elementSize.scrollAreaWidth != this.state.scrollAreaWidth )
    {
      // Set the State!
      this.setState({

        // Scroll Area Height and Width
        scrollAreaHeight: elementSize.scrollAreaHeight,
        scrollAreaWidth: elementSize.scrollAreaWidth,

        // Scroll Wrapper Height and Width
        scrollWrapperHeight: elementSize.scrollWrapperHeight,
        scrollWrapperWidth: elementSize.scrollWrapperWidth,

        // Make sure The wrapper is Ready, then render the scrollbar
        ready: true
      }, () => cb ? cb() : false)
    }

    else return cb ? cb() : false
  }

  componentDidMount() {
    this.calculateSize()

    // Attach The Event for Responsive View~
    window.addEventListener('resize', this.calculateSize.bind(this))
  }

  componentWillUnmount(){
    // Remove Event
    window.removeEventListener('resize', this.calculateSize.bind(this))
  }

}

// The Props
ScrollWrapper.propTypes = {
  speed: React.PropTypes.number,
  className: React.PropTypes.string,
  style: React.PropTypes.object
}

ScrollWrapper.defaultProps = {
  speed: 53,
  className: "",
  style: {  }
}

export default ScrollWrapper;
<commit_msg>Uncaught TypeError: cb is not a function #2<commit_after>
import React from 'react';

import VerticalScrollbar from './vertical-scrollbar.js';
import HorizontalScrollbar from './horizontal-scrollbar.js';

require('../../sass/_Scrollbar.sass')

class ScrollWrapper extends React.Component {

  constructor() {
    super();
    this.state = {
      ready: false,
      scrollY: null,
      scrollX: null,
      top: 0,
      left: 0,
      scrollAreaHeight: null,
      scrollAreaWidth: null,
      scrollWrapperHeight: null,
      scrollWrapperWidth: null,
      verticalHeight: null,
      vMovement: 0,
      hMovement: 0,
      dragging: false,
      start: { y: 0, x: 0}
    }
  }

  render(){

    return(

      <div
        onClick={ this.calculateSize.bind(this) }
        className={ "react-scrollbar__wrapper" + ( this.props.className ? " " + this.props.className : "" ) }
        ref="scrollWrapper"
        style={this.props.style}
          >

        <div
          className={ "react-scrollbar__area" + ( this.state.dragging ? ' ' : ' react-scrollbar-transition') }
          ref="scrollArea"
          onWheel={ this.scroll.bind(this) }
          onTouchStart={ this.startDrag.bind(this) }
          onTouchMove={ this.onDrag.bind(this) }
          onTouchEnd={ this.stopDrag.bind(this) }
          style={{ marginTop: this.state.top * -1 +'px', marginLeft: this.state.left * -1 +'px' }} >

          { this.props.children }

          { this.state.ready ?

            <VerticalScrollbar
              area={{ height: this.state.scrollAreaHeight }}
              wrapper={{ height: this.state.scrollWrapperHeight }}
              scrolling={ this.state.vMovement }
              draggingFromParent={ this.state.dragging }
              onChangePosition={ this.handleChangePosition.bind(this) }
              onDragging={ this.handleScrollbarDragging.bind(this) }
              onStopDrag={ this.handleScrollbarStopDrag.bind(this) } />

          : null }

          { this.state.ready ?

            <HorizontalScrollbar
              area={{ width: this.state.scrollAreaWidth }}
              wrapper={{ width: this.state.scrollWrapperWidth }}
              scrolling={ this.state.hMovement }
              draggingFromParent={ this.state.dragging }
              onChangePosition={ this.handleChangePosition.bind(this) }
              onDragging={ this.handleScrollbarDragging.bind(this) }
              onStopDrag={ this.handleScrollbarStopDrag.bind(this) } />

          : null }

        </div>
      </div>

    )

  }

  scroll(e){
    e.preventDefault()

    // Make sure the content height is not changed
    this.calculateSize(() => {
      // Set the wheel step
      let num = this.props.speed

      // DOM events
      let shifted = e.shiftKey
      let scrollY = e.deltaY > 0 ? num : -(num)
      let scrollX = e.deltaX > 0 ? num : -(num)

      // Fix Mozilla Shifted Wheel~
      if(shifted && e.deltaX == 0) scrollX = e.deltaY > 0 ? num : -(num)

      // Next Value
      let nextY = this.state.top + scrollY
      let nextX = this.state.left + scrollX

      // Is it Scrollable?
      let canScrollY = this.state.scrollAreaHeight > this.state.scrollWrapperHeight
      let canScrollX = this.state.scrollAreaWidth > this.state.scrollWrapperWidth

      // Vertical Scrolling
      if(canScrollY && !shifted) this.normalizeVertical(nextY)

      // Horizontal Scrolling
      if(shifted && canScrollX) this.normalizeHorizontal(nextX)
    })

  }

  // DRAG EVENT JUST FOR TOUCH DEVICE~
  startDrag(e){
    e.preventDefault()
    e.stopPropagation()

    e = e.changedTouches ? e.changedTouches[0] : e

    // Make sure the content height is not changed
    this.calculateSize(() => {
      // Prepare to drag
      this.setState({
        dragging: true,
        start: { y: e.pageY, x: e.pageX }
      })
    })

  }

  onDrag(e){

    if(this.state.dragging){

      e.preventDefault()
      e = e.changedTouches ? e.changedTouches[0] : e

      // Invers the Movement
      let yMovement = this.state.start.y - e.pageY
      let xMovement = this.state.start.x - e.pageX

      // Update the last e.page
      this.setState({ start: { y: e.pageY, x: e.pageX } })

      // The next Vertical Value will be
      let nextY = this.state.top + yMovement
      let nextX = this.state.left + xMovement

      this.normalizeVertical(nextY)
      this.normalizeHorizontal(nextX)

    }

  }

  stopDrag(e){
    this.setState({ dragging: false })
  }

  normalizeVertical(next){

    // Vertical Scrolling
    let lowerEnd = this.state.scrollAreaHeight - this.state.scrollWrapperHeight

    // Max Scroll Down
    if(next > lowerEnd) next = lowerEnd

    // Max Scroll Up
    else if(next < 0) next = 0

    // Update the Vertical Value
    this.setState({
      top: next,
      vMovement: next / this.state.scrollAreaHeight * 100
    })
  }

  normalizeHorizontal(next){
    // Horizontal Scrolling
    let rightEnd = this.state.scrollAreaWidth - this.state.scrollWrapperWidth

    // Max Scroll Right
    if(next > rightEnd) next = rightEnd;

    // Max Scroll Right
    else if(next < 0) next = 0

    // Update the Horizontal Value
    this.setState({
      left: next,
      hMovement: next / this.state.scrollAreaWidth * 100
    })
  }

  handleChangePosition(movement, orientation){
    // Make sure the content height is not changed
    this.calculateSize(() => {
      // Convert Percentage to Pixel
      let next = movement / 100
      if( orientation == 'vertical' ) this.normalizeVertical( next * this.state.scrollAreaHeight )
      if( orientation == 'horizontal' ) this.normalizeHorizontal( next * this.state.scrollAreaWidth )
    })
  }

  handleScrollbarDragging(){
    this.setState({ dragging: true })
  }

  handleScrollbarStopDrag(){
    this.setState({ dragging: false })
  }

  getSize(){
    // The Elements
    let $scrollArea = this.refs.scrollArea
    let $scrollWrapper = this.refs.scrollWrapper

    // Get new Elements Size
    let elementSize = {
      // Scroll Area Height and Width
      scrollAreaHeight: $scrollArea.children[0].clientHeight,
      scrollAreaWidth: $scrollArea.children[0].clientWidth,

      // Scroll Wrapper Height and Width
      scrollWrapperHeight: $scrollWrapper.clientHeight,
      scrollWrapperWidth: $scrollWrapper.clientWidth,
    }

    return elementSize
  }

  calculateSize(cb){
    if(typeof(cb)!='function') cb = null;
    let elementSize = this.getSize()

    if( elementSize.scrollWrapperHeight != this.state.scrollWrapperHeight ||
        elementSize.scrollWrapperWidth != this.state.scrollWrapperWidth ||
        elementSize.scrollAreaHeight != this.state.scrollAreaHeight ||
        elementSize.scrollAreaWidth != this.state.scrollAreaWidth )
    {
      // Set the State!
      this.setState({

        // Scroll Area Height and Width
        scrollAreaHeight: elementSize.scrollAreaHeight,
        scrollAreaWidth: elementSize.scrollAreaWidth,

        // Scroll Wrapper Height and Width
        scrollWrapperHeight: elementSize.scrollWrapperHeight,
        scrollWrapperWidth: elementSize.scrollWrapperWidth,

        // Make sure The wrapper is Ready, then render the scrollbar
        ready: true
      }, () => cb ? cb() : false)
    }

    else return cb ? cb() : false
  }

  componentDidMount() {
    this.calculateSize()

    // Attach The Event for Responsive View~
    window.addEventListener('resize', this.calculateSize.bind(this))
  }

  componentWillUnmount(){
    // Remove Event
    window.removeEventListener('resize', this.calculateSize.bind(this))
  }

}

// The Props
ScrollWrapper.propTypes = {
  speed: React.PropTypes.number,
  className: React.PropTypes.string,
  style: React.PropTypes.object
}

ScrollWrapper.defaultProps = {
  speed: 53,
  className: "",
  style: {  }
}

export default ScrollWrapper;
<|endoftext|>


<commit_before>module.exports = function (options) {
    var routes = options.view
    var render = options.render

    function setLocation(data) {
        render(match(routes, data))
        history.pushState({}, "", data)
    }

    window.addEventListener("popstate", function () {
        render(match(routes, location.pathname))
    })

    window.addEventListener("click", function (e) {
        if (e.metaKey || e.shiftKey || e.ctrlKey || e.altKey) {
            return
        }

        var target = e.target

        while (target && target.localName !== "a") {
            target = target.parentNode
        }

        if (target && target.host === location.host
            && !target.hasAttribute("data-no-routing")) {

            var element = target.hash === "" ? element : document.querySelector(target.hash)
            if (element) {
                element.scrollIntoView(true)

            } else {
                setLocation(target.pathname)
                e.preventDefault()
            }
        }
    })

    render(match(routes, location.pathname))

    function match(routes, path) {
        for (var route in routes) {
            var re = regexify(route), params = {}, match

            path.replace(new RegExp(re.re, "g"), function () {
                for (var i = 1; i < arguments.length - 2; i++) {
                    params[re.keys.shift()] = arguments[i]
                }

                match = function (model, actions) {
                    if (actions) {
                        actions.setLocation = setLocation
                    }
                    return routes[route](model, actions, params)
                }
            })

            if (match) {
                return match
            }
        }

        return routes["/"]
    }

    function regexify(path) {
        var keys = [], re = "^" + path
            .replace(/\//g, "\\/")
            .replace(/:([A-Za-z0-9_]+)/g, function (_, key) {
                keys.push(key)
                return "([A-Za-z0-9_]+)"
            }) + "/?$"

        return { re: re, keys: keys }
    }
}

<commit_msg>document.querySelector can be called as long as seletor is not ''<commit_after>module.exports = function (options) {
    var routes = options.view
    var render = options.render

    function setLocation(data) {
        render(match(routes, data))
        history.pushState({}, "", data)
    }

    window.addEventListener("popstate", function () {
        render(match(routes, location.pathname))
    })

    window.addEventListener("click", function (e) {
        if (e.metaKey || e.shiftKey || e.ctrlKey || e.altKey) {
            return
        }

        var target = e.target

        while (target && target.localName !== "a") {
            target = target.parentNode
        }

        if (target && target.host === location.host
            && !target.hasAttribute("data-no-routing")) {

            var element = document.querySelector(target.hash === "" ? element : target.hash)

            if (element) {
                element.scrollIntoView(true)
            } else {
                e.preventDefault()
                setLocation(target.pathname)
            }
        }
    })

    render(match(routes, location.pathname))

    function match(routes, path) {
        for (var route in routes) {
            var re = regexify(route), params = {}, match

            path.replace(new RegExp(re.re, "g"), function () {
                for (var i = 1; i < arguments.length - 2; i++) {
                    params[re.keys.shift()] = arguments[i]
                }

                match = function (model, actions) {
                    actions.setLocation = setLocation
                    return routes[route](model, actions, params)
                }
            })

            if (match) {
                return match
            }
        }

        return routes["/"]
    }

    function regexify(path) {
        var keys = [], re = "^" + path
            .replace(/\//g, "\\/")
            .replace(/:([A-Za-z0-9_]+)/g, function (_, key) {
                keys.push(key)
                return "([A-Za-z0-9_]+)"
            }) + "/?$"

        return { re: re, keys: keys }
    }
}

<|endoftext|>


<commit_before>import {RequestUtil} from 'mesosphere-shared-reactjs';

import {
  REQUEST_SUMMARY_HISTORY_SUCCESS,
  REQUEST_MESOS_HISTORY_ONGOING,
  REQUEST_SUMMARY_SUCCESS,
  REQUEST_SUMMARY_ERROR,
  REQUEST_SUMMARY_ONGOING
} from '../constants/ActionTypes';
var AppDispatcher = require('./AppDispatcher');
var Config = require('../config/Config');
import {Hooks} from 'PluginSDK';
var TimeScales = require('../constants/TimeScales');

var _historyServiceOnline = true;

function testHistoryServerResponse(response) {
  // If the response is an empty object, that means something is whack
  // Fall back to making requests to Mesos
  if (response === {}) {
    _historyServiceOnline = false;
  }
}

function testHistoryOnline() {
  RequestUtil.json({
    url: `${Config.historyServer}/dcos-history-service/history/last`,
    success: function (response) {
      _historyServiceOnline = true;
      testHistoryServerResponse(response);
    },
    error: function () {
      setTimeout(testHistoryOnline, Config.testHistoryInterval);
    }
  });
}

function requestFromHistoryServer(resolve, reject, timeScale = 'last') {
  let url = `${Config.historyServer}/dcos-history-service/history/${timeScale}`;
  let successEventType = REQUEST_SUMMARY_SUCCESS;

  if (timeScale === TimeScales.MINUTE) {
    successEventType = REQUEST_SUMMARY_HISTORY_SUCCESS;
  }

  RequestUtil.json({
    url,
    success: function (response) {
      testHistoryServerResponse(response);
      AppDispatcher.handleServerAction({
        type: successEventType,
        data: response
      });
      resolve();
    },
    error: function () {
      _historyServiceOnline = false;

      setTimeout(testHistoryOnline, Config.testHistoryInterval);
      // Immediately fall back on state-summary
      requestFromMesos(resolve, reject);
    },
    hangingRequestCallback: function () {
      AppDispatcher.handleServerAction({type: REQUEST_MESOS_HISTORY_ONGOING});
    }
  });
}

function requestFromMesos(resolve, reject) {
  RequestUtil.json({
    url: `${Config.rootUrl}/mesos/master/state-summary`,
    success: function (response) {
      AppDispatcher.handleServerAction({
        type: REQUEST_SUMMARY_SUCCESS,
        data: response
      });
      resolve();
    },
    error: function (e) {
      AppDispatcher.handleServerAction({
        type: REQUEST_SUMMARY_ERROR,
        data: e.message
      });
      reject();
    },
    hangingRequestCallback: function () {
      AppDispatcher.handleServerAction({type: REQUEST_SUMMARY_ONGOING});
    }
  });
}

var MesosSummaryActions = {

  fetchSummary: RequestUtil.debounceOnError(
    Config.getRefreshRate(),
    function (resolve, reject) {

      return function (timeScale) {
        let canAccessHistoryServer = Hooks.applyFilter(
          'hasCapability', false, 'historyServiceAPI'
        );

        if (!_historyServiceOnline || !canAccessHistoryServer) {
          requestFromMesos(resolve, reject);
        } else {
          requestFromHistoryServer(resolve, reject, timeScale);
        }
      };
    },
    {delayAfterCount: Config.delayAfterErrorCount}
  )

};

module.exports = MesosSummaryActions;
<commit_msg>Adding crude test of history server data in MesosSummaryActions<commit_after>import {RequestUtil} from 'mesosphere-shared-reactjs';

import {
  REQUEST_SUMMARY_HISTORY_SUCCESS,
  REQUEST_MESOS_HISTORY_ONGOING,
  REQUEST_SUMMARY_SUCCESS,
  REQUEST_SUMMARY_ERROR,
  REQUEST_SUMMARY_ONGOING
} from '../constants/ActionTypes';
var AppDispatcher = require('./AppDispatcher');
var Config = require('../config/Config');
import {Hooks} from 'PluginSDK';
var TimeScales = require('../constants/TimeScales');

var _historyServiceOnline = true;

function testHistoryServerResponse(response) {
  // If the response is an empty object, that means something is whack
  // Fall back to making requests to Mesos
  if (response === {} ||
      Array.isArray(response.frameworks) ||
      Array.isArray(response.slaves)) {
    _historyServiceOnline = false;
  }
}

function testHistoryOnline() {
  RequestUtil.json({
    url: `${Config.historyServer}/dcos-history-service/history/last`,
    success: function (response) {
      _historyServiceOnline = true;
      testHistoryServerResponse(response);
    },
    error: function () {
      setTimeout(testHistoryOnline, Config.testHistoryInterval);
    }
  });
}

function requestFromHistoryServer(resolve, reject, timeScale = 'last') {
  let url = `${Config.historyServer}/dcos-history-service/history/${timeScale}`;
  let successEventType = REQUEST_SUMMARY_SUCCESS;

  if (timeScale === TimeScales.MINUTE) {
    successEventType = REQUEST_SUMMARY_HISTORY_SUCCESS;
  }

  RequestUtil.json({
    url,
    success: function (response) {
      testHistoryServerResponse(response);
      AppDispatcher.handleServerAction({
        type: successEventType,
        data: response
      });
      resolve();
    },
    error: function () {
      _historyServiceOnline = false;

      setTimeout(testHistoryOnline, Config.testHistoryInterval);
      // Immediately fall back on state-summary
      requestFromMesos(resolve, reject);
    },
    hangingRequestCallback: function () {
      AppDispatcher.handleServerAction({type: REQUEST_MESOS_HISTORY_ONGOING});
    }
  });
}

function requestFromMesos(resolve, reject) {
  RequestUtil.json({
    url: `${Config.rootUrl}/mesos/master/state-summary`,
    success: function (response) {
      AppDispatcher.handleServerAction({
        type: REQUEST_SUMMARY_SUCCESS,
        data: response
      });
      resolve();
    },
    error: function (e) {
      AppDispatcher.handleServerAction({
        type: REQUEST_SUMMARY_ERROR,
        data: e.message
      });
      reject();
    },
    hangingRequestCallback: function () {
      AppDispatcher.handleServerAction({type: REQUEST_SUMMARY_ONGOING});
    }
  });
}

var MesosSummaryActions = {

  fetchSummary: RequestUtil.debounceOnError(
    Config.getRefreshRate(),
    function (resolve, reject) {

      return function (timeScale) {
        let canAccessHistoryServer = Hooks.applyFilter(
          'hasCapability', false, 'historyServiceAPI'
        );

        if (!_historyServiceOnline || !canAccessHistoryServer) {
          requestFromMesos(resolve, reject);
        } else {
          requestFromHistoryServer(resolve, reject, timeScale);
        }
      };
    },
    {delayAfterCount: Config.delayAfterErrorCount}
  )

};

module.exports = MesosSummaryActions;
<|endoftext|>


<commit_before>import find from 'lodash/find'
import merge from 'lodash/merge'
import each from 'lodash/each'

import events from './store/module/events'

/**
 * Includes language in the route
 * @param  {Object} route
 * @return {Object}
 */
export const localize = (route, urlPrefix) => {
  let originalRouteParams = route.params || {}
  return merge(route, {
    params: {
      ...originalRouteParams,
      lang: urlPrefix
    }
  })
}

/**
 * Update URL prefix
 * @param  {VueRouter} router
 * @param  {String} urlPrefix
 */
export const updateURLPrefix = (router, urlPrefix) => {
  const { currentRoute } = router

  if (router && currentRoute) {
    router.replace(localize({ name: currentRoute.name }, urlPrefix))
  }
}

/**
 * Applies specific functionalities to handle language redirects and URL prefixing.
 * The application will be able to add the language urlPrefix property in its URL and
 * to change the application language based on that specific parameter.
 * If that urlPrefix provided via URL is not valid or it doesn't exist the application
 * will fallback to the default language.
 * VueRouter instance is required to unlock this feature.
 */
export const registerRouter = (router, store) => {
  if (!router) {
    return
  }

  // First time the router is registered, the route needs to be synced with the current language
  updateURLPrefix(router, store.getters.currentLanguage.urlPrefix)

  router.beforeEach((to, from, next) => {
    const { availableLanguages, currentLanguage, forceTranslation, languages } = store.getters
    const urlPrefix = to.params.lang
    const languageList = forceTranslation ? languages : availableLanguages
    const urlLanguage = find(languageList, { urlPrefix })

    /**
     * In case the language is not provided or doesn't exists,
     * the default language will be used.
     * This will only be fired on landing, because most of the time
     * the URL doesn't contain a language prefix or the user typed
     * a different language on purpose and we need to check it.
     */
    if (!urlLanguage || !from.name) {
      return next(localize({ name: to.name }, currentLanguage.urlPrefix))
    }

    /**
     * Check if the detected language in the URL is also the current
     * translated language, otherwise it needs to be updated.
     * Browser language has prioriry over the store state
     */
    const isDiff = urlLanguage && urlLanguage.urlPrefix !== currentLanguage.urlPrefix

    if (isDiff) {
      return store.dispatch(events.SET_LANGUAGE, urlLanguage.code).then(() => next())
    }

    next()
  })
}

/**
 * Route parser takes the current routes object before is injected in the VueRouter instance
 * and it returns the necessary tree structure to enable language prefixing
 * @param  {Array<Object>} routes
 * @param  {String} [defaultCode='en'] - language redirect
 * @return {Array<Object>}
 */
export const routeParser = (routes, defaultCode = 'en') => {
  each(routes, route => {
    const { path } = route
    route.path = `/:lang${path}`
  })

  return [
    ...routes,
    {
      path: '/*',
      name: 'redirect',
      redirect: {
        path: `/${defaultCode}`
      }
    }
  ]
}

export default function (Vue, router, store) {
  Vue.prototype.$localize = (route) => {
    return localize(route, store.getters.currentLanguage.urlPrefix)
  }
}
<commit_msg>fix($localize): no data loss during route localization<commit_after>import find from 'lodash/find'
import merge from 'lodash/merge'
import each from 'lodash/each'

import events from './store/module/events'

/**
 * Includes language in the route
 * @param  {Object} route
 * @return {Object}
 */
export const localize = (route, urlPrefix) => {
  let originalRouteParams = route.params || {}

  /**
   * It's not possible to push/replace a route with the readonly property `path`
   * so it's necessary to copy the route in a new object first and then delete
   * the property
   */
  let routeCopy = { ...route }
  delete routeCopy.path

  return merge(routeCopy, {
    params: {
      ...originalRouteParams,
      lang: urlPrefix
    }
  })
}

/**
 * Update URL prefix
 * @param  {VueRouter} router
 * @param  {String} urlPrefix
 */
export const updateURLPrefix = (router, urlPrefix) => {
  const { currentRoute } = router

  if (router && currentRoute) {
    router.replace(localize(currentRoute, urlPrefix))
  }
}

/**
 * Applies specific functionalities to handle language redirects and URL prefixing.
 * The application will be able to add the language urlPrefix property in its URL and
 * change the application language based on that specific parameter.
 * If that prefix is not valid or it doesn't exist, the application will fallback
 * to the default language.
 * VueRouter instance is required to unlock this feature.
 */
export const registerRouter = (router, store) => {
  if (!router) {
    return
  }

  // First time the router is registered, the route needs to be synced with the current language
  updateURLPrefix(router, store.getters.currentLanguage.urlPrefix)

  router.beforeEach((to, from, next) => {
    const { availableLanguages, currentLanguage, forceTranslation, languages } = store.getters
    const urlPrefix = to.params.lang
    const languageList = forceTranslation ? languages : availableLanguages
    const urlLanguage = find(languageList, { urlPrefix })

    /**
     * In case the language is not provided or doesn't exists,
     * the default language will be used.
     * This will only be fired on landing, because most of the time
     * the URL doesn't contain a language prefix or the user typed
     * a different language on purpose and we need to check it.
     */
    if (!urlLanguage || !from.name) {
      return next(localize(to, currentLanguage.urlPrefix))
    }

    /**
     * Check if the detected language in the URL is also the current
     * translated language, otherwise it needs to be updated.
     * Browser language has prioriry over the store state
     */
    const isDiff = urlLanguage && urlLanguage.urlPrefix !== currentLanguage.urlPrefix

    if (isDiff) {
      return store.dispatch(events.SET_LANGUAGE, urlLanguage.code).then(() => next())
    }

    next()
  })
}

/**
 * Route parser takes the current routes object before is injected in the VueRouter instance
 * and it returns the necessary tree structure to enable language prefixing
 * @param  {Array<Object>} routes
 * @param  {String} [defaultCode='en'] - language redirect
 * @return {Array<Object>}
 */
export const routeParser = (routes, defaultCode = 'en') => {
  each(routes, route => {
    const { path } = route
    route.path = `/:lang${path}`
  })

  return [
    ...routes,
    {
      path: '/*',
      name: 'redirect',
      redirect: {
        path: `/${defaultCode}`
      }
    }
  ]
}

export default function (Vue, router, store) {
  Vue.prototype.$localize = (route) => {
    return localize(route, store.getters.currentLanguage.urlPrefix)
  }
}
<|endoftext|>


<commit_before>export default function(app) {
  return {
    state: {
      router: match(location.pathname)
    },
    actions: {
      router: {
        match: function(state, actions, data, emit) {
          return {
            router: emit("route", match(data))
          }
        },
        go: function(state, actions, data) {
          history.pushState({}, "", data)
          actions.router.match(data)
        }
      }
    },
    events: {
      loaded: function(state, actions) {
        match()
        addEventListener("popstate", match)
        function match() {
          actions.router.match(location.pathname)
        }
      },
      render: function(state, actions, view) {
        return view[state.router.match]
      }
    }
  }

  function match(data) {
    var match
    var params = {}

    for (var route in app.view) {
      var keys = []

      if (!match && route !== "*") {
        data.replace(
          RegExp(
            "^" +
              route
                .replace(/\//g, "\\/")
                .replace(/:([\w]+)/g, function(_, key) {
                  keys.push(key)
                  return "([-\\w]+)"
                }) +
              "/?$",
            "g"
          ),
          function() {
            for (var i = 1; i < arguments.length - 2; ) {
              params[keys.shift()] = arguments[i++]
            }
            match = route
          }
        )
      }
    }

    return {
      match: match || "*",
      params: params
    }
  }
}
<commit_msg>Fix internal routing of URLs with query strings (#217)<commit_after>export default function(app) {
  return {
    state: {
      router: match(location.pathname)
    },
    actions: {
      router: {
        match: function(state, actions, data, emit) {
          return {
            router: emit("route", match(data))
          }
        },
        go: function(state, actions, data) {
          history.pushState({}, "", data)
          actions.router.match(data.split('?')[0])
        }
      }
    },
    events: {
      loaded: function(state, actions) {
        match()
        addEventListener("popstate", match)
        function match() {
          actions.router.match(location.pathname)
        }
      },
      render: function(state, actions, view) {
        return view[state.router.match]
      }
    }
  }

  function match(data) {
    var match
    var params = {}

    for (var route in app.view) {
      var keys = []

      if (!match && route !== "*") {
        data.replace(
          RegExp(
            "^" +
              route
                .replace(/\//g, "\\/")
                .replace(/:([\w]+)/g, function(_, key) {
                  keys.push(key)
                  return "([-\\w]+)"
                }) +
              "/?$",
            "g"
          ),
          function() {
            for (var i = 1; i < arguments.length - 2; ) {
              params[keys.shift()] = arguments[i++]
            }
            match = route
          }
        )
      }
    }

    return {
      match: match || "*",
      params: params
    }
  }
}
<|endoftext|>


<commit_before>/**
 * @author: @AngularClass
 */

module.exports = function(config) {
  var testWebpackConfig = require('./webpack.test.js');

  config.set({

    // base path that will be used to resolve all patterns (e.g. files, exclude)
    basePath: '',

    /*
     * Frameworks to use
     *
     * available frameworks: https://npmjs.org/browse/keyword/karma-adapter
     */
    frameworks: ['jasmine'],

    // list of files to exclude
    exclude: [ ],

    /*
     * list of files / patterns to load in the browser
     *
     * we are building the test environment in ./spec-bundle.js
     */
    files: [ { pattern: './config/spec-bundle.js', watched: false } ],

    /*
     * preprocess matching files before serving them to the browser
     * available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
     */
    preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] },

    // Webpack Config at ./webpack.test.js
    webpack: testWebpackConfig,

    coverageReporter: {
      dir : 'coverage/',
      reporters: [
        { type: 'text-summary' },
        { type: 'json' },
        { type: 'html' }
      ]
    },

    // Webpack please don't spam the console when running in karma!
    webpackServer: { noInfo: true },

    /*
     * test results reporter to use
     *
     * possible values: 'dots', 'progress'
     * available reporters: https://npmjs.org/browse/keyword/karma-reporter
     */
    reporters: [ 'mocha', 'coverage' ],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    /*
     * level of logging
     * possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
     */
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    /*
     * start these browsers
     * available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
     */
    browsers: [
      // 'Chrome',
      'PhantomJS'
    ],

    /*
     * Continuous Integration mode
     * if true, Karma captures browsers, runs the tests and exits
     */
    singleRun: true
  });

};
<commit_msg>Enabled watch mode in Karma.<commit_after>/**
 * @author: @AngularClass
 */

module.exports = function(config) {
  var testWebpackConfig = require('./webpack.test.js');

  config.set({

    // base path that will be used to resolve all patterns (e.g. files, exclude)
    basePath: '',

    /*
     * Frameworks to use
     *
     * available frameworks: https://npmjs.org/browse/keyword/karma-adapter
     */
    frameworks: ['jasmine'],

    // list of files to exclude
    exclude: [ ],

    /*
     * list of files / patterns to load in the browser
     *
     * we are building the test environment in ./spec-bundle.js
     */
    files: [ { pattern: './config/spec-bundle.js', watched: true} ],

    /*
     * preprocess matching files before serving them to the browser
     * available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
     */
    preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] },

    // Webpack Config at ./webpack.test.js
    webpack: testWebpackConfig,

    coverageReporter: {
      dir : 'coverage/',
      reporters: [
        { type: 'text-summary' },
        { type: 'json' },
        { type: 'html' }
      ]
    },

    // Webpack please don't spam the console when running in karma!
    webpackServer: { noInfo: true },

    /*
     * test results reporter to use
     *
     * possible values: 'dots', 'progress'
     * available reporters: https://npmjs.org/browse/keyword/karma-reporter
     */
    reporters: [ 'mocha', 'coverage' ],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    /*
     * level of logging
     * possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
     */
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    /*
     * start these browsers
     * available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
     */
    browsers: [
      // 'Chrome',
      'PhantomJS'
    ],

    /*
     * Continuous Integration mode
     * if true, Karma captures browsers, runs the tests and exits
     */
    singleRun: false
  });

};
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    //debug = require('gulp-debug'),
    flatten = require('gulp-flatten'),
    shell = require('gulp-shell'),
    del = require('del'),
    msbuild = require('gulp-msbuild'),
    assemblyInfo = require('gulp-dotnet-assembly-info'),
    argv = require('yargs').argv,
    sequence = require('run-sequence');

var config = {
  slnname: 'Requester',
  src: './../src/',
  build: {
    outdir: './build/',
    version: '0.6.0',
    revision: argv.buildrevision || '0',
    profile: argv.buildprofile || 'Release'
  }
};

gulp.task('default', function (cb) {
  sequence(
    ['clean', 'assemblyinfo'],
    'build', 'copy', 'integration-tests', cb);
});

gulp.task('ci', function (cb) {
  sequence(
    ['init-tools', 'clean', 'assemblyinfo', 'nuget-restore'],
    'build', 'copy', 'integration-tests', 'nuget-pack', cb);
});

gulp.task('init-tools', shell.task([
  'nuget restore ./tools/packages.config -o ./tools/']
));

gulp.task('nuget-restore', function () {
  return gulp.src(config.src + '*.sln', { read: false })
    .pipe(shell('nuget restore <%= file.path %>'));
});

gulp.task('clean', function(cb) {
  del(config.build.outdir, cb);
});

gulp.task('assemblyinfo', function() {
  return gulp
    .src(config.src + 'GlobalAssemblyInfo.cs')
    .pipe(assemblyInfo({
      version: config.build.version + '.' + config.build.revision
    }))
    .pipe(gulp.dest(config.src));
});

gulp.task('build', function() {
  return gulp.src(config.src + '*.sln')
    .pipe(msbuild({
      toolsVersion: 14.0,
      configuration: config.build.profile,
      targets: ['Clean', 'Build'],
      errorOnFail: true,
      stdout: true,
      verbosity: 'minimal'
    }));
});

gulp.task('copy', function() {
  return gulp.src(config.src + 'projects/**/bin/' + config.build.profile + '/*.{dll,XML}')
    .pipe(flatten())
    .pipe(gulp.dest(config.build.outdir));
});

gulp.task('integration-tests', function () {
  return gulp.src(config.src + 'tests/**/bin/' + config.build.profile + '/*.IntegrationTests.dll')
    .pipe(shell('xunit.console.exe <%= file.path %> -noshadow', { cwd: './tools/xunit.runner.console.2.1.0/tools/' }));
});

gulp.task('nuget-pack', shell.task([
  'nuget pack ./' + config.slnname + '.nuspec -version ' + config.build.version + ' -basepath ' + config.build.outdir + ' -o ' + config.build.outdir]
));<commit_msg>Bumped v0.7.0<commit_after>var gulp = require('gulp'),
    //debug = require('gulp-debug'),
    flatten = require('gulp-flatten'),
    shell = require('gulp-shell'),
    del = require('del'),
    msbuild = require('gulp-msbuild'),
    assemblyInfo = require('gulp-dotnet-assembly-info'),
    argv = require('yargs').argv,
    sequence = require('run-sequence');

var config = {
  slnname: 'Requester',
  src: './../src/',
  build: {
    outdir: './build/',
    version: '0.7.0',
    revision: argv.buildrevision || '0',
    profile: argv.buildprofile || 'Release'
  }
};

gulp.task('default', function (cb) {
  sequence(
    ['clean', 'assemblyinfo'],
    'build', 'copy', 'integration-tests', cb);
});

gulp.task('ci', function (cb) {
  sequence(
    ['init-tools', 'clean', 'assemblyinfo', 'nuget-restore'],
    'build', 'copy', 'integration-tests', 'nuget-pack', cb);
});

gulp.task('init-tools', shell.task([
  'nuget restore ./tools/packages.config -o ./tools/']
));

gulp.task('nuget-restore', function () {
  return gulp.src(config.src + '*.sln', { read: false })
    .pipe(shell('nuget restore <%= file.path %>'));
});

gulp.task('clean', function(cb) {
  del(config.build.outdir, cb);
});

gulp.task('assemblyinfo', function() {
  return gulp
    .src(config.src + 'GlobalAssemblyInfo.cs')
    .pipe(assemblyInfo({
      version: config.build.version + '.' + config.build.revision
    }))
    .pipe(gulp.dest(config.src));
});

gulp.task('build', function() {
  return gulp.src(config.src + '*.sln')
    .pipe(msbuild({
      toolsVersion: 14.0,
      configuration: config.build.profile,
      targets: ['Clean', 'Build'],
      errorOnFail: true,
      stdout: true,
      verbosity: 'minimal'
    }));
});

gulp.task('copy', function() {
  return gulp.src(config.src + 'projects/**/bin/' + config.build.profile + '/*.{dll,XML}')
    .pipe(flatten())
    .pipe(gulp.dest(config.build.outdir));
});

gulp.task('integration-tests', function () {
  return gulp.src(config.src + 'tests/**/bin/' + config.build.profile + '/*.IntegrationTests.dll')
    .pipe(shell('xunit.console.exe <%= file.path %> -noshadow', { cwd: './tools/xunit.runner.console.2.1.0/tools/' }));
});

gulp.task('nuget-pack', shell.task([
  'nuget pack ./' + config.slnname + '.nuspec -version ' + config.build.version + ' -basepath ' + config.build.outdir + ' -o ' + config.build.outdir]
));<|endoftext|>