<commit_before>/**
 * Author: Olaolu Olawuyi

 * Date Created: 20/08/2015

 * Last Modified: 14/02/2016

 * Twitter: @whizkydee, @webtwic

 * Github: https://github.com/whizkydee/whizkydee.github.io

*/

var Webtwic = Webtwic || {};

var browser = bowser;

var test_canvas = document.createElement("canvas");
var canvascheck=(test_canvas.getContext)? true : false;

Webtwic = {
	// Basic Information about Webtwic
	name: "Webtwic",
	description: "A community for coding and tech tweaks where beginners and experts can learn.",
	repo: "https://github.com/whizkydee/whizkydee.github.io",
	author: "Olaolu Olawuyi",
	version: 1.07,

	// Start main functions for the object

	// Function to add browser name and version to body class
	_showBrowser: function(b) {
		$("body").addClass(b + " " + b + parseInt(browser.version));
	},

	// Function to set attributes and values to elements
	_setAttr: function(elem, name, val) {
		$(elem, this).attr(name, val);
	},

	// Function to push down .site-content
	_adjustSiteContent: function() {
		if( $("body").hasClass("default-body") ) {
			$(".top-stripe").addClass("adjustedMargin");
			$("#header .logo").addClass("adjustedTop");
			$(".main-menu").addClass("adjustedMargin");
			$("#header").addClass("adjustSiteContent");
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".site-content").addClass("adjustSiteContent");
			$(".secondary-header").addClass("adjustedMargin");
		}
	},

	// Function to push up .site-content to default state
	_undoSiteAdjust: function() {
		if( $("body").hasClass("default-body") ) {
			$(".top-stripe").removeClass("adjustedMargin");
			$("#header .logo").removeClass("adjustedTop");
			$(".main-menu").removeClass("adjustedMargin");
			$("#header").removeClass("adjustSiteContent");
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".secondary-header").removeClass("adjustedMargin");
		}
	},

	// Function to show Notifications before header
	_showNotif: function(text) {
		text = (typeof text == "undefined") ? notif_text : text;
		Webtwic._adjustSiteContent();
		if( $("body").hasClass("default-body") ) {
			$(".top-stripe").before(
				"
"+text+"
"
			);
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".secondary-header").before(
				"
"+text+"
"
			);
		} else {
			return;
		}
		$(".close-button").on("click", function() {
			Webtwic._undoReset();
		});
	},

	// Function to hide Notifications
	_hideNotif: function() {
		$("#notifBanner").removeClass("notif_vis");
	},

	_resetSite: function() {
		Webtwic._showNotif();
		Webtwic._adjustSiteContent();
	},

	_undoReset: function() {
		Webtwic._hideNotif();
		Webtwic._undoSiteAdjust();
	},

	// Function to launch modal

	_launchModal: function(w, h, r, p, c, e, b) {
		this.width = w;
	}

}, WBT = Webtwic,
notif_text = "Some features which affect the functionality of webtwic are disabled in your browser. Please try refreshing the page or get a better browser. ";

jQuery(document).ready(function() {
	// Test for HTML5 support
	if(typeof Modernizr != "undefined" && !Modernizr.canvas) {
		Webtwic._showNotif("Oops. Your browser doesn't support HTML5. Please get a better browser  for a better experience.");
	} else {
		// Do nothing.
	}

	// Define Variables
	var $to_top = $("a.to-top"),
	is_toggle_active = $(".hamburger").hasClass("is_active"),
	height = 200;

	// Performance Fixes

	// Start browser detection

	browser.ie = browser.msie;

	if (browser.webkit) {
		$("body").addClass("webkit");
	}
	if(browser.chrome) {
		Webtwic._showBrowser("chrome");
	}
	if(browser.msedge) {
		Webtwic._showBrowser("msedge");
	}
	if(browser.firefox) {
		Webtwic._showBrowser("firefox");
	}
	if(browser.msie) {
		Webtwic._showBrowser("ie");
	}
	if(browser.safari) {
		Webtwic._showBrowser("safari");
	}
	if(browser.opera) {
		Webtwic._showBrowser("opera");
	}

	/*
		TODO: Rebuild Performance fixes for attributes
		See history of Performance fixes.
		Also, check StackOverflow.
	*/

	if (!Modernizr.flexbox || !Modernizr.inlinesvg || !Modernizr.svg || !Modernizr.svgclippaths || !Modernizr.fontface || !Modernizr.boxshadow || !Modernizr.borderradius || !Modernizr.csstransforms) {
		Webtwic._showNotif();
	} else {
		// Do nothing.
	}

	// Start Main Page

	$("nav li ul.drop-nav").hide().removeClass("dropNavFallback");

	if ( $(window).width() > 860 ) {
		$("nav li.dropdown").hover(function() {
			$("ul.drop-nav", this).stop().slideDown("fast");
		}, function() {
			$("ul.drop-nav", this).stop().slideUp("fast");
		});
	}

	$(".active-item").append(
		"<svg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><path d='M 16.682,19.674c 0.010-0.012, 0.014-0.028, 0.024-0.040l 6.982-7.714c 0.39-0.434, 0.39-1.138,0-1.572 c-0.004-0.004-0.008-0.006-0.012-0.008C 23.496,10.13, 23.244,10, 22.964,10L 8.998,10 c-0.286,0-0.54,0.138-0.722,0.352L 8.272,10.348 c-0.39,0.434-0.39,1.138,0,1.572l 6.998,7.754C 15.66,20.108, 16.292,20.108, 16.682,19.674z'></path></svg>"
	);

	$("a.hamburger").click(function(e) {
		$(this).toggleClass("is_active");

		e.preventDefault();
	});
	$(".mobile-header .mobile-nav").hide();

	$(window).scroll(function() {
		($(this).scrollTop() > height) ? $to_top.addClass("topVisible"): $to_top.removeClass("topVisible");
	});

	// Styles for homepage article-social

	$(".article .article-social a").hover(function() {
		$("span", this).eq(1).fadeIn(400);
	}, function() {
		$("span", this).eq(1).fadeOut(250);
	});

	// Functions for search-icon and ui-overlay-search

	$(".header-follow-search .search-wrap").on("click", function() {
		openUiOverlay();
	});

	$(".header-follow-search .close-icon").on("click", function() {
		closeUiOverlay();
	});

	$(".header-follow-search .close-icon").hover(
		function() {
			$(this).addClass("spin");
		},
		function() {
			$(this).removeClass("spin");
		});

	function openUiOverlay() {
		$(".ui-overlay-search").fadeIn(400).addClass("is_open");
	}

	function closeUiOverlay() {
		$(".ui-overlay-search").fadeOut(400).removeClass("is_open");
	}

	$(".ui-overlay-search .search-input input").focus(function() {
		$(".search-input").attr("data-focused", true);
		$(".search-input input").addClass("_is-focused");
		$("#__expand").addClass("visible");
	});

	$(".ui-overlay-search .search-input input").blur(function() {
		$(".search-input").attr("data-focused", false);
		$(".search-input input").removeClass("_is-focused");
		$("#__expand").removeClass("visible");
	});

	$(".post-meta .post-meta-inner .cta-btns a.is_inactive").on("click", function(e) {
		e.preventDefault();
	});

	$(document).keydown(function(e) {
    if (e.keyCode == 27) {
        closeUiOverlay();
    } else {
		 return;
	 }});

	 $(".mobile-nav").hide();

	// Functions for more-posts button click

	function addLoader() {
		$(".secondary-category-section .category-posts-column [data-clicked='false']").attr("data-clicked", "true").append("");
	}
	$(".secondary-category-section .category-posts-column [data-clicked='false']").on("click", function(e) {
		$(this).css({
			"background": "#50ABF1",
			"color": "#fff"
		});
		addLoader();
		e.preventDefault();
	});

	$to_top.on("click", function(e) {
		$("body,html").animate({
			scrollTop: 0
		}, 1000);

		e.preventDefault();
	});

});
<commit_msg>Create fallback condition if Modernizr is undefined<commit_after>/**
 * Author: Olaolu Olawuyi

 * Date Created: 20/08/2015

 * Last Modified: 14/02/2016

 * Twitter: @whizkydee, @webtwic

 * Github: https://github.com/whizkydee/whizkydee.github.io

*/

var Webtwic = Webtwic || {};

var browser = bowser;

var test_canvas = document.createElement("canvas");
var canvascheck=(test_canvas.getContext)? true : false;

Webtwic = {
	// Basic Information about Webtwic
	name: "Webtwic",
	description: "A community for coding and tech tweaks where beginners and experts can learn.",
	repo: "https://github.com/whizkydee/whizkydee.github.io",
	author: "Olaolu Olawuyi",
	version: 1.07,

	// Start main functions for the object

	// Function to add browser name and version to body class
	_showBrowser: function(b) {
		$("body").addClass(b + " " + b + parseInt(browser.version));
	},

	// Function to set attributes and values to elements
	_setAttr: function(elem, name, val) {
		$(elem, this).attr(name, val);
	},

	// Function to push down .site-content
	_adjustSiteContent: function() {
		if( $("body").hasClass("default-body") ) {
			$(".top-stripe").addClass("adjustedMargin");
			$("#header .logo").addClass("adjustedTop");
			$(".main-menu").addClass("adjustedMargin");
			$("#header").addClass("adjustSiteContent");
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".site-content").addClass("adjustSiteContent");
			$(".secondary-header").addClass("adjustedMargin");
		}
	},

	// Function to push up .site-content to default state
	_undoSiteAdjust: function() {
		if( $("body").hasClass("default-body") ) {
			$(".top-stripe").removeClass("adjustedMargin");
			$("#header .logo").removeClass("adjustedTop");
			$(".main-menu").removeClass("adjustedMargin");
			$("#header").removeClass("adjustSiteContent");
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".secondary-header").removeClass("adjustedMargin");
		}
	},

	// Function to show Notifications before header
	_showNotif: function(text) {
		text = (typeof text == "undefined") ? notif_text : text;
		Webtwic._adjustSiteContent();
		if( $("body").hasClass("default-body") ) {
			$(".top-stripe").before(
				"
"+text+"
"
			);
		} else if ( $("body").hasClass("secondary-body") ) {
			$(".secondary-header").before(
				"
"+text+"
"
			);
		} else {
			return;
		}
		$(".close-button").on("click", function() {
			Webtwic._undoReset();
		});
	},

	// Function to hide Notifications
	_hideNotif: function() {
		$("#notifBanner").removeClass("notif_vis");
	},

	_resetSite: function() {
		Webtwic._showNotif();
		Webtwic._adjustSiteContent();
	},

	_undoReset: function() {
		Webtwic._hideNotif();
		Webtwic._undoSiteAdjust();
	},

	// Function to launch modal

	_launchModal: function(w, h, r, p, c, e, b) {
		this.width = w;
	}

}, WBT = Webtwic,
notif_text = "Some features which affect the functionality of webtwic are disabled in your browser. Please try refreshing the page or get a better browser. ";

jQuery(document).ready(function() {
	// Test for HTML5 support
	if(window.Modernizr) {
		if(!Modernizr.canvas) {
			Webtwic._showNotif("Oops. Your browser doesn't support HTML5. Please get a better browser  for a better experience.");
		} else {
			// Do nothing.
		}
	} else if (!window.Modernizr) {
		if(canvascheck == false) {
			alert("hello");
		} else {
			// Do nothing.
		}
	} else {
		// Do nothing.
	}

	// Define Variables
	var $to_top = $("a.to-top"),
	is_toggle_active = $(".hamburger").hasClass("is_active"),
	height = 200;

	// Performance Fixes

	// Start browser detection

	browser.ie = browser.msie;

	if (browser.webkit) {
		$("body").addClass("webkit");
	}
	if(browser.chrome) {
		Webtwic._showBrowser("chrome");
	}
	if(browser.msedge) {
		Webtwic._showBrowser("msedge");
	}
	if(browser.firefox) {
		Webtwic._showBrowser("firefox");
	}
	if(browser.msie) {
		Webtwic._showBrowser("ie");
	}
	if(browser.safari) {
		Webtwic._showBrowser("safari");
	}
	if(browser.opera) {
		Webtwic._showBrowser("opera");
	}

	/*
		TODO: Rebuild Performance fixes for attributes
		See history of Performance fixes.
		Also, check StackOverflow.
	*/

	if (window.Modernizr) {
		if (!Modernizr.flexbox || !Modernizr.inlinesvg || !Modernizr.svg || !Modernizr.svgclippaths || !Modernizr.fontface || !Modernizr.boxshadow || !Modernizr.borderradius || !Modernizr.csstransforms) {
			Webtwic._showNotif();
		} else {
			// Do nothing.
		}
	} else {
		// Do nothing.
	}

	// Start Main Page

	$("nav li ul.drop-nav").hide().removeClass("dropNavFallback");

	if ( $(window).width() > 860 ) {
		$("nav li.dropdown").hover(function() {
			$("ul.drop-nav", this).stop().slideDown("fast");
		}, function() {
			$("ul.drop-nav", this).stop().slideUp("fast");
		});
	}

	$(".active-item").append(
		"<svg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><path d='M 16.682,19.674c 0.010-0.012, 0.014-0.028, 0.024-0.040l 6.982-7.714c 0.39-0.434, 0.39-1.138,0-1.572 c-0.004-0.004-0.008-0.006-0.012-0.008C 23.496,10.13, 23.244,10, 22.964,10L 8.998,10 c-0.286,0-0.54,0.138-0.722,0.352L 8.272,10.348 c-0.39,0.434-0.39,1.138,0,1.572l 6.998,7.754C 15.66,20.108, 16.292,20.108, 16.682,19.674z'></path></svg>"
	);

	$("a.hamburger").click(function(e) {
		$(this).toggleClass("is_active");

		e.preventDefault();
	});
	$(".mobile-header .mobile-nav").hide();

	$(window).scroll(function() {
		($(this).scrollTop() > height) ? $to_top.addClass("topVisible"): $to_top.removeClass("topVisible");
	});

	// Styles for homepage article-social

	$(".article .article-social a").hover(function() {
		$("span", this).eq(1).fadeIn(400);
	}, function() {
		$("span", this).eq(1).fadeOut(250);
	});

	// Functions for search-icon and ui-overlay-search

	$(".header-follow-search .search-wrap").on("click", function() {
		openUiOverlay();
	});

	$(".header-follow-search .close-icon").on("click", function() {
		closeUiOverlay();
	});

	$(".header-follow-search .close-icon").hover(
		function() {
			$(this).addClass("spin");
		},
		function() {
			$(this).removeClass("spin");
		});

	function openUiOverlay() {
		$(".ui-overlay-search").fadeIn(400).addClass("is_open");
	}

	function closeUiOverlay() {
		$(".ui-overlay-search").fadeOut(400).removeClass("is_open");
	}

	$(".ui-overlay-search .search-input input").focus(function() {
		$(".search-input").attr("data-focused", true);
		$(".search-input input").addClass("_is-focused");
		$("#__expand").addClass("visible");
	});

	$(".ui-overlay-search .search-input input").blur(function() {
		$(".search-input").attr("data-focused", false);
		$(".search-input input").removeClass("_is-focused");
		$("#__expand").removeClass("visible");
	});

	$(".post-meta .post-meta-inner .cta-btns a.is_inactive").on("click", function(e) {
		e.preventDefault();
	});

	$(document).keydown(function(e) {
    if (e.keyCode == 27) {
        closeUiOverlay();
    } else {
		 return;
	 }});

	 $(".mobile-nav").hide();

	// Functions for more-posts button click

	function addLoader() {
		$(".secondary-category-section .category-posts-column [data-clicked='false']").attr("data-clicked", "true").append("");
	}
	$(".secondary-category-section .category-posts-column [data-clicked='false']").on("click", function(e) {
		$(this).css({
			"background": "#50ABF1",
			"color": "#fff"
		});
		addLoader();
		e.preventDefault();
	});

	$to_top.on("click", function(e) {
		$("body,html").animate({
			scrollTop: 0
		}, 1000);

		e.preventDefault();
	});

});
<|endoftext|>


<commit_before>var slice = [].slice

function Vestibule () {
    this._waiting = []
    this.open = null
}

Vestibule.prototype.enter = function (callback) {
    if (this.open == null) {
        var cookie = {}
        this._waiting.push({
            cookie: cookie,
            callback: callback
        })
        return cookie
    }
    callback.apply(null, this.open)
    return null
}

Vestibule.prototype.leave = function (cookie) {
    for (var i = 0, I = this._waiting.length; i < I; i++) {
        if (this._waiting[i].cookie === cookie) {
            this._waiting.splice(i, 1)
            break
        }
    }
}

Vestibule.prototype.notify = function () {
    var vargs = slice.call(arguments)
    this._waiting.splice(0, this._waiting.length).forEach(function (waiting) {
        waiting.callback.apply(null, vargs)
    })
}

module.exports = Vestibule
<commit_msg>Add waiting.<commit_after>var slice = [].slice

function Vestibule () {
    this._waiting = []
    this.waiting = 0
    this.open = null
}

Vestibule.prototype.enter = function (callback) {
    if (this.open == null) {
        var cookie = {}
        this.waiting++
        this._waiting.push({
            cookie: cookie,
            callback: callback
        })
        return cookie
    }
    callback.apply(null, this.open)
    return null
}

Vestibule.prototype.leave = function (cookie) {
    for (var i = 0, I = this._waiting.length; i < I; i++) {
        if (this._waiting[i].cookie === cookie) {
            this._waiting.splice(i, 1)
            this.waiting--
            break
        }
    }
}

Vestibule.prototype.notify = function () {
    var vargs = slice.call(arguments)
    this.waiting = 0
    this._waiting.splice(0, this._waiting.length).forEach(function (waiting) {
        waiting.callback.apply(null, vargs)
    })
}

module.exports = Vestibule
<|endoftext|>


<commit_before>// @flow weak

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import RaisedButton from 'material-ui/RaisedButton';
import withWidth, { LARGE } from 'material-ui/utils/withWidth';
import spacing from 'material-ui/styles/spacing';
import typography from 'material-ui/styles/typography';
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import FullWidthSection from '../components/FullWidthSection';

class HomePage extends Component {
  static propTypes = {
    width: PropTypes.number.isRequired,
  };

  static contextTypes = {
    router: PropTypes.object.isRequired,
  };

  homePageHero() {
    const styles = {
      root: {
        overflow: 'hidden',
      },
      tagline: {
        margin: '16px auto 0 auto',
        textAlign: 'center',
        maxWidth: 575,
      },
      label: {
        color: lightBaseTheme.palette.primary1Color,
      },
      h1: {
        fontWeight: typography.fontWeightLight,
      },
      h2: {
        fontSize: 20,
        lineHeight: '28px',
        paddingTop: 19,
        marginBottom: 13,
        letterSpacing: 0,
      },
      nowrap: {
        whiteSpace: 'nowrap',
      },
      taglineWhenLarge: {
        marginTop: 32,
      },
      h1WhenLarge: {
        fontSize: 56,
      },
      h2WhenLarge: {
        fontSize: 24,
        lineHeight: '32px',
        paddingTop: 16,
        marginBottom: 12,
      },
    };

    styles.h2 = Object.assign({}, styles.h1, styles.h2);

    if (this.props.width === LARGE) {
    //   styles.tagline = Object.assign({}, styles.tagline, styles.taglineWhenLarge);
    //   styles.h1 = Object.assign({}, styles.h1, styles.h1WhenLarge);
    //   styles.h2 = Object.assign({}, styles.h2, styles.h2WhenLarge);
    }

    return (
      <FullWidthSection style={styles.root}>

React-Move

      </FullWidthSection>
    );
  }

  homeContribute() {
    const styles = {
      root: {
        textAlign: 'center',
      },
      h3: {
        margin: 0,
        padding: 0,
        fontWeight: typography.fontWeightLight,
        fontSize: 22,
      },
      button: {
        marginTop: 32,
      },
    };

    return (
      <FullWidthSection useContent style={styles.root}>
        <RaisedButton
          label="GitHub"
          primary
          href="https://github.com/react-tools/react-move"
          style={styles.button}
        />
        <RaisedButton
          label="Examples"
          onTouchTap={this.handleTouchTapDemo}
          style={styles.button}
        />
      </FullWidthSection>
    );
  }

  handleTouchTapDemo = () => {
    this.context.router.push('/redux-examples/states-by-age');
  };

  render() {
    const style = {
      paddingTop: spacing.desktopKeylineIncrement,
    };

    return (

        {this.homePageHero()}
        {this.homeContribute()}

    );
  }
}

export default withWidth()(HomePage);
<commit_msg>fix broken link<commit_after>// @flow weak

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import RaisedButton from 'material-ui/RaisedButton';
import withWidth, { LARGE } from 'material-ui/utils/withWidth';
import spacing from 'material-ui/styles/spacing';
import typography from 'material-ui/styles/typography';
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import FullWidthSection from '../components/FullWidthSection';

class HomePage extends Component {
  static propTypes = {
    width: PropTypes.number.isRequired,
  };

  static contextTypes = {
    router: PropTypes.object.isRequired,
  };

  homePageHero() {
    const styles = {
      root: {
        overflow: 'hidden',
      },
      tagline: {
        margin: '16px auto 0 auto',
        textAlign: 'center',
        maxWidth: 575,
      },
      label: {
        color: lightBaseTheme.palette.primary1Color,
      },
      h1: {
        fontWeight: typography.fontWeightLight,
      },
      h2: {
        fontSize: 20,
        lineHeight: '28px',
        paddingTop: 19,
        marginBottom: 13,
        letterSpacing: 0,
      },
      nowrap: {
        whiteSpace: 'nowrap',
      },
      taglineWhenLarge: {
        marginTop: 32,
      },
      h1WhenLarge: {
        fontSize: 56,
      },
      h2WhenLarge: {
        fontSize: 24,
        lineHeight: '32px',
        paddingTop: 16,
        marginBottom: 12,
      },
    };

    styles.h2 = Object.assign({}, styles.h1, styles.h2);

    if (this.props.width === LARGE) {
    //   styles.tagline = Object.assign({}, styles.tagline, styles.taglineWhenLarge);
    //   styles.h1 = Object.assign({}, styles.h1, styles.h1WhenLarge);
    //   styles.h2 = Object.assign({}, styles.h2, styles.h2WhenLarge);
    }

    return (
      <FullWidthSection style={styles.root}>

React-Move

      </FullWidthSection>
    );
  }

  homeContribute() {
    const styles = {
      root: {
        textAlign: 'center',
      },
      h3: {
        margin: 0,
        padding: 0,
        fontWeight: typography.fontWeightLight,
        fontSize: 22,
      },
      button: {
        marginTop: 32,
      },
    };

    return (
      <FullWidthSection useContent style={styles.root}>
        <RaisedButton
          label="GitHub"
          primary
          href="https://github.com/react-tools/react-move"
          style={styles.button}
        />
        <RaisedButton
          label="Examples"
          onTouchTap={this.handleTouchTapDemo}
          style={styles.button}
        />
      </FullWidthSection>
    );
  }

  handleTouchTapDemo = () => {
    this.context.router.push('/documentation/node-group');
  };

  render() {
    const style = {
      paddingTop: spacing.desktopKeylineIncrement,
    };

    return (

        {this.homePageHero()}
        {this.homeContribute()}

    );
  }
}

export default withWidth()(HomePage);
<|endoftext|>


<commit_before>(function(window, undefined) {
  "use strict";

  /**
   * Naming policy:
   * **************
   *  - Upper case: Parameters recognized by Guignol
   *  - No underscore (prefix): var in local scope or parameter
   *  - One underscore (prefix): Related to the instance
   *  - Two underscores (prefix): Related to every instances
   */
  var __easings = {},
      __renderers = {},
      __identity = function(v) { return v; },
      __properties = 'START END FROM TO EASING ANIMATION'.split(' ');

  /**
   * Recognized parameters:
   * **********************
   *  - scenario: (?object)
   *  - times: (?object)
   *  - renderers: (?object)
   *  - animations: (?object)
   *  - start: (?number)
   *  - end: (?number)
   */
  window.Guignol = function(options) {
    var _o = options || {},
        _times = _o.times || _o.t || {},
        _renderers = _o.renderers || _o.r || {},
        _animations = _o.animations || _o.a || {},
        _scenario = _o.scenario || _o.s || {},
        _start = _getTime(_o.start),
        _end = _getTime(_o.end),
        _originTime,
        _time,
        _isPlaying;

    function _getTime(t) {
      return typeof t === 'string' ?
        _times[t] || null :
        t;
    }

    function _getAnim(o) {
      var res = {};

      if (typeof o === 'string')
        return _animations[o] || o;
      else if (typeof o === 'object') {
        if (o.ANIMATION && _animations[o.ANIMATION]) {
          var k,
              res = {},
              a = _animations[o.ANIMATION];
          for (k in o)
            res[k] = o[k];
          for (k in a)
            res[k] = a[k];

          delete res.ANIMATION;
          return res;
        }
      }

      return o;
    }

    function _render(t) {
      var i, s, r; // index, shape, renderer

      for (i in _scenario) {
        s = _scenario[i];

        // Check local, then global:
        r = _renderers[s.RENDERER] || __renderers[s.RENDERER];

        if (
          r && (s.END === undefined || _getTime(s.END) > t) &&
          (s.START === undefined || _getTime(s.START) < t)
        ) {
          r(__expand(s, t, _getTime, _getAnim));
        }
      }

      if (_isPlaying && t < _end)
        __requestAnimFrame(_convertAndRender);
      else if (t > _end)
        _isPlaying = false
    }

    function _convertAndRender(t) {
      _time = t - (_originTime || 0) + (_start || 0)
      _render(_time);
    }

    this.goTo = function(t) {
      _time = t;
      _render(t);
      return this;
    };
    this.play = function() {
      _originTime = new Date();
      _isPlaying = true;
      _convertAndRender(_originTime);
      return this;
    };
    this.stop = function() {
      _isPlaying = false;
      return this;
    };
    this.time = function() {
      return _time;
    };
  };
  var G = window.Guignol;

  /**
   * Find window.requestAnimationFrame fallback:
   */
  var __requestAnimFrame = (function() {
    return  window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function(callback) {
              window.setTimeout(callback, 1000 / 60);
            };
  })();

  function __interpolate(from, to, progress) {
    if (typeof from === 'object') {
      var res = {};
      for (var k in from)
        res[k] = __interpolate(from[k], to[k], progress);
      return res;
    } else if (typeof from === 'number')
      return from + (to - from) * progress;
    else
      return from;
  }

  /**
   * Recognized parameters:
   * **********************
   *  - START: The start time of the animation (number|string)
   *  - END: The end time of the animation (number|string)
   *  - FROM: The initial value of the animation (number)
   *  - TO: The final value of the animation (number)
   *  - EASING: The easing of the animation (?function|string)
   *  - ANIMATION: The parent animation (?string)
   */
  function __expand(v, t, getTime, getAnim) {
    getTime = getTime || __identity;
    getAnim = getAnim || __identity;

    // If null or undefined, return the same value:
    if (v == null)
      return v;

    // If an array, find the good timeStep:
    else if (Object.prototype.toString.call(v) === '[object Array]') {
      var i, oMin, oMax, s, e,
          min, max;
      for (i in v) {
        var o = getAnim(v[i]),
            s = getTime(o.START),
            e = getTime(o.END);

        // If a timestep matches, just interpolate
        if (s <= t && e >= t) {
          var progress = (t - s) / (e - s);
          progress = Math.min(1, Math.max(0, progress));

          if (o.EASING) {
            if (__easings[o.EASING])
              progress = __easings[o.EASING](progress);
            else if (typeof o.EASING === 'function')
              progress = o.EASING(progress);
          }

          return __interpolate(o.FROM, o.TO, progress);
        }

        // If not, find the good persistent timestep
        else {
          if (s > t && (min === undefined || s < min)) {
            min = s;
            oMin = o;
          } else if (e < t && (max === undefined || e > max)) {
            max = e;
            oMax = o;
          }
        }
      }

      if (oMax)
        return oMax.TO;
      else if (oMin)
        return oMin.FROM;

    // If an object, try to interpolate:
    } else if (typeof v === 'object' || typeof v === 'string') {
      var o = getAnim(v);

      // If it is still a string, then there is nothing to expand:
      if (typeof o === 'string')
        return v;

      var s = getTime(o.START),
          e = getTime(o.END)

      // Let's first check if the object is a valid animation:
      if (s !== undefined && e !== undefined) {
        var progress = (t - s) / (e - s);
        progress = Math.min(1, Math.max(0, progress));

        if (o.EASING) {
          if (__easings[o.EASING])
            progress = __easings[o.EASING](progress);
          else if (typeof o.EASING === 'function')
            progress = o.EASING(progress);
        }

        return __interpolate(o.FROM, o.TO, progress);

      // If not, let's expand sub-objects:
      } else {
        var res = {};

        for (var k in o) {
          if (typeof o[k] === 'object')
            res[k] = __expand(o[k], t, getTime, getAnim);
          else if (typeof o[k] === 'string') {
            var o2 = getAnim(o[k]);
            if (typeof o2 === 'object')
              res[k] = __expand(o[k], t, getTime, getAnim);
            else
              res[k] = o[k];
          } else
            res[k] = o[k];
        }

        return res;
      }

    // It not an object or an array, nothing to expand:
    } else
      return v;
  }

  G.expand = __expand;
  G.interpolate = __interpolate;

  G.requestAnimationFrame = __requestAnimFrame;
  G.easings = function(a1, a2) {
    if (arguments.length === 1) {
      if (typeof a1 === 'object') {
        for (var k in a1)
          G.easings(k, a1[k]);
      } else
        return __easings[a1];
    } else if (arguments.length === 2) {
      if (typeof a2 !== 'function')
        throw '[guignol] Easings must be functions.';
      __easings[a1] = a2;
    }
    return this;
  }
  G.renderers = function(a1, a2) {
    if (arguments.length === 1) {
      if (typeof a1 === 'object') {
        for (var k in a1)
          G.renderers(k, a1[k]);
      } else
        return __renderers[a1];
    } else if (arguments.length === 2) {
      if (typeof a2 !== 'function')
        throw '[guignol] Renderers must be functions.';
      __renderers[a1] = a2;
    }
    return this;
  }
})(window);
<commit_msg>minor changes<commit_after>;(function(window, undefined) {
  "use strict";

  /**
   * Naming policy:
   * **************
   *  - UPPERCASE: Parameters recognized by Guignol
   *  - camlCase: var in local scope or parameter
   *  - _camlCaseUnderscore: Related to the instance
   *  - __camlCaseUnderscores: Related to every instances
   */
  var __easings = {},
      __renderers = {},
      __identity = function(v) { return v; },
      __properties = 'START END FROM TO EASING ANIMATION'.split(' ');

  /**
   * Recognized parameters:
   * **********************
   *  - scenario: (?object)
   *  - times: (?object)
   *  - renderers: (?object)
   *  - animations: (?object)
   *  - start: (?number)
   *  - end: (?number)
   */
  window.Guignol = function(options) {
    var _o = options || {},
        _times = _o.times || _o.t || {},
        _renderers = _o.renderers || _o.r || {},
        _animations = _o.animations || _o.a || {},
        _scenario = _o.scenario || _o.s || {},
        _start = _getTime(_o.start),
        _end = _getTime(_o.end),
        _originTime,
        _time,
        _isPlaying;

    function _getTime(t) {
      return typeof t === 'string' ?
        _times[t] || null :
        t;
    }

    function _getAnim(o) {
      var res = {};

      if (typeof o === 'string')
        return _animations[o] || o;
      else if (typeof o === 'object') {
        if (o.ANIMATION && _animations[o.ANIMATION]) {
          var k,
              res = {},
              a = _animations[o.ANIMATION];
          for (k in o)
            res[k] = o[k];
          for (k in a)
            res[k] = a[k];

          delete res.ANIMATION;
          return res;
        }
      }

      return o;
    }

    function _render(t) {
      var i, s, r; // index, shape, renderer

      for (i in _scenario) {
        s = _scenario[i];

        // Check local, then global:
        r = _renderers[s.RENDERER] || __renderers[s.RENDERER];

        if (
          r && (s.END === undefined || _getTime(s.END) > t) &&
          (s.START === undefined || _getTime(s.START) < t)
        ) {
          r(__expand(s, t, _getTime, _getAnim));
        }
      }

      if (_isPlaying && t < _end)
        __requestAnimFrame(_convertAndRender);
      else if (t > _end)
        _isPlaying = false
    }

    function _convertAndRender(t) {
      _time = t - (_originTime || 0) + (_start || 0)
      _render(_time);
    }

    this.goTo = function(t) {
      _time = t;
      _render(t);
      return this;
    };
    this.play = function() {
      _originTime = new Date();
      _isPlaying = true;
      _convertAndRender(_originTime);
      return this;
    };
    this.stop = function() {
      _isPlaying = false;
      return this;
    };
    this.time = function() {
      return _time;
    };
  };
  var G = window.Guignol;

  /**
   * Find window.requestAnimationFrame fallback:
   */
  var __requestAnimFrame = (function() {
    return  window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function(callback) {
              window.setTimeout(callback, 1000 / 60);
            };
  })();

  function __interpolate(from, to, progress) {
    if (typeof from === 'object') {
      var res = {};
      for (var k in from)
        res[k] = __interpolate(from[k], to[k], progress);
      return res;
    } else if (typeof from === 'number')
      return from + (to - from) * progress;
    else
      return from;
  }

  /**
   * Recognized parameters:
   * **********************
   *  - START: The start time of the animation (number|string)
   *  - END: The end time of the animation (number|string)
   *  - FROM: The initial value of the animation (number)
   *  - TO: The final value of the animation (number)
   *  - EASING: The easing of the animation (?function|string)
   *  - ANIMATION: The parent animation (?string)
   */
  function __expand(v, t, getTime, getAnim) {
    getTime = getTime || __identity;
    getAnim = getAnim || __identity;

    // If null or undefined, return the same value:
    if (v == null)
      return v;

    // If an array, find the good timeStep:
    else if (Object.prototype.toString.call(v) === '[object Array]') {
      var i, oMin, oMax, s, e,
          min, max;
      for (i in v) {
        var o = getAnim(v[i]),
            s = getTime(o.START),
            e = getTime(o.END);

        // If a timestep matches, just interpolate
        if (s <= t && e >= t) {
          var progress = (t - s) / (e - s);
          progress = Math.min(1, Math.max(0, progress));

          if (o.EASING) {
            if (__easings[o.EASING])
              progress = __easings[o.EASING](progress);
            else if (typeof o.EASING === 'function')
              progress = o.EASING(progress);
          }

          return __interpolate(o.FROM, o.TO, progress);
        }

        // If not, find the good persistent timestep
        else {
          if (s > t && (min === undefined || s < min)) {
            min = s;
            oMin = o;
          } else if (e < t && (max === undefined || e > max)) {
            max = e;
            oMax = o;
          }
        }
      }

      if (oMax)
        return oMax.TO;
      else if (oMin)
        return oMin.FROM;

    // If an object, try to interpolate:
    } else if (typeof v === 'object' || typeof v === 'string') {
      var o = getAnim(v);

      // If it is still a string, then there is nothing to expand:
      if (typeof o === 'string')
        return v;

      var s = getTime(o.START),
          e = getTime(o.END)

      // Let's first check if the object is a valid animation:
      if (s !== undefined && e !== undefined) {
        var progress = (t - s) / (e - s);
        progress = Math.min(1, Math.max(0, progress));

        if (o.EASING) {
          if (__easings[o.EASING])
            progress = __easings[o.EASING](progress);
          else if (typeof o.EASING === 'function')
            progress = o.EASING(progress);
        }

        return __interpolate(o.FROM, o.TO, progress);

      // If not, let's expand sub-objects:
      } else {
        var res = {};

        for (var k in o) {
          if (typeof o[k] === 'object')
            res[k] = __expand(o[k], t, getTime, getAnim);
          else if (typeof o[k] === 'string') {
            var o2 = getAnim(o[k]);
            if (typeof o2 === 'object')
              res[k] = __expand(o[k], t, getTime, getAnim);
            else
              res[k] = o[k];
          } else
            res[k] = o[k];
        }

        return res;
      }

    // It not an object or an array, nothing to expand:
    } else
      return v;
  }

  G.expand = __expand;
  G.interpolate = __interpolate;

  G.requestAnimationFrame = __requestAnimFrame;
  G.easings = function(a1, a2) {
    if (arguments.length === 1) {
      if (typeof a1 === 'object') {
        for (var k in a1)
          G.easings(k, a1[k]);
      } else
        return __easings[a1];
    } else if (arguments.length === 2) {
      if (typeof a2 !== 'function')
        throw '[guignol] Easings must be functions.';
      __easings[a1] = a2;
    }
    return this;
  }
  G.renderers = function(a1, a2) {
    if (arguments.length === 1) {
      if (typeof a1 === 'object') {
        for (var k in a1)
          G.renderers(k, a1[k]);
      } else
        return __renderers[a1];
    } else if (arguments.length === 2) {
      if (typeof a2 !== 'function')
        throw '[guignol] Renderers must be functions.';
      __renderers[a1] = a2;
    }
    return this;
  }
})(window);
<|endoftext|>


<commit_before>const TOOLTIP_ID = '_ext_tooltip_34F75D';

let prefs = null;
let ignoreMouseEvent = false;

/* global defaultPrefs */
browser.storage.local.get('prefs', (rawItem) => {
  // see https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/StorageArea/get
  const item = Array.isArray(rawItem) ? rawItem[0] : rawItem;
  prefs = item.prefs ? item.prefs : defaultPrefs;
});

browser.storage.onChanged.addListener((changes, area) => {
  prefs = changes.prefs.newValue;
});

let popup = document.createElement('div');
popup.style.cssText = 'position: absolute; left: 0; top: 0; z-index: 999999; background-color: white';

document.addEventListener('selectionchange', () => {
  ignoreMouseEvent = false;
});

document.addEventListener('mouseup', (e) => {
  if (!isTooltip(e.target)) {
    hideTooltip();
  }
  if (prefs === null || prefs.wordSelectMode != 0 || ignoreMouseEvent) {
    return;
  }
  let sel = document.getSelection();
  let text = sel.toString().trim();
  if (text.length < 1) {
    return;
  }
  let focusNode = sel.focusNode;
  if (focusNode.nodeName.toLowerCase() == 'textarea'
    || focusNode.nodeName.toLowerCase() == 'input') {
    return;
  }
  ignoreMouseEvent = true;
  showTooltipFromSelection(sel, text);
});

document.addEventListener('click', (e) => {
  if (prefs === null || prefs.wordSelectMode != 1) {
    return;
  }
  if (e.ctrlKey != prefs.useCtrl
    || e.altKey != prefs.useAlt
    || e.metaKey != prefs.useMeta) {
    return;
  }
  let oldSettings = enableTextSelection();
  try {
    let sel = document.getSelection();
    sel.removeAllRanges();
    let range = createRangeFromPoint(e.clientX, e.clientY);
    if (range === null) {
      return;
    }
    sel.addRange(range);
    sel.modify("move", "backward", "word");
    sel.modify("extend", "forward", "word");
    let text = sel.toString().trim();
    if (text.length < 1) {
      return;
    }
    showTooltipFromSelection(sel, text);
    sel.removeAllRanges();
  } finally {
    restoreTextSelection(oldSettings);
  }
});

function enableTextSelection() {
  let oldSettings = {};
  if (document.body.style.MozUserSelect !== null) {
    oldSettings['MozUserSelect'] = document.body.style.MozUserSelect;
    document.body.style.MozUserSelect = 'text';
  }
  document.addEventListener('selectstart', function (e) {
    e.stopPropagation();
    e.stopImmediatePropagation();
    return true;
  }, {
    capture: true,
    once: true
  });
  return oldSettings;
}

function restoreTextSelection(oldSettings) {
  if (oldSettings['MozUserSelect'] !== undefined) {
    document.body.style.MozUserSelect = oldSettings['MozUserSelect'];
  }
}

function createRangeFromPoint(x, y) {
  let range = document.createRange();
  let textNode;
  let offset;

  if (document.caretPositionFromPoint) {
    let caretPos = document.caretPositionFromPoint(x, y);
    textNode = caretPos.offsetNode;
    offset = caretPos.offset;
    if (caretPos == null) {
      return null;
    }
  } else if (document.caretRangeFromPoint) {
    let caretRange = document.caretRangeFromPoint(x, y);
    if (caretRange == null) {
      return null;
    }
    textNode = caretRange.startContainer;
    offset = caretRange.startOffset;
  } else {
    return null;
  }
  range.setStart(textNode, offset);
  range.setEnd(textNode, offset);
  return range;
}

function showTooltipFromSelection(sel, text) {
  hideTooltip();
  let range = sel.getRangeAt(0);
  let bounds = range.getBoundingClientRect();
  showTooltip(text, {
    left: Math.trunc(window.pageXOffset + bounds.left),
    top: Math.trunc(window.pageYOffset + bounds.bottom)
  });
}

function showTooltip(text, pos) {
  let ret = getWordMeaning(text);
  ret.then((result) => {
    let tooltip = document.createElement('div');
    tooltip.id = TOOLTIP_ID;
    tooltip.innerHTML = result;
    tooltip.style.setProperty('position', `absolute`, 'important');
    tooltip.style.setProperty('top', `${pos.top}px`, 'important');
    tooltip.style.setProperty('left', `${pos.left}px`, 'important');
    tooltip.style.setProperty('display', `block`, 'important');
    tooltip.style.setProperty('width', `fit-content`, 'important');
    tooltip.style.setProperty('width', `-moz-fit-content`, 'important');
    tooltip.style.setProperty('width', `-webkit-fit-content`, 'important');
    tooltip.style.setProperty('height', `auto`, 'important');
    tooltip.style.setProperty('z-index', `${Number.MAX_SAFE_INTEGER}`, 'important');
    tooltip.style.setProperty('background-color', `white`, 'important');
    tooltip.style.setProperty('color', `black`, 'important');
    tooltip.style.setProperty('font', `normal 12px sans-serif`, 'important');
    tooltip.style.setProperty('border', `1px solid black`, 'important');
    tooltip.style.setProperty('margin', `0`, 'important');
    tooltip.style.setProperty('padding', `0`, 'important');
    document.body.appendChild(tooltip);
  }).catch(() => {
    // do nothing
  });
}

function hideTooltip() {
  let tooltip = document.getElementById(TOOLTIP_ID);
  if (tooltip != null) {
    document.body.removeChild(tooltip);
  }
}

function isTooltip(elem) {
  let tooltip = document.getElementById(TOOLTIP_ID);
  if (tooltip == null) {
    return false;
  }
  return (tooltip == elem || tooltip.contains(elem));
}

function getWordMeaning(word) {
  let dictUrl = `http://m.endic.naver.com/search.nhn?sLn=en&query=${encodeURIComponent(word)}&searchOption=entryIdiom&forceRedirect=`;
  let dictPageUrl = `http://endic.naver.com/search.nhn?sLn=en&query=${encodeURIComponent(word)}`;
  return fetch(dictUrl).then((response) => response.text())
      .then((text) => (new DOMParser()).parseFromString(text, 'text/html'))
      .then((doc) => {
        let cards = doc.body.querySelectorAll('div.section_card div.entry_search_word');
        if (cards.length < 1) {
          throw Error('No Result');
        }
        let result = '';
        let i = 0;
        for (let card of cards) {
          let title = card.querySelector('div.h_word>strong');
          let descs = card.querySelectorAll('ul.desc_lst p.desc');
          result += `<dl style="margin: 6px"><dt>${title.innerHTML}</dt><dd style="margin-left: 1em">`;
          if (descs.length > 1) {
            result += '
';
            for (let desc of descs) {
              result += `<li>${desc.textContent}</li>`;
            }
            result += '
'
          } else if (descs.length == 1) {
            result += descs[0].textContent;
          }
          result += '

';
          i++;
          if (i >=  5) {
            break;
          }
        }
        result += `<p style="margin: 6px; text-align: right"><a href="${dictPageUrl}" target="_blank" rel="noopener noreferrer">네이버 사전 열기</a></p>`
        return result;
      });
}
<commit_msg>발음기호가 표기되도록 변경<commit_after>const TOOLTIP_ID = '_ext_tooltip_34F75D';

let prefs = null;
let ignoreMouseEvent = false;

/* global defaultPrefs */
browser.storage.local.get('prefs', (rawItem) => {
  // see https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/StorageArea/get
  const item = Array.isArray(rawItem) ? rawItem[0] : rawItem;
  prefs = item.prefs ? item.prefs : defaultPrefs;
});

browser.storage.onChanged.addListener((changes, area) => {
  prefs = changes.prefs.newValue;
});

let popup = document.createElement('div');
popup.style.cssText = 'position: absolute; left: 0; top: 0; z-index: 999999; background-color: white';

document.addEventListener('selectionchange', () => {
  ignoreMouseEvent = false;
});

document.addEventListener('mouseup', (e) => {
  if (!isTooltip(e.target)) {
    hideTooltip();
  }
  if (prefs === null || prefs.wordSelectMode != 0 || ignoreMouseEvent) {
    return;
  }
  let sel = document.getSelection();
  let text = sel.toString().trim();
  if (text.length < 1) {
    return;
  }
  let focusNode = sel.focusNode;
  if (focusNode.nodeName.toLowerCase() == 'textarea'
    || focusNode.nodeName.toLowerCase() == 'input') {
    return;
  }
  ignoreMouseEvent = true;
  showTooltipFromSelection(sel, text);
});

document.addEventListener('click', (e) => {
  if (prefs === null || prefs.wordSelectMode != 1) {
    return;
  }
  if (e.ctrlKey != prefs.useCtrl
    || e.altKey != prefs.useAlt
    || e.metaKey != prefs.useMeta) {
    return;
  }
  let oldSettings = enableTextSelection();
  try {
    let sel = document.getSelection();
    sel.removeAllRanges();
    let range = createRangeFromPoint(e.clientX, e.clientY);
    if (range === null) {
      return;
    }
    sel.addRange(range);
    sel.modify("move", "backward", "word");
    sel.modify("extend", "forward", "word");
    let text = sel.toString().trim();
    if (text.length < 1) {
      return;
    }
    showTooltipFromSelection(sel, text);
    sel.removeAllRanges();
  } finally {
    restoreTextSelection(oldSettings);
  }
});

function enableTextSelection() {
  let oldSettings = {};
  if (document.body.style.MozUserSelect !== null) {
    oldSettings['MozUserSelect'] = document.body.style.MozUserSelect;
    document.body.style.MozUserSelect = 'text';
  }
  document.addEventListener('selectstart', function (e) {
    e.stopPropagation();
    e.stopImmediatePropagation();
    return true;
  }, {
    capture: true,
    once: true
  });
  return oldSettings;
}

function restoreTextSelection(oldSettings) {
  if (oldSettings['MozUserSelect'] !== undefined) {
    document.body.style.MozUserSelect = oldSettings['MozUserSelect'];
  }
}

function createRangeFromPoint(x, y) {
  let range = document.createRange();
  let textNode;
  let offset;

  if (document.caretPositionFromPoint) {
    let caretPos = document.caretPositionFromPoint(x, y);
    textNode = caretPos.offsetNode;
    offset = caretPos.offset;
    if (caretPos == null) {
      return null;
    }
  } else if (document.caretRangeFromPoint) {
    let caretRange = document.caretRangeFromPoint(x, y);
    if (caretRange == null) {
      return null;
    }
    textNode = caretRange.startContainer;
    offset = caretRange.startOffset;
  } else {
    return null;
  }
  range.setStart(textNode, offset);
  range.setEnd(textNode, offset);
  return range;
}

function showTooltipFromSelection(sel, text) {
  hideTooltip();
  let range = sel.getRangeAt(0);
  let bounds = range.getBoundingClientRect();
  showTooltip(text, {
    left: Math.trunc(window.pageXOffset + bounds.left),
    top: Math.trunc(window.pageYOffset + bounds.bottom)
  });
}

function showTooltip(text, pos) {
  let ret = getWordMeaning(text);
  ret.then((result) => {
    let tooltip = document.createElement('div');
    tooltip.id = TOOLTIP_ID;
    tooltip.innerHTML = result;
    tooltip.style.setProperty('position', `absolute`, 'important');
    tooltip.style.setProperty('top', `${pos.top}px`, 'important');
    tooltip.style.setProperty('left', `${pos.left}px`, 'important');
    tooltip.style.setProperty('display', `block`, 'important');
    tooltip.style.setProperty('width', `fit-content`, 'important');
    tooltip.style.setProperty('width', `-moz-fit-content`, 'important');
    tooltip.style.setProperty('width', `-webkit-fit-content`, 'important');
    tooltip.style.setProperty('height', `auto`, 'important');
    tooltip.style.setProperty('z-index', `${Number.MAX_SAFE_INTEGER}`, 'important');
    tooltip.style.setProperty('background-color', `white`, 'important');
    tooltip.style.setProperty('color', `black`, 'important');
    tooltip.style.setProperty('font', `normal 12px sans-serif`, 'important');
    tooltip.style.setProperty('border', `1px solid black`, 'important');
    tooltip.style.setProperty('margin', `0`, 'important');
    tooltip.style.setProperty('padding', `0`, 'important');
    document.body.appendChild(tooltip);
  }).catch(() => {
    // do nothing
  });
}

function hideTooltip() {
  let tooltip = document.getElementById(TOOLTIP_ID);
  if (tooltip != null) {
    document.body.removeChild(tooltip);
  }
}

function isTooltip(elem) {
  let tooltip = document.getElementById(TOOLTIP_ID);
  if (tooltip == null) {
    return false;
  }
  return (tooltip == elem || tooltip.contains(elem));
}

function getWordMeaning(word) {
  let dictUrl = `http://m.endic.naver.com/search.nhn?sLn=en&query=${encodeURIComponent(word)}&searchOption=entryIdiom&forceRedirect=`;
  let dictPageUrl = `http://endic.naver.com/search.nhn?sLn=en&query=${encodeURIComponent(word)}`;
  return fetch(dictUrl).then((response) => response.text())
      .then((text) => (new DOMParser()).parseFromString(text, 'text/html'))
      .then((doc) => {
        let cards = doc.body.querySelectorAll('div.section_card div.entry_search_word');
        if (cards.length < 1) {
          throw Error('No Result');
        }
        let result = '';
        let i = 0;
        for (let card of cards) {
          let title = card.querySelector('div.h_word>strong');
          let descs = card.querySelectorAll('ul.desc_lst p.desc');
          result += `<dl style="margin: 6px"><dt>${title.innerHTML}</dt>`
          let pronounces = card.querySelectorAll('div.pronun_area');
          for (let pronounce of pronounces) {
            let country = pronounce.querySelector('em.speech');
            let pronounceText = pronounce.querySelector('span.pronun');
            if (pronounceText === null) {
              continue;
            }
            result += `<dd style="margin-left: 0">${pronounceText.innerHTML}</dd>`;
          }
          result += '
';
          if (descs.length > 1) {
            result += '
';
            for (let desc of descs) {
              result += `<li>${desc.textContent}</li>`;
            }
            result += '
'
          } else if (descs.length == 1) {
            result += descs[0].textContent;
          }
          result += '

';
          i++;
          if (i >=  5) {
            break;
          }
        }
        result += `<p style="margin: 6px; text-align: right"><a href="${dictPageUrl}" target="_blank" rel="noopener noreferrer">네이버 사전 열기</a></p>`
        return result;
      });
}
<|endoftext|>


<commit_before>exports.config = {

    //
    // ==================
    // Specify Test Files
    // ==================
    // Define which test specs should run. The pattern is relative to the directory
    // from which `wdio` was called. Notice that, if you are calling `wdio` from an
    // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
    // directory is where your package.json resides, so `wdio` will be called from there.
    //
    specs: [
        './test/specs/**/*.js'
    ],
    // Patterns to exclude.
    exclude: [
        // 'path/to/excluded/files'
    ],
    //
    // ============
    // Capabilities
    // ============
    // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
    // time. Depending on the number of capabilities, WebdriverIO launches several test
    // sessions. Within your capabilities you can overwrite the spec and exclude options in
    // order to group specific specs to a specific capability.
    //
    // First, you can define how many instances should be started at the same time. Let's
    // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
    // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
    // files and you set maxInstances to 10, all spec files will get tested at the same time
    // and 30 processes will get spawned. The property handles how many capabilities
    // from the same test should run tests.
    //
    maxInstances: 10,
    //
    // If you have trouble getting all important capabilities together, check out the
    // Sauce Labs platform configurator - a great tool to configure your capabilities:
    // https://docs.saucelabs.com/reference/platforms-configurator
    //
    capabilities: [{
        // maxInstances can get overwritten per capability. So if you have an in-house Selenium
        // grid with only 5 firefox instances available you can make sure that not more than
        // 5 instances get started at a time.
        maxInstances: 5,
        //
        browserName: 'firefox'
    }],
    //
    // ===================
    // Test Configurations
    // ===================
    // Define all options that are relevant for the WebdriverIO instance here
    //
    // By default WebdriverIO commands are executed in a synchronous way using
    // the wdio-sync package. If you still want to run your tests in an async way
    // e.g. using promises you can set the sync option to false.
    sync: true,
    //
    // Level of logging verbosity: silent | verbose | command | data | result | error
    logLevel: 'result',
    //
    // Enables colors for log output.
    coloredLogs: true,
    //
    // If you only want to run your tests until a specific amount of tests have failed use
    // bail (default is 0 - don't bail, run all tests).
    bail: 0,
    //
    // Saves a screenshot to a given path if a command fails.
    screenshotPath: './errorShots/',
    //
    // Set a base URL in order to shorten url command calls. If your url parameter starts
    // with "/", then the base url gets prepended.
    baseUrl: 'http://localhost',
    //
    // Default timeout for all waitFor* commands.
    waitforTimeout: 10000,
    //
    // Default timeout in milliseconds for request
    // if Selenium Grid doesn't send response
    connectionRetryTimeout: 90000,
    //
    // Default request retries count
    connectionRetryCount: 3,
    //
    // Initialize the browser instance with a WebdriverIO plugin. The object should have the
    // plugin name as key and the desired plugin options as properties. Make sure you have
    // the plugin installed before running any tests. The following plugins are currently
    // available:
    // WebdriverCSS: https://github.com/webdriverio/webdrivercss
    // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
    // Browserevent: https://github.com/webdriverio/browserevent
    // plugins: {
    //     webdrivercss: {
    //         screenshotRoot: 'my-shots',
    //         failedComparisonsRoot: 'diffs',
    //         misMatchTolerance: 0.05,
    //         screenWidth: [320,480,640,1024]
    //     },
    //     webdriverrtc: {},
    //     browserevent: {}
    // },
    //
    // Test runner services
    // Services take over a specific job you don't want to take care of. They enhance
    // your test setup with almost no effort. Unlike plugins, they don't add new
    // commands. Instead, they hook themselves up into the test process.
    services: ['selenium-standalone','webpack'],
    //
    // Framework you want to run your specs with.
    // The following are supported: Mocha, Jasmine, and Cucumber
    // see also: http://webdriver.io/guide/testrunner/frameworks.html
    //
    // Make sure you have the wdio adapter package for the specific framework installed
    // before running any tests.
    framework: 'mocha',
    //
    // Test reporter for stdout.
    // The only one supported by default is 'dot'
    // see also: http://webdriver.io/guide/testrunner/reporters.html
    // reporters: ['dot'],
    //
    // Options to be passed to Mocha.
    // See the full list at http://mochajs.org/
    mochaOpts: {
        ui: 'bdd'
    },
    //
    // =====
    // Hooks
    // =====
    // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
    // it and to build services around it. You can either apply a single function or an array of
    // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
    // resolved to continue.
    //
    // Gets executed once before all workers get launched.
    // onPrepare: function (config, capabilities) {
    // },
    //
    // Gets executed just before initialising the webdriver session and test framework. It allows you
    // to manipulate configurations depending on the capability or spec.
    // beforeSession: function (config, capabilities, specs) {
    // },
    //
    // Gets executed before test execution begins. At this point you can access all global
    // variables, such as `browser`. It is the perfect place to define custom commands.
    // before: function (capabilities, specs) {
    // },
    //
    // Hook that gets executed before the suite starts
    // beforeSuite: function (suite) {
    // },
    //
    // Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling
    // beforeEach in Mocha)
    // beforeHook: function () {
    // },
    //
    // Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling
    // afterEach in Mocha)
    // afterHook: function () {
    // },
    //
    // Function to be executed before a test (in Mocha/Jasmine) or a step (in Cucumber) starts.
    // beforeTest: function (test) {
    // },
    //
    // Runs before a WebdriverIO command gets executed.
    // beforeCommand: function (commandName, args) {
    // },
    //
    // Runs after a WebdriverIO command gets executed
    // afterCommand: function (commandName, args, result, error) {
    // },
    //
    // Function to be executed after a test (in Mocha/Jasmine) or a step (in Cucumber) starts.
    // afterTest: function (test) {
    // },
    //
    // Hook that gets executed after the suite has ended
    // afterSuite: function (suite) {
    // },
    //
    // Gets executed after all tests are done. You still have access to all global variables from
    // the test.
    // after: function (result, capabilities, specs) {
    // },
    //
    // Gets executed right after terminating the webdriver session.
    // afterSession: function (config, capabilities, specs) {
    // },
    //
    // Gets executed after all workers got shut down and the process is about to exit. It is not
    // possible to defer the end of the process using a promise.
    // onComplete: function(exitCode) {
    // }
}
<commit_msg>Switch tests to chrome<commit_after>exports.config = {

    //
    // ==================
    // Specify Test Files
    // ==================
    // Define which test specs should run. The pattern is relative to the directory
    // from which `wdio` was called. Notice that, if you are calling `wdio` from an
    // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
    // directory is where your package.json resides, so `wdio` will be called from there.
    //
    specs: [
        './test/specs/**/*.js'
    ],
    // Patterns to exclude.
    exclude: [
        // 'path/to/excluded/files'
    ],
    //
    // ============
    // Capabilities
    // ============
    // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
    // time. Depending on the number of capabilities, WebdriverIO launches several test
    // sessions. Within your capabilities you can overwrite the spec and exclude options in
    // order to group specific specs to a specific capability.
    //
    // First, you can define how many instances should be started at the same time. Let's
    // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
    // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
    // files and you set maxInstances to 10, all spec files will get tested at the same time
    // and 30 processes will get spawned. The property handles how many capabilities
    // from the same test should run tests.
    //
    maxInstances: 10,
    //
    // If you have trouble getting all important capabilities together, check out the
    // Sauce Labs platform configurator - a great tool to configure your capabilities:
    // https://docs.saucelabs.com/reference/platforms-configurator
    //
    capabilities: [{
        // maxInstances can get overwritten per capability. So if you have an in-house Selenium
        // grid with only 5 firefox instances available you can make sure that not more than
        // 5 instances get started at a time.
        maxInstances: 5,
        //
        browserName: 'chrome'
    }],
    //
    // ===================
    // Test Configurations
    // ===================
    // Define all options that are relevant for the WebdriverIO instance here
    //
    // By default WebdriverIO commands are executed in a synchronous way using
    // the wdio-sync package. If you still want to run your tests in an async way
    // e.g. using promises you can set the sync option to false.
    sync: true,
    //
    // Level of logging verbosity: silent | verbose | command | data | result | error
    logLevel: 'result',
    //
    // Enables colors for log output.
    coloredLogs: true,
    //
    // If you only want to run your tests until a specific amount of tests have failed use
    // bail (default is 0 - don't bail, run all tests).
    bail: 0,
    //
    // Saves a screenshot to a given path if a command fails.
    screenshotPath: './errorShots/',
    //
    // Set a base URL in order to shorten url command calls. If your url parameter starts
    // with "/", then the base url gets prepended.
    baseUrl: 'http://localhost',
    //
    // Default timeout for all waitFor* commands.
    waitforTimeout: 10000,
    //
    // Default timeout in milliseconds for request
    // if Selenium Grid doesn't send response
    connectionRetryTimeout: 90000,
    //
    // Default request retries count
    connectionRetryCount: 3,
    //
    // Initialize the browser instance with a WebdriverIO plugin. The object should have the
    // plugin name as key and the desired plugin options as properties. Make sure you have
    // the plugin installed before running any tests. The following plugins are currently
    // available:
    // WebdriverCSS: https://github.com/webdriverio/webdrivercss
    // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
    // Browserevent: https://github.com/webdriverio/browserevent
    // plugins: {
    //     webdrivercss: {
    //         screenshotRoot: 'my-shots',
    //         failedComparisonsRoot: 'diffs',
    //         misMatchTolerance: 0.05,
    //         screenWidth: [320,480,640,1024]
    //     },
    //     webdriverrtc: {},
    //     browserevent: {}
    // },
    //
    // Test runner services
    // Services take over a specific job you don't want to take care of. They enhance
    // your test setup with almost no effort. Unlike plugins, they don't add new
    // commands. Instead, they hook themselves up into the test process.
    services: ['selenium-standalone','webpack'],
    //
    // Framework you want to run your specs with.
    // The following are supported: Mocha, Jasmine, and Cucumber
    // see also: http://webdriver.io/guide/testrunner/frameworks.html
    //
    // Make sure you have the wdio adapter package for the specific framework installed
    // before running any tests.
    framework: 'mocha',
    //
    // Test reporter for stdout.
    // The only one supported by default is 'dot'
    // see also: http://webdriver.io/guide/testrunner/reporters.html
    // reporters: ['dot'],
    //
    // Options to be passed to Mocha.
    // See the full list at http://mochajs.org/
    mochaOpts: {
        ui: 'bdd'
    },
    //
    // =====
    // Hooks
    // =====
    // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance
    // it and to build services around it. You can either apply a single function or an array of
    // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got
    // resolved to continue.
    //
    // Gets executed once before all workers get launched.
    // onPrepare: function (config, capabilities) {
    // },
    //
    // Gets executed just before initialising the webdriver session and test framework. It allows you
    // to manipulate configurations depending on the capability or spec.
    // beforeSession: function (config, capabilities, specs) {
    // },
    //
    // Gets executed before test execution begins. At this point you can access all global
    // variables, such as `browser`. It is the perfect place to define custom commands.
    // before: function (capabilities, specs) {
    // },
    //
    // Hook that gets executed before the suite starts
    // beforeSuite: function (suite) {
    // },
    //
    // Hook that gets executed _before_ a hook within the suite starts (e.g. runs before calling
    // beforeEach in Mocha)
    // beforeHook: function () {
    // },
    //
    // Hook that gets executed _after_ a hook within the suite starts (e.g. runs after calling
    // afterEach in Mocha)
    // afterHook: function () {
    // },
    //
    // Function to be executed before a test (in Mocha/Jasmine) or a step (in Cucumber) starts.
    // beforeTest: function (test) {
    // },
    //
    // Runs before a WebdriverIO command gets executed.
    // beforeCommand: function (commandName, args) {
    // },
    //
    // Runs after a WebdriverIO command gets executed
    // afterCommand: function (commandName, args, result, error) {
    // },
    //
    // Function to be executed after a test (in Mocha/Jasmine) or a step (in Cucumber) starts.
    // afterTest: function (test) {
    // },
    //
    // Hook that gets executed after the suite has ended
    // afterSuite: function (suite) {
    // },
    //
    // Gets executed after all tests are done. You still have access to all global variables from
    // the test.
    // after: function (result, capabilities, specs) {
    // },
    //
    // Gets executed right after terminating the webdriver session.
    // afterSession: function (config, capabilities, specs) {
    // },
    //
    // Gets executed after all workers got shut down and the process is about to exit. It is not
    // possible to defer the end of the process using a promise.
    // onComplete: function(exitCode) {
    // }
}
<|endoftext|>


<commit_before>
/*

	hashids
	http://www.hashids.org/node-js/
	(c) 2013 Ivan Akimov

	https://github.com/ivanakimov/hashids.node.js
	hashids may be freely distributed under the MIT license.

*/

/*jslint node: true, white: true, plusplus: true */

var Hashids;
module.exports = Hashids = (function () {

	"use strict";

	function Hashids(salt, minHashLength, alphabet) {

		var uniqueAlphabet, i, j, len, sepsLength, diff, guardCount;

		this.version = "0.3.0";

		/* internal settings */

		this.minAlphabetLength = 16;
		this.sepDiv = 3.5;
		this.guardDiv = 12;

		/* error messages */

		this.errorAlphabetLength = "error: alphabet must contain at least X unique characters";
		this.errorAlphabetSpace = "error: alphabet cannot contain spaces";

		/* alphabet vars */

		this.alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
		this.seps = "cfhistuCFHISTU";
		this.minHashLength = parseInt(minHashLength, 10) > 0 ? minHashLength : 0;
		this.salt = (typeof salt === "string") ? salt : "";

		if (typeof alphabet === "string") {
			this.alphabet = alphabet;
		}

		for (uniqueAlphabet = "", i = 0, len = this.alphabet.length; i !== len; i++) {
			if (uniqueAlphabet.indexOf(this.alphabet[i]) === -1) {
				uniqueAlphabet += this.alphabet[i];
			}
		}

		this.alphabet = uniqueAlphabet;

		if (this.alphabet.length < this.minAlphabetLength) {
			throw this.errorAlphabetLength.replace("X", this.minAlphabetLength);
		}

		if (this.alphabet.search(" ") !== -1) {
			throw this.errorAlphabetSpace;
		}

		/* seps should contain only characters present in alphabet; alphabet should not contains seps */

		for (i = 0, len = this.seps.length; i !== len; i++) {

			j = this.alphabet.indexOf(this.seps[i]);
			if (j === -1) {
				this.seps = this.seps.substr(0, i) + " " + this.seps.substr(i + 1);
			} else {
				this.alphabet = this.alphabet.substr(0, j) + " " + this.alphabet.substr(j + 1);
			}

		}

		this.alphabet = this.alphabet.replace(/ /g, "");

		this.seps = this.seps.replace(/ /g, "");
		this.seps = this.consistentShuffle(this.seps, this.salt);

		if (!this.seps.length || (this.alphabet.length / this.seps.length) > this.sepDiv) {

			sepsLength = Math.ceil(this.alphabet.length / this.sepDiv);

			if (sepsLength === 1) {
				sepsLength++;
			}

			if (sepsLength > this.seps.length) {

				diff = sepsLength - this.seps.length;
				this.seps += this.alphabet.substr(0, diff);
				this.alphabet = this.alphabet.substr(diff);

			} else {
				this.seps = this.seps.substr(0, sepsLength);
			}

		}

		this.alphabet = this.consistentShuffle(this.alphabet, this.salt);
		guardCount = Math.ceil(this.alphabet.length / this.guardDiv);

		if (this.alphabet.length < 3) {
			this.guards = this.seps.substr(0, guardCount);
			this.seps = this.seps.substr(guardCount);
		} else {
			this.guards = this.alphabet.substr(0, guardCount);
			this.alphabet = this.alphabet.substr(guardCount);
		}

	}

	Hashids.prototype.encrypt = function() {

		var ret = "",
			i, len,
			numbers = Array.prototype.slice.call(arguments);

		if (!numbers.length) {
			return ret;
		}

		if (numbers[0] instanceof Array) {
			numbers = numbers[0];
		}

		for (i = 0, len = numbers.length; i !== len; i++) {
			if (typeof numbers[i] !== "number" || numbers[i] % 1 !== 0 || numbers[i] < 0) {
				return ret;
			}
		}

		return this.encode(numbers);

	};

	Hashids.prototype.decrypt = function(hash) {

		var ret = [];

		if (!hash.length || typeof hash !== "string") {
			return ret;
		}

		return this.decode(hash, this.alphabet);

	};

	Hashids.prototype.encryptHex = function(str) {

		var i, len, numbers;

		if (!/^[0-9a-fA-F]+$/.test(str)) {
			return "";
		}

		numbers = str.match(/[\w\W]{1,12}/g);

		for (i = 0, len = numbers.length; i !== len; i++) {
			numbers[i] = parseInt("1" + numbers[i], 16);
		}

		return this.encrypt.apply(this, numbers);

	};

	Hashids.prototype.decryptHex = function(hash) {

		var ret = "",
			i, len,
			numbers = this.decrypt(hash);

		for (i = 0, len = numbers.length; i !== len; i++) {
			ret += (numbers[i]).toString(16).substr(1);
		}

		return ret;

	};

	Hashids.prototype.encode = function(numbers) {

		var ret, lottery, i, len, number, buffer, last, sepsIndex, guardIndex, guard, halfLength, excess,
			alphabet = this.alphabet,
			numbersSize = numbers.length,
			numbersHashInt = 0;

		for (i = 0, len = numbers.length; i !== len; i++) {
			numbersHashInt += (numbers[i] % (i + 100));
		}

		lottery = ret = alphabet[numbersHashInt % alphabet.length];
		for (i = 0, len = numbers.length; i !== len; i++) {

			number = numbers[i];
			buffer = lottery + this.salt + alphabet;

			alphabet = this.consistentShuffle(alphabet, buffer.substr(0, alphabet.length));
			last = this.hash(number, alphabet);

			ret += last;

			if (i + 1 < numbersSize) {
				number %= (last.charCodeAt(0) + i);
				sepsIndex = number % this.seps.length;
				ret += this.seps[sepsIndex];
			}

		}

		if (ret.length < this.minHashLength) {

			guardIndex = (numbersHashInt + ret[0].charCodeAt(0)) % this.guards.length;
			guard = this.guards[guardIndex];

			ret = guard + ret;

			if (ret.length < this.minHashLength) {

				guardIndex = (numbersHashInt + ret[2].charCodeAt(0)) % this.guards.length;
				guard = this.guards[guardIndex];

				ret += guard;

			}

		}

		halfLength = parseInt(alphabet.length / 2, 10);
		while (ret.length < this.minHashLength) {

			alphabet = this.consistentShuffle(alphabet, alphabet);
			ret = alphabet.substr(halfLength) + ret + alphabet.substr(0, halfLength);

			excess = ret.length - this.minHashLength;
			if (excess > 0) {
				ret = ret.substr(excess / 2, this.minHashLength);
			}

		}

		return ret;

	};

	Hashids.prototype.decode = function(hash, alphabet) {

		var ret = [],
			i = 0,
			lottery, len, subHash, buffer,
			r = new RegExp("[" + this.guards + "]", "g"),
			hashBreakdown = hash.replace(r, " "),
			hashArray = hashBreakdown.split(" ");

		if (hashArray.length === 3 || hashArray.length === 2) {
			i = 1;
		}

		hashBreakdown = hashArray[i];
		if (typeof hashBreakdown[0] !== "undefined") {

			lottery = hashBreakdown[0];
			hashBreakdown = hashBreakdown.substr(1);

			r = new RegExp("[" + this.seps + "]", "g");
			hashBreakdown = hashBreakdown.replace(r, " ");
			hashArray = hashBreakdown.split(" ");

			for (i = 0, len = hashArray.length; i !== len; i++) {

				subHash = hashArray[i];
				buffer = lottery + this.salt + alphabet;

				alphabet = this.consistentShuffle(alphabet, buffer.substr(0, alphabet.length));
				ret.push(this.unhash(subHash, alphabet));

			}

			if (this.encode(ret) !== hash) {
				ret = [];
			}

		}

		return ret;

	};

	Hashids.prototype.consistentShuffle = function(alphabet, salt) {

		var integer, j, temp, i, v, p;

		if (!salt.length) {
			return alphabet;
		}

		for (i = alphabet.length - 1, v = 0, p = 0; i > 0; i--, v++) {

			v %= salt.length;
			p += integer = salt[v].charCodeAt(0);
			j = (integer + v + p) % i;

			temp = alphabet[j];
			alphabet = alphabet.substr(0, j) + alphabet[i] + alphabet.substr(j + 1);
			alphabet = alphabet.substr(0, i) + temp + alphabet.substr(i + 1);

		}

		return alphabet;

	};

	Hashids.prototype.hash = function(input, alphabet) {

		var hash = "",
			alphabetLength = alphabet.length;

		do {
			hash = alphabet[input % alphabetLength] + hash;
			input = parseInt(input / alphabetLength, 10);
		} while (input);

		return hash;

	};

	Hashids.prototype.unhash = function(input, alphabet) {

		var number = 0, pos, i;

		for (i = 0; i < input.length; i++) {
			pos = alphabet.indexOf(input[i]);
			number += pos * Math.pow(alphabet.length, input.length - i - 1);
		}

		return number;

	};

	return Hashids;

}());
<commit_msg>cleanup<commit_after>
/*

	hashids
	http://www.hashids.org/node-js/
	(c) 2013 Ivan Akimov

	https://github.com/ivanakimov/hashids.node.js
	hashids may be freely distributed under the MIT license.

*/

/*jslint node: true, white: true, plusplus: true */

var Hashids;
module.exports = Hashids = (function () {

	"use strict";

	function Hashids(salt, minHashLength, alphabet) {

		var uniqueAlphabet, i, j, len, sepsLength, diff, guardCount;

		this.version = "0.3.0";

		/* internal settings */

		this.minAlphabetLength = 16;
		this.sepDiv = 3.5;
		this.guardDiv = 12;

		/* error messages */

		this.errorAlphabetLength = "error: alphabet must contain at least X unique characters";
		this.errorAlphabetSpace = "error: alphabet cannot contain spaces";

		/* alphabet vars */

		this.alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
		this.seps = "cfhistuCFHISTU";
		this.minHashLength = parseInt(minHashLength, 10) > 0 ? minHashLength : 0;
		this.salt = (typeof salt === "string") ? salt : "";

		if (typeof alphabet === "string") {
			this.alphabet = alphabet;
		}

		for (uniqueAlphabet = "", i = 0, len = this.alphabet.length; i !== len; i++) {
			if (uniqueAlphabet.indexOf(this.alphabet[i]) === -1) {
				uniqueAlphabet += this.alphabet[i];
			}
		}

		this.alphabet = uniqueAlphabet;

		if (this.alphabet.length < this.minAlphabetLength) {
			throw this.errorAlphabetLength.replace("X", this.minAlphabetLength);
		}

		if (this.alphabet.search(" ") !== -1) {
			throw this.errorAlphabetSpace;
		}

		/* seps should contain only characters present in alphabet; alphabet should not contains seps */

		for (i = 0, len = this.seps.length; i !== len; i++) {

			j = this.alphabet.indexOf(this.seps[i]);
			if (j === -1) {
				this.seps = this.seps.substr(0, i) + " " + this.seps.substr(i + 1);
			} else {
				this.alphabet = this.alphabet.substr(0, j) + " " + this.alphabet.substr(j + 1);
			}

		}

		this.alphabet = this.alphabet.replace(/ /g, "");

		this.seps = this.seps.replace(/ /g, "");
		this.seps = this.consistentShuffle(this.seps, this.salt);

		if (!this.seps.length || (this.alphabet.length / this.seps.length) > this.sepDiv) {

			sepsLength = Math.ceil(this.alphabet.length / this.sepDiv);

			if (sepsLength === 1) {
				sepsLength++;
			}

			if (sepsLength > this.seps.length) {

				diff = sepsLength - this.seps.length;
				this.seps += this.alphabet.substr(0, diff);
				this.alphabet = this.alphabet.substr(diff);

			} else {
				this.seps = this.seps.substr(0, sepsLength);
			}

		}

		this.alphabet = this.consistentShuffle(this.alphabet, this.salt);
		guardCount = Math.ceil(this.alphabet.length / this.guardDiv);

		if (this.alphabet.length < 3) {
			this.guards = this.seps.substr(0, guardCount);
			this.seps = this.seps.substr(guardCount);
		} else {
			this.guards = this.alphabet.substr(0, guardCount);
			this.alphabet = this.alphabet.substr(guardCount);
		}

	}

	Hashids.prototype.encrypt = function() {

		var ret = "",
			i, len,
			numbers = Array.prototype.slice.call(arguments);

		if (!numbers.length) {
			return ret;
		}

		if (numbers[0] instanceof Array) {
			numbers = numbers[0];
		}

		for (i = 0, len = numbers.length; i !== len; i++) {
			if (typeof numbers[i] !== "number" || numbers[i] % 1 !== 0 || numbers[i] < 0) {
				return ret;
			}
		}

		return this.encode(numbers);

	};

	Hashids.prototype.decrypt = function(hash) {

		var ret = [];

		if (!hash.length || typeof hash !== "string") {
			return ret;
		}

		return this.decode(hash, this.alphabet);

	};

	Hashids.prototype.encryptHex = function(str) {

		var i, len, numbers;

		if (!/^[0-9a-fA-F]+$/.test(str)) {
			return "";
		}

		numbers = str.match(/[\w\W]{1,12}/g);

		for (i = 0, len = numbers.length; i !== len; i++) {
			numbers[i] = parseInt("1" + numbers[i], 16);
		}

		return this.encrypt.apply(this, numbers);

	};

	Hashids.prototype.decryptHex = function(hash) {

		var ret = [],
			i, len,
			numbers = this.decrypt(hash);

		for (i = 0, len = numbers.length; i !== len; i++) {
			ret += (numbers[i]).toString(16).substr(1);
		}

		return ret;

	};

	Hashids.prototype.encode = function(numbers) {

		var ret, lottery, i, len, number, buffer, last, sepsIndex, guardIndex, guard, halfLength, excess,
			alphabet = this.alphabet,
			numbersSize = numbers.length,
			numbersHashInt = 0;

		for (i = 0, len = numbers.length; i !== len; i++) {
			numbersHashInt += (numbers[i] % (i + 100));
		}

		lottery = ret = alphabet[numbersHashInt % alphabet.length];
		for (i = 0, len = numbers.length; i !== len; i++) {

			number = numbers[i];
			buffer = lottery + this.salt + alphabet;

			alphabet = this.consistentShuffle(alphabet, buffer.substr(0, alphabet.length));
			last = this.hash(number, alphabet);

			ret += last;

			if (i + 1 < numbersSize) {
				number %= (last.charCodeAt(0) + i);
				sepsIndex = number % this.seps.length;
				ret += this.seps[sepsIndex];
			}

		}

		if (ret.length < this.minHashLength) {

			guardIndex = (numbersHashInt + ret[0].charCodeAt(0)) % this.guards.length;
			guard = this.guards[guardIndex];

			ret = guard + ret;

			if (ret.length < this.minHashLength) {

				guardIndex = (numbersHashInt + ret[2].charCodeAt(0)) % this.guards.length;
				guard = this.guards[guardIndex];

				ret += guard;

			}

		}

		halfLength = parseInt(alphabet.length / 2, 10);
		while (ret.length < this.minHashLength) {

			alphabet = this.consistentShuffle(alphabet, alphabet);
			ret = alphabet.substr(halfLength) + ret + alphabet.substr(0, halfLength);

			excess = ret.length - this.minHashLength;
			if (excess > 0) {
				ret = ret.substr(excess / 2, this.minHashLength);
			}

		}

		return ret;

	};

	Hashids.prototype.decode = function(hash, alphabet) {

		var ret = [],
			i = 0,
			lottery, len, subHash, buffer,
			r = new RegExp("[" + this.guards + "]", "g"),
			hashBreakdown = hash.replace(r, " "),
			hashArray = hashBreakdown.split(" ");

		if (hashArray.length === 3 || hashArray.length === 2) {
			i = 1;
		}

		hashBreakdown = hashArray[i];
		if (typeof hashBreakdown[0] !== "undefined") {

			lottery = hashBreakdown[0];
			hashBreakdown = hashBreakdown.substr(1);

			r = new RegExp("[" + this.seps + "]", "g");
			hashBreakdown = hashBreakdown.replace(r, " ");
			hashArray = hashBreakdown.split(" ");

			for (i = 0, len = hashArray.length; i !== len; i++) {

				subHash = hashArray[i];
				buffer = lottery + this.salt + alphabet;

				alphabet = this.consistentShuffle(alphabet, buffer.substr(0, alphabet.length));
				ret.push(this.unhash(subHash, alphabet));

			}

			if (this.encode(ret) !== hash) {
				ret = [];
			}

		}

		return ret;

	};

	Hashids.prototype.consistentShuffle = function(alphabet, salt) {

		var integer, j, temp, i, v, p;

		if (!salt.length) {
			return alphabet;
		}

		for (i = alphabet.length - 1, v = 0, p = 0; i > 0; i--, v++) {

			v %= salt.length;
			p += integer = salt[v].charCodeAt(0);
			j = (integer + v + p) % i;

			temp = alphabet[j];
			alphabet = alphabet.substr(0, j) + alphabet[i] + alphabet.substr(j + 1);
			alphabet = alphabet.substr(0, i) + temp + alphabet.substr(i + 1);

		}

		return alphabet;

	};

	Hashids.prototype.hash = function(input, alphabet) {

		var hash = "",
			alphabetLength = alphabet.length;

		do {
			hash = alphabet[input % alphabetLength] + hash;
			input = parseInt(input / alphabetLength, 10);
		} while (input);

		return hash;

	};

	Hashids.prototype.unhash = function(input, alphabet) {

		var number = 0, pos, i;

		for (i = 0; i < input.length; i++) {
			pos = alphabet.indexOf(input[i]);
			number += pos * Math.pow(alphabet.length, input.length - i - 1);
		}

		return number;

	};

	return Hashids;

}());
<|endoftext|>


<commit_before>'use strict';
var sportsQuestions = [];
var entertainmentQuestions = [];
var feminismQuestions = [];
var chosenCategory;

// all localStorage functions here
function storeCategory() {
  var categoryJSON = JSON.stringify(chosenCategory);
  localStorage.setItem('categoryChoice', categoryJSON);
}

//Question Constructor Below This Line
function Question(question, right, wrongOne, wrongTwo, wrongThree, category) {
  this.question = question;
  this.right = right,
  this.wrongOne = wrongOne;
  this.wrongTwo = wrongTwo;
  this.wrongThree = wrongThree;
  this.category = category;
}

//Sports Questions Below This Line
var sportOne = new Question('When did The University of Kansas last win the NCAA National Championship?', '2008', '2012', '1994', '1956', 'sports');
sportsQuestions.push(sportOne);

var sportTwo = new Question('As of June 20, 2016, how many days has it been since the Flyers won the Stanley Cup?', '15,000 days', '25,000 days', '24 days', '3,000 days', 'sports');
sportsQuestions.push(sportTwo);

var sportThree = new Question('What record number of beers did MLB Hall of Famer Wade Boggs drink in a single day?', '107', '64', '78', '33', 'sports');
sportsQuestions.push(sportThree);

var sportFour = new Question('When was the first celebratory champagne bottle pop after a motor race?', 'The 1967 24 Hours of Le Mans', 'The 1958 Monaco Grand Prix', 'The 1987 Sonoma Motor Classic Festival', 'The 1974 Monterey Motor Classic', 'sports');
sportsQuestions.push(sportFour);

var sportFive = new Question('Who is the last non-quarterback to win NFL MVP?', 'Adrian Peterson', 'Ray Lewis', 'LaDainian Tomlinson', 'Shaun Alexander', 'sports');
sportsQuestions.push(sportFive);

var sportSix = new Question('The 1942 and 1946 FIFA World Cup tournaments were cancelled due to WWII and its aftermath. Which two countries sought to host these events?', 'Nazi Germany & Brazil', 'France & Sweden', 'Argentina & Canada', 'Portugal & Uraguay', 'sports');
sportsQuestions.push(sportSix);

var sportSeven = new Question('What year was Table Tennis added to the Summer Olympics?', '1988', '1980', '1996', '1972', 'sports');
sportsQuestions.push(sportSeven);

var sportEight = new Question('Against which MLB team did Hank Aaron hit his 500th homerun?', 'San Fransico Giants', 'Atlanta Braves', 'Milwaukee Brewers', 'Cincinnati Reds', 'sports');
sportsQuestions.push(sportEight);

var sportNine = new Question('Which current NBA team belonged to the American Basketball Association(ABA) before the league\'s merge with the NBA in 1976', 'Indianna Pacers', 'LA Clippers', 'LA Lakers', 'Chicago Bulls', 'sports');
sportsQuestions.push(sportNine);

var sportTen = new Question('in 1994, NBA legend Michael Jordan played Double-A minor league baseball for an affiliate of the Chicago White Sox. Which South-Eastern team did he play for?', 'Birminham Barons', 'Charleston Riverdogs', 'Memphis Redbirds', 'Shreveport Captains', 'sports');
sportsQuestions.push(sportTen);

//Entertainment Questions Below This Line
var entertainOne = new Question('When asked what he had done with his life to merit an invitation to the Whitehouse, to which First Lady did Miles Davis respond: “Well, I’ve changed the course of music five or six times. What have you done except f**k the president?”', 'Nancy Reagan', 'Barbara Bush', 'Jackie Kennedy', 'Betty Ford', 'entertainment');
entertainmentQuestions.push(entertainOne);

var entertainTwo = new Question('In the film Pineapple Express, which Star Wars creature is referenced by James Franco during his captivity?', 'Rancor', 'Tauntaun', 'Jawa', 'Wookie', 'entertainment');
entertainmentQuestions.push(entertainTwo);

var entertainThree = new Question('Who wrote the poetry spoken in Beyonce\'s Lemonade film', 'Warsan Shire', 'Roxane Gay', 'Chiminanda Ngozi Adichi', 'bell hooks', 'entertainment');
entertainmentQuestions.push(entertainThree);

var entertainFour = new Question('In what year was Wu-Tang member Raekwon’s gold-selling “Only Built for Cuban Linx” released?', '1995', '1994', '1996', '1997', 'entertainment');
entertainmentQuestions.push(entertainFour);

var entertainFive = new Question('Which Hip-Hop artist has acted in films alongside Edward Norton, Jack Black, and Bruce Willis?', 'Mos Def', 'Ludacris', 'Queen Latifah', 'Ice Cube', 'entertainment');
entertainmentQuestions.push(entertainFive);

//Feminism Questions Below This Line
var femOne = new Question('The Equal Rights Amendment was first introduced to Congress in 1923 and intended to guarantee equal rights for women. In what year was this Amendment ratified?', 'It has not yet been ratified', '1977', '1979', '1982', 'feminism');
feminismQuestions.push(femOne);

var femTwo = new Question('Who are the current female Supreme Court members?', 'Justice Sonya Sotomayor, Justice Ruth Bader Ginsburg, Justice Elena Kagan', 'Justice Notorious R.B.G., Justice Notorious B.I.G., Justice Antonin Scalia', 'Justice Sandra Day O’Connor, Justice Sonya Sotomayor, Justice Ruth Bader Ginsburg', 'Justice Michelle Obama, Justice Condoleeza Rice, Justice Hillary Clinton', 'feminism');
feminismQuestions.push(femTwo);

var femThree = new Question('Who was the first woman to win the Nobel Prize for Science(first for Physics, then years later in Chemistry)?', 'Marie Curie', 'Ada Lovelace', 'Rachel Carson', 'Sally Ride', 'feminism');
feminismQuestions.push(femThree);

var femFour = new Question('What is Intersectional Feminism?', 'The view that women experience oppression in varying degrees of intensity.', 'Feminism at traffic intersections' , 'Feminism for cats', 'Black Lives Matter', 'feminism');
feminismQuestions.push(femFour);

var femFive = new Question('Which feminist author famously wrote, “Caring for myself is not self-indulgence, it is self-preservation, and that is an act of political warfare.” ?', 'Audre Lorde', 'Angela Davis', 'Gloria Steinem', 'Alice Walker', 'feminism');
feminismQuestions.push(femFive);

//Category Selector CHANGE SPORTSQUESTIONS TO CHOSENCATEGORY LATER IN APP.JS
function chooseCategory() {
  var catSport = document.getElementById('sports');
  catSport.addEventListener('click', categorySelector);
  var catEnt = document.getElementById('entertainment');
  catEnt.addEventListener('click', categorySelector);
  var catFem = document.getElementById('feminism');
  catFem.addEventListener('click', categorySelector);

  function categorySelector(event) {
    event.preventDefault();
    var clickedCategory = event.target;
    if (clickedCategory === catSport) {
      chosenCategory = sportsQuestions;
      storeCategory(chosenCategory);
      window.location.replace('play.html');
    }
    if (clickedCategory === catEnt) {
      chosenCategory = entertainmentQuestions;
      storeCategory(chosenCategory);
      window.location.replace('play.html');
    }
    if (clickedCategory === catFem) {
      chosenCategory = feminismQuestions;
      storeCategory(chosenCategory);
      window.location.replace('play.html');
    }
  }
}

chooseCategory();<commit_msg>retrieved lost entertainment questions 6-10<commit_after>'use strict';
var sportsQuestions = [];
var entertainmentQuestions = [];
var feminismQuestions = [];
var chosenCategory;

// all localStorage functions here
function storeCategory() {
  var categoryJSON = JSON.stringify(chosenCategory);
  localStorage.setItem('categoryChoice', categoryJSON);
}

//Question Constructor Below This Line
function Question(question, right, wrongOne, wrongTwo, wrongThree, category) {
  this.question = question;
  this.right = right,
  this.wrongOne = wrongOne;
  this.wrongTwo = wrongTwo;
  this.wrongThree = wrongThree;
  this.category = category;
}

//Sports Questions Below This Line
var sportOne = new Question('When did The University of Kansas last win the NCAA National Championship?', '2008', '2012', '1994', '1956', 'sports');
sportsQuestions.push(sportOne);

var sportTwo = new Question('As of June 20, 2016, how many days has it been since the Flyers won the Stanley Cup?', '15,000 days', '25,000 days', '24 days', '3,000 days', 'sports');
sportsQuestions.push(sportTwo);

var sportThree = new Question('What record number of beers did MLB Hall of Famer Wade Boggs drink in a single day?', '107', '64', '78', '33', 'sports');
sportsQuestions.push(sportThree);

var sportFour = new Question('When was the first celebratory champagne bottle pop after a motor race?', 'The 1967 24 Hours of Le Mans', 'The 1958 Monaco Grand Prix', 'The 1987 Sonoma Motor Classic Festival', 'The 1974 Monterey Motor Classic', 'sports');
sportsQuestions.push(sportFour);

var sportFive = new Question('Who is the last non-quarterback to win NFL MVP?', 'Adrian Peterson', 'Ray Lewis', 'LaDainian Tomlinson', 'Shaun Alexander', 'sports');
sportsQuestions.push(sportFive);

var sportSix = new Question('The 1942 and 1946 FIFA World Cup tournaments were cancelled due to WWII and its aftermath. Which two countries sought to host these events?', 'Nazi Germany & Brazil', 'France & Sweden', 'Argentina & Canada', 'Portugal & Uraguay', 'sports');
sportsQuestions.push(sportSix);

var sportSeven = new Question('What year was Table Tennis added to the Summer Olympics?', '1988', '1980', '1996', '1972', 'sports');
sportsQuestions.push(sportSeven);

var sportEight = new Question('Against which MLB team did Hank Aaron hit his 500th homerun?', 'San Fransico Giants', 'Atlanta Braves', 'Milwaukee Brewers', 'Cincinnati Reds', 'sports');
sportsQuestions.push(sportEight);

var sportNine = new Question('Which current NBA team belonged to the American Basketball Association(ABA) before the league\'s merge with the NBA in 1976', 'Indianna Pacers', 'LA Clippers', 'LA Lakers', 'Chicago Bulls', 'sports');
sportsQuestions.push(sportNine);

var sportTen = new Question('in 1994, NBA legend Michael Jordan played Double-A minor league baseball for an affiliate of the Chicago White Sox. Which South-Eastern team did he play for?', 'Birminham Barons', 'Charleston Riverdogs', 'Memphis Redbirds', 'Shreveport Captains', 'sports');
sportsQuestions.push(sportTen);

//Entertainment Questions Below This Line
var entertainOne = new Question('When asked what he had done with his life to merit an invitation to the Whitehouse, to which First Lady did Miles Davis respond: “Well, I’ve changed the course of music five or six times. What have you done except f**k the president?”', 'Nancy Reagan', 'Barbara Bush', 'Jackie Kennedy', 'Betty Ford', 'entertainment');
entertainmentQuestions.push(entertainOne);

var entertainTwo = new Question('In the film Pineapple Express, which Star Wars creature is referenced by James Franco during his captivity?', 'Rancor', 'Tauntaun', 'Jawa', 'Wookie', 'entertainment');
entertainmentQuestions.push(entertainTwo);

var entertainThree = new Question('Who wrote the poetry spoken in Beyonce\'s Lemonade film', 'Warsan Shire', 'Roxane Gay', 'Chiminanda Ngozi Adichi', 'bell hooks', 'entertainment');
entertainmentQuestions.push(entertainThree);

var entertainFour = new Question('In what year was Wu-Tang member Raekwon’s gold-selling “Only Built for Cuban Linx” released?', '1995', '1994', '1996', '1997', 'entertainment');
entertainmentQuestions.push(entertainFour);

var entertainFive = new Question('Which Hip-Hop artist has acted in films alongside Edward Norton, Jack Black, and Bruce Willis?', 'Mos Def', 'Ludacris', 'Queen Latifah', 'Ice Cube', 'entertainment');
entertainmentQuestions.push(entertainFive);

var entertainSix = new Question('In the 1942 classic Casablanca, Humphrey Bogart’s character Rick Blaine speaks the famous line: “Of all the ____ joints, in all the towns in the world, she walks into mine.”', 'gin', 'whiskey', 'tequila', 'wine', 'entertainment');
entertainmentQuestions.push(entertainSix);

var entertainSeven = new Question('Dr. Dre isn\'t known for his medical advice, but he suggests that his audiences "Smoke weed" how often?', 'Everyday', 'Twice a week', 'Never', 'Monthly', 'entertainment');
entertainmentQuestions.push(entertainSeven);

var entertainEight = new Question('Lost in La Mancha is a 2002 documentary about which renowned Sci/Fi and Fantasy director\'s failed attempt to finish a film about the story of Don Quixote?', 'Terry Gilliam', 'J.J. Abrams', 'Guillermo del Toro', 'Ridley Scott', 'entertainment');
entertainmentQuestions.push(entertainEight);

var entertainNine = new Question('Who was the first ever Black Oscar winner in a category outside of acting?', 'Issac Hayes', 'Stevie Wonder', 'Hattie McDaniel', 'Sidney Poitier', 'entertainment');
entertainmentQuestions.push(entertainNine);

var entertainTen = new Question('What South-Western town is the setting for the acclaimed AMC television series Breaking Bad', 'Albequerque', 'Santa Fe', 'Phoenix', 'San Antonio', 'entertainment');
entertainmentQuestions.push(entertainTen);

//Feminism Questions Below This Line
var femOne = new Question('The Equal Rights Amendment was first introduced to Congress in 1923 and intended to guarantee equal rights for women. In what year was this Amendment ratified?', 'It has not yet been ratified', '1977', '1979', '1982', 'feminism');
feminismQuestions.push(femOne);

var femTwo = new Question('Who are the current female Supreme Court members?', 'Justice Sonya Sotomayor, Justice Ruth Bader Ginsburg, Justice Elena Kagan', 'Justice Notorious R.B.G., Justice Notorious B.I.G., Justice Antonin Scalia', 'Justice Sandra Day O’Connor, Justice Sonya Sotomayor, Justice Ruth Bader Ginsburg', 'Justice Michelle Obama, Justice Condoleeza Rice, Justice Hillary Clinton', 'feminism');
feminismQuestions.push(femTwo);

var femThree = new Question('Who was the first woman to win the Nobel Prize for Science(first for Physics, then years later in Chemistry)?', 'Marie Curie', 'Ada Lovelace', 'Rachel Carson', 'Sally Ride', 'feminism');
feminismQuestions.push(femThree);

var femFour = new Question('What is Intersectional Feminism?', 'The view that women experience oppression in varying degrees of intensity.', 'Feminism at traffic intersections' , 'Feminism for cats', 'Black Lives Matter', 'feminism');
feminismQuestions.push(femFour);

var femFive = new Question('Which feminist author famously wrote, “Caring for myself is not self-indulgence, it is self-preservation, and that is an act of political warfare.” ?', 'Audre Lorde', 'Angela Davis', 'Gloria Steinem', 'Alice Walker', 'feminism');
feminismQuestions.push(femFive);

//Category Selector CHANGE SPORTSQUESTIONS TO CHOSENCATEGORY LATER IN APP.JS
function chooseCategory() {
  var catSport = document.getElementById('sports');
  catSport.addEventListener('click', categorySelector);
  var catEnt = document.getElementById('entertainment');
  catEnt.addEventListener('click', categorySelector);
  var catFem = document.getElementById('feminism');
  catFem.addEventListener('click', categorySelector);

  function categorySelector(event) {
    event.preventDefault();
    var clickedCategory = event.target;
    if (clickedCategory === catSport) {
      chosenCategory = sportsQuestions;
      storeCategory(chosenCategory);
      window.location.replace('play.html');
    }
    if (clickedCategory === catEnt) {
      chosenCategory = entertainmentQuestions;
      storeCategory(chosenCategory);
      window.location.replace('play.html');
    }
    if (clickedCategory === catFem) {
      chosenCategory = feminismQuestions;
      storeCategory(chosenCategory);
      window.location.replace('play.html');
    }
  }
}

chooseCategory();<|endoftext|>