<commit_before>// Beaver: A beaver in the game.

var Class = require("classe");
var log = require(__basedir + "/gameplay/log");
var GameObject = require("./gameObject");

//<<-- Creer-Merge: requires -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

//<<-- /Creer-Merge: requires -->>

// @class Beaver: A beaver in the game.
var Beaver = Class(GameObject, {
    /**
     * Initializes Beavers.
     *
     * @param {Object} data - a simple mapping passed in to the constructor with whatever you sent with it. GameSettings are in here by key/value as well.
     */
    init: function(data) {
        GameObject.init.apply(this, arguments);

        /**
         * The number of actions remaining for the beaver this turn.
         *
         * @type {number}
         */
        this.actions = this.actions || 0;

        /**
         * The number of branches this beaver is holding.
         *
         * @type {number}
         */
        this.branches = this.branches || 0;

        /**
         * Number of turns this beaver is distracted for (0 means not distracted).
         *
         * @type {number}
         */
        this.distracted = this.distracted || 0;

        /**
         * The number of fish this beaver is holding.
         *
         * @type {number}
         */
        this.fish = this.fish || 0;

        /**
         * How much health this beaver has left.
         *
         * @type {number}
         */
        this.health = this.health || 0;

        /**
         * The Job this beaver was recruited to do.
         *
         * @type {Job}
         */
        this.job = this.job || null;

        /**
         * How many moves this beaver has left this turn.
         *
         * @type {number}
         */
        this.moves = this.moves || 0;

        /**
         * The Player that owns and can control this beaver.
         *
         * @type {Player}
         */
        this.owner = this.owner || null;

        /**
         * The tile this beaver is on.
         *
         * @type {Tile}
         */
        this.tile = this.tile || null;

        //<<-- Creer-Merge: init -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        for(var key of this.job) {
            this[key] = this.job[key];
        }

        //<<-- /Creer-Merge: init -->>
    },

    gameObjectName: "Beaver",

    /**
     * Attacks another adjacent beaver.
     *
     * @param {Player} player - the player that called this.
     * @param {Tile} tile - The tile of the beaver you want to attack.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully attacked, false otherwise.
     */
    attack: function(player, tile, asyncReturn) {
        // <<-- Creer-Merge: attack -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's attack function here
        return false;

        // <<-- /Creer-Merge: attack -->>
    },

    /**
     * Builds a lodge on the Beavers current tile.
     *
     * @param {Player} player - the player that called this.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully built a lodge, false otherwise.
     */
    buildLodge: function(player, asyncReturn) {
        // <<-- Creer-Merge: buildLodge -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's buildLodge function here
        return false;

        // <<-- /Creer-Merge: buildLodge -->>
    },

    /**
     * Drops some of the given resource on the beaver's tile. Fish dropped in water disappear instantly, and fish dropped on land die one per tile per turn.
     *
     * @param {Player} player - the player that called this.
     * @param {string} resource - The type of resource to drop ('branch' or 'fish').
     * @param {number} amount - The amount of the resource to drop, numbers <= 0 will drop all of that type.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully dropped the resource, false otherwise.
     */
    drop: function(player, resource, amount, asyncReturn) {
        // <<-- Creer-Merge: drop -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's drop function here
        return false;

        // <<-- /Creer-Merge: drop -->>
    },

    /**
     * Harvests the branches or fish from a Spawner on an adjacent tile.
     *
     * @param {Player} player - the player that called this.
     * @param {Tile} tile - The tile you want to harvest.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully harvested, false otherwise.
     */
    harvest: function(player, tile, asyncReturn) {
        // <<-- Creer-Merge: harvest -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.
        let reason = null;
        let gathered = 0;
        const load = this.fish + this.branches;

        if(player === null || player !== this.game.currentPlayer) {
            reason = `Not ${player}'s turn.`;
        }
        else if(this.owner !== player) {
            reason = `${this} is owned by ${this.owner} not by ${player}.`;
        }
        else if(tile === null) {
            reason = `${tile} is not a valid Tile.`;
        }
        else if(tile.spawner === null) {
            reason = `Tile ${tile} has no spawner.`;
        }
        else if(!this.tile.hasNeighbor(tile)) {
            reason = `${this} on tile ${this.tile} is not adjacent to ${tile}.`;
        }
        else if(this.health <= 0) {
            reason = `${this} is dead.`;
        }
        else if(this.actions <= 0) {
            reason = `${this} has no actions available.`;
        }
        else if(this.distracted > 0) {
            reason = `${this} is distracted for ${this.distracted} more turns.`;
        }
        else if(load >= this.job.carryLimit) {
            reason = `Beaver cannot carry more. Limit: (${load}/${this.job.carryLimit})`;
        }

        if(reason !== null) {
            return this.game.logicError(false, reason);
        }

        const available = Math.pow(2, tile.spawner.health);
        const space = this.job.carryLimit - load;
        let skill = this.job.fishing;
        let container = "fish";

        if(tile.spawner.type === "Branch") {
            skill = this.job.chopping;
            container = "branches";
        }

        gathered = available < skill ? available : skill;
        gathered = gathered > space ? space : gathered;
        this[container] += gathered;
        this.actions--;

        if(tile.spawner.health > 0) {
            tile.spawner.health--;
        }

        return gathered > 0;
        // <<-- /Creer-Merge: harvest -->>
    },

    /**
     * Moves this beaver from its current tile to an adjacent tile.
     *
     * @param {Player} player - the player that called this.
     * @param {Tile} tile - The tile this beaver should move to. Costs 2 moves normally, 3 if moving upstream, and 1 if moving downstream.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if the move worked, false otherwise.
     */
    move: function(player, tile, asyncReturn) {
        // <<-- Creer-Merge: move -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's move function here
        return false;

        // <<-- /Creer-Merge: move -->>
    },

    /**
     * Picks up some branches or fish on the beaver's tile.
     *
     * @param {Player} player - the player that called this.
     * @param {string} resource - The type of resource to pickup ('branch' or 'fish').
     * @param {number} amount - The amount of the resource to drop, numbers <= 0 will pickup all of that type.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully picked up a resource, false otherwise.
     */
    pickup: function(player, resource, amount, asyncReturn) {
        // <<-- Creer-Merge: pickup -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's pickup function here
        return false;

        // <<-- /Creer-Merge: pickup -->>
    },

    //<<-- Creer-Merge: added-functions -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

    // You can add additional functions here. These functions will not be directly callable by client AIs

    //<<-- /Creer-Merge: added-functions -->>

});

module.exports = Beaver;
<commit_msg>Update to use beaver _check<commit_after>// Beaver: A beaver in the game.

var Class = require("classe");
var log = require(__basedir + "/gameplay/log");
var GameObject = require("./gameObject");

//<<-- Creer-Merge: requires -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

//<<-- /Creer-Merge: requires -->>

// @class Beaver: A beaver in the game.
var Beaver = Class(GameObject, {
    /**
     * Initializes Beavers.
     *
     * @param {Object} data - a simple mapping passed in to the constructor with whatever you sent with it. GameSettings are in here by key/value as well.
     */
    init: function(data) {
        GameObject.init.apply(this, arguments);

        /**
         * The number of actions remaining for the beaver this turn.
         *
         * @type {number}
         */
        this.actions = this.actions || 0;

        /**
         * The number of branches this beaver is holding.
         *
         * @type {number}
         */
        this.branches = this.branches || 0;

        /**
         * Number of turns this beaver is distracted for (0 means not distracted).
         *
         * @type {number}
         */
        this.distracted = this.distracted || 0;

        /**
         * The number of fish this beaver is holding.
         *
         * @type {number}
         */
        this.fish = this.fish || 0;

        /**
         * How much health this beaver has left.
         *
         * @type {number}
         */
        this.health = this.health || 0;

        /**
         * The Job this beaver was recruited to do.
         *
         * @type {Job}
         */
        this.job = this.job || null;

        /**
         * How many moves this beaver has left this turn.
         *
         * @type {number}
         */
        this.moves = this.moves || 0;

        /**
         * The Player that owns and can control this beaver.
         *
         * @type {Player}
         */
        this.owner = this.owner || null;

        /**
         * The tile this beaver is on.
         *
         * @type {Tile}
         */
        this.tile = this.tile || null;

        //<<-- Creer-Merge: init -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        for(var key of this.job) {
            this[key] = this.job[key];
        }

        //<<-- /Creer-Merge: init -->>
    },

    gameObjectName: "Beaver",

    /**
     * Attacks another adjacent beaver.
     *
     * @param {Player} player - the player that called this.
     * @param {Tile} tile - The tile of the beaver you want to attack.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully attacked, false otherwise.
     */
    attack: function(player, tile, asyncReturn) {
        // <<-- Creer-Merge: attack -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's attack function here
        return false;

        // <<-- /Creer-Merge: attack -->>
    },

    /**
     * Builds a lodge on the Beavers current tile.
     *
     * @param {Player} player - the player that called this.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully built a lodge, false otherwise.
     */
    buildLodge: function(player, asyncReturn) {
        // <<-- Creer-Merge: buildLodge -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's buildLodge function here
        return false;

        // <<-- /Creer-Merge: buildLodge -->>
    },

    /**
     * Drops some of the given resource on the beaver's tile. Fish dropped in water disappear instantly, and fish dropped on land die one per tile per turn.
     *
     * @param {Player} player - the player that called this.
     * @param {string} resource - The type of resource to drop ('branch' or 'fish').
     * @param {number} amount - The amount of the resource to drop, numbers <= 0 will drop all of that type.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully dropped the resource, false otherwise.
     */
    drop: function(player, resource, amount, asyncReturn) {
        // <<-- Creer-Merge: drop -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's drop function here
        return false;

        // <<-- /Creer-Merge: drop -->>
    },

    /**
     * Harvests the branches or fish from a Spawner on an adjacent tile.
     *
     * @param {Player} player - the player that called this.
     * @param {Tile} tile - The tile you want to harvest.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully harvested, false otherwise.
     */
    harvest: function(player, tile, asyncReturn) {
        // <<-- Creer-Merge: harvest -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.
        let reason = this._check(player, tile);
        let gathered = 0;
        const load = this.fish + this.branches;

        if(reason) {
            // reason exists, don't update with new reason
        }
        else if(!this.tile.hasNeighbor(tile)) {
            reason = `${this} on tile ${this.tile} is not adjacent to ${tile}.`;
        }
        else if(this.actions <= 0) {
            reason = `${this} has no actions available.`;
        }
        else if(load >= this.job.carryLimit) {
            reason = `Beaver cannot carry more. Limit: (${load}/${this.job.carryLimit})`;
        }

        if(reason) {
            return this.game.logicError(false, reason);
        }

        const available = Math.pow(2 /* tbd */, tile.spawner.health);
        const space = this.job.carryLimit - load;
        let skill = this.job.fishing;
        let container = "fish";

        if(tile.spawner.type === "Branch") {
            skill = this.job.chopping;
            container = "branches";
        }

        gathered = available < skill ? available : skill;
        gathered = gathered > space ? space : gathered;
        this[container] += gathered;
        this.actions--;

        if(tile.spawner.health > 0) {
            tile.spawner.health--;
        }

        return true;
        // <<-- /Creer-Merge: harvest -->>
    },

    /**
     * Moves this beaver from its current tile to an adjacent tile.
     *
     * @param {Player} player - the player that called this.
     * @param {Tile} tile - The tile this beaver should move to. Costs 2 moves normally, 3 if moving upstream, and 1 if moving downstream.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if the move worked, false otherwise.
     */
    move: function(player, tile, asyncReturn) {
        // <<-- Creer-Merge: move -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's move function here
        return false;

        // <<-- /Creer-Merge: move -->>
    },

    /**
     * Picks up some branches or fish on the beaver's tile.
     *
     * @param {Player} player - the player that called this.
     * @param {string} resource - The type of resource to pickup ('branch' or 'fish').
     * @param {number} amount - The amount of the resource to drop, numbers <= 0 will pickup all of that type.
     * @param {function} asyncReturn - if you nest orders in this function you must return that value via this function in the order's callback.
     * @returns {boolean} True if successfully picked up a resource, false otherwise.
     */
    pickup: function(player, resource, amount, asyncReturn) {
        // <<-- Creer-Merge: pickup -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

        // Developer: Put your game logic for the Beaver's pickup function here
        return false;

        // <<-- /Creer-Merge: pickup -->>
    },

    //<<-- Creer-Merge: added-functions -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.

    // You can add additional functions here. These functions will not be directly callable by client AIs

    //<<-- /Creer-Merge: added-functions -->>

});

module.exports = Beaver;
<|endoftext|>


<commit_before>import ApplicationController from "./application_controller";
import axios from 'axios';
import {Collapse, Dropdown} from 'bootstrap';

export default class extends ApplicationController {
    /**
     *
     */
    initialize() {
        this.axios();
    }

    /**
     *
     */
    connect() {
        this.csrf();
        this.bootstrap();
    }

    /**
     * Initialization & configuration Turbo
     */
    turbo() {
        document.addEventListener('turbo:load', () => {
            this.csrf();
        });
    }

    /**
     * Creating an instance Axios
     */
    axios() {
        window.axios = axios;
    }

    /**
     * We'll load the axios HTTP library which allows us to easily issue requests
     * to our Laravel back-end. This library automatically handles sending the
     * CSRF token as a header based on the value of the "XSRF" token cookie.
     */
    csrf() {
        const token = document.head.querySelector('meta[name="csrf_token"]');

        if (!token) {
            return;
        }

        /**
         * Next we will register the CSRF Token as a common header with Axios so that
         * all outgoing HTTP requests automatically have it attached. This is just
         * a simple convenience so we don't have to attach every token manually.
         */
        window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
        window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
    }

    /**
     *
     */
    goToTop() {
        window.scrollTo({top: 0, behavior: 'smooth'});
    }

    /**
     *
     */
    bootstrap() {
        let dropdownElementList = [].slice.call(document.querySelectorAll('.dropdown-toggle'))
        let dropdownList = dropdownElementList.map(function (dropdownToggleEl) {
            return new Dropdown(dropdownToggleEl)
        })

        let collapseElementList = [].slice.call(document.querySelectorAll('.collapse'))
        let collapseList = collapseElementList.map(function (collapseEl) {
            return new Collapse(collapseEl)
        })
    }
}
<commit_msg>refs #1152 [Bootstrap] Changed collapse hidden default<commit_after>import ApplicationController from "./application_controller";
import axios from 'axios';
import {Collapse, Dropdown} from 'bootstrap';

export default class extends ApplicationController {
    /**
     *
     */
    initialize() {
        this.axios();
    }

    /**
     *
     */
    connect() {
        this.csrf();
        this.bootstrap();
    }

    /**
     * Initialization & configuration Turbo
     */
    turbo() {
        document.addEventListener('turbo:load', () => {
            this.csrf();
        });
    }

    /**
     * Creating an instance Axios
     */
    axios() {
        window.axios = axios;
    }

    /**
     * We'll load the axios HTTP library which allows us to easily issue requests
     * to our Laravel back-end. This library automatically handles sending the
     * CSRF token as a header based on the value of the "XSRF" token cookie.
     */
    csrf() {
        const token = document.head.querySelector('meta[name="csrf_token"]');

        if (!token) {
            return;
        }

        /**
         * Next we will register the CSRF Token as a common header with Axios so that
         * all outgoing HTTP requests automatically have it attached. This is just
         * a simple convenience so we don't have to attach every token manually.
         */
        window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
        window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
    }

    /**
     *
     */
    goToTop() {
        window.scrollTo({top: 0, behavior: 'smooth'});
    }

    /**
     *
     */
    bootstrap() {
        let dropdownElementList = [].slice.call(document.querySelectorAll('.dropdown-toggle'))
        let dropdownList = dropdownElementList.map(function (dropdownToggleEl) {
            return new Dropdown(dropdownToggleEl)
        })

        let collapseElementList = [].slice.call(document.querySelectorAll('.collapse'))
        let collapseList = collapseElementList.map(function (collapseEl) {
            return new Collapse(collapseEl, {
                toggle: false
            })
        })
    }
}
<|endoftext|>


<commit_before>// @flow

import React, { Component } from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import classnames from "classnames";
import actions from "../../actions";
import { getSelectedSource, getSymbols } from "../../selectors";
import { isEnabled } from "devtools-config";
import "./Outline.css";
import PreviewFunction from "../shared/PreviewFunction";

import type {
  SymbolDeclarations,
  SymbolDeclaration
} from "../../utils/parser/getSymbols";
import type { AstLocation } from "../../utils/parser/types";
import type { SourceRecord } from "../../reducers/sources";

export class Outline extends Component {
  state: any;

  props: {
    isHidden: boolean,
    symbols: SymbolDeclarations,
    selectSource: (string, { line: number }) => void,
    selectedSource: ?SourceRecord
  };

  selectItem(location: AstLocation) {
    const { selectedSource, selectSource } = this.props;
    if (!selectedSource) {
      return;
    }
    const selectedSourceId = selectedSource.get("id");
    const startLine = location.start.line;
    selectSource(selectedSourceId, { line: startLine });
  }

  renderPlaceholder() {
    return (

        { L10N.getStr("outline.noFunctions") }

    );
  }

  renderFunction(func: SymbolDeclaration) {
    const { name, location, parameterNames } = func;

    return (
      <li
        key={`${name}:${location.start.line}:${location.start.column}`}
        className="outline-list__element"
        onClick={() => this.selectItem(location)}
      >
        <PreviewFunction func={{ name, parameterNames }} />

    );
  }

  renderFunctions(symbols) {
    return (

        { symbols.map(func => this.renderFunction(func)) }

    );
  }

  render() {
    const { isHidden, symbols } = this.props;

    const symbolsToDisplay = symbols.functions
      .filter(func => func.name != "anonymous");

    return (

        { symbolsToDisplay.length >0 ? this.renderFunctions(symbolsToDisplay) : this.renderPlaceholder() }

    );
  }
}

Outline.displayName = "Outline";

export default connect(
  state => {
    const selectedSource = getSelectedSource(state);
    return {
      symbols: getSymbols(state, selectedSource && selectedSource.toJS()),
      selectedSource
    };
  },
  dispatch => bindActionCreators(actions, dispatch)
)(Outline);
<commit_msg>remove no longer used import<commit_after>// @flow

import React, { Component } from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import classnames from "classnames";
import actions from "../../actions";
import { getSelectedSource, getSymbols } from "../../selectors";
import "./Outline.css";
import PreviewFunction from "../shared/PreviewFunction";

import type {
  SymbolDeclarations,
  SymbolDeclaration
} from "../../utils/parser/getSymbols";
import type { AstLocation } from "../../utils/parser/types";
import type { SourceRecord } from "../../reducers/sources";

export class Outline extends Component {
  state: any;

  props: {
    isHidden: boolean,
    symbols: SymbolDeclarations,
    selectSource: (string, { line: number }) => void,
    selectedSource: ?SourceRecord
  };

  selectItem(location: AstLocation) {
    const { selectedSource, selectSource } = this.props;
    if (!selectedSource) {
      return;
    }
    const selectedSourceId = selectedSource.get("id");
    const startLine = location.start.line;
    selectSource(selectedSourceId, { line: startLine });
  }

  renderPlaceholder() {
    return (

        { L10N.getStr("outline.noFunctions") }

    );
  }

  renderFunction(func: SymbolDeclaration) {
    const { name, location, parameterNames } = func;

    return (
      <li
        key={`${name}:${location.start.line}:${location.start.column}`}
        className="outline-list__element"
        onClick={() => this.selectItem(location)}
      >
        <PreviewFunction func={{ name, parameterNames }} />

    );
  }

  renderFunctions(symbols) {
    return (

        { symbols.map(func => this.renderFunction(func)) }

    );
  }

  render() {
    const { isHidden, symbols } = this.props;

    const symbolsToDisplay = symbols.functions
      .filter(func => func.name != "anonymous");

    return (

        { symbolsToDisplay.length >0 ? this.renderFunctions(symbolsToDisplay) : this.renderPlaceholder() }

    );
  }
}

Outline.displayName = "Outline";

export default connect(
  state => {
    const selectedSource = getSelectedSource(state);
    return {
      symbols: getSymbols(state, selectedSource && selectedSource.toJS()),
      selectedSource
    };
  },
  dispatch => bindActionCreators(actions, dispatch)
)(Outline);
<|endoftext|>


<commit_before>Prism.languages.c = Prism.languages.extend('clike', {
	'keyword': /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
	'operator': /\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/,
	'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i
});

Prism.languages.insertBefore('c', 'string', {
	'macro': {
		// allow for multiline macro definitions
		// spaces after the # character compile fine with gcc
		pattern: /(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,
		lookbehind: true,
		alias: 'property',
		inside: {
			// highlight the path of the include statement as a string
			'string': {
				pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,
				lookbehind: true
			},
			// highlight macro directives as keywords
			'directive': {
				pattern: /(#\s*)\b(define|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,
				lookbehind: true,
				alias: 'keyword'
			}
		}
	},
	// highlight predefined macros as constants
	'constant': /\b(__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|stdin|stdout|stderr)\b/
});

delete Prism.languages.c['class-name'];
delete Prism.languages.c['boolean'];
<commit_msg>Add more keywords and constants for C.<commit_after>Prism.languages.c = Prism.languages.extend('clike', {
	'keyword': /\b(_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
	'operator': /\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/,
	'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i
});

Prism.languages.insertBefore('c', 'string', {
	'macro': {
		// allow for multiline macro definitions
		// spaces after the # character compile fine with gcc
		pattern: /(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,
		lookbehind: true,
		alias: 'property',
		inside: {
			// highlight the path of the include statement as a string
			'string': {
				pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,
				lookbehind: true
			},
			// highlight macro directives as keywords
			'directive': {
				pattern: /(#\s*)\b(define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,
				lookbehind: true,
				alias: 'keyword'
			}
		}
	},
	// highlight predefined macros as constants
	'constant': /\b(__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/
});

delete Prism.languages.c['class-name'];
delete Prism.languages.c['boolean'];
<|endoftext|>


<commit_before>/**
 * @file MOZTracker main script
 * @author Matt Schoen
 * @version 0.1
 *
 * @namespace moztrack
 */
var moztrack = moztrack || {};
(function(){
	var progress;

	var startDate = new Date(2015, 5, 26, 12);
	var endDate = new Date(2015, 7, 6, 19, 17);

	var episodeNum = 2659;

	var showStartDate = new Date(1999, 0, 11);
	var showEndDate = new Date(2015, 8, 6);

	var showTime, realTime;

	var perEpisode = 28;
	var perEpisodeOverride = 24;
	moztrack.startOverride = new Date(2015,5,26,0,0);

	$(document).ready(function() {
		//Setup local DB
		moztrack.db = openDatabase('moztrack', '0.1', 'Daily show episodes', 1*1024*1024);
		//moztrack.createLocalStorage();
		//Screw it, just reset every time
		moztrack.clearLocalStorage();

		//Create tracker
		var content = document.getElementById("moztrack-content");
		progress = Div();

		content.appendChild(Div({}, ["Stream started at " + startDate]));
		content.appendChild(Div({}, ["Stream ends at " + endDate]));
		content.appendChild(Div({}, [sprintf("Stream duration: %.2f hours", (endDate - startDate) / (60 * 60 * 1000))]));
		content.appendChild(Div({}, ["Episode count: " + episodeNum]));
		perEpisode = (endDate - startDate) / episodeNum;
		content.appendChild(Div({}, [sprintf("Computed %.2f minutes per episode", ((perEpisode / (60 * 1000))))]));
		content.appendChild(Div({}, ["Episode length overridden to: " + perEpisodeOverride]));
		var realEpCount = ((endDate - startDate) / (60 * 1000) / perEpisodeOverride);
		content.appendChild(Div({}, [sprintf("Actual stream length: %.2f episodes", realEpCount)]));
		content.appendChild(Div({}, [sprintf("Skipped about %.2f episodes", (episodeNum - realEpCount))]));
		var overDiff = (startDate - moztrack.startOverride) / (24 * 60 * 1000);
		content.appendChild(Div({}, [sprintf("Start time override: " + moztrack.startOverride + ", which means %.2f/180 skipped episodes so far", overDiff)]));

		showTime = Input({},[],{"onkeyup":function(){
			var date = new Date(this.value);
			moztrack.getRealTime(date);
		}});

		realTime = Input({},[],{"onkeyup":function(){
			var date = new Date(this.value);
			moztrack.getShowTime(date);
		}});

		content.appendChild(Div({"style":"margin-top:25px;"},[
			Div({},[
				"Show Time: ", showTime,
				" Real Time: ", realTime
			]),
			Elm("button", {"type":"button"}, ["Reset Local Storage"], {"onclick":moztrack.clearLocalStorage}),
			progress
		]));

		//start on a delay for the first load
		// setTimeout(function(){
			// realTime.value = new Date().format("Y-m-d H:i:s");
			// moztrack.getShowTime(new Date());
		// }, 1500);
	});
	moztrack.createLocalStorage = function(){
		//If table exists, assume we've done this before
		doIfTableNotExist(moztrack.db, "episodes", function(){
			moztrack.db.transaction(function(tx){
				tx.executeSql('CREATE TABLE IF NOT EXISTS "episodes" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "guest" VARCHAR, "date" DATETIME NOT NULL, "realtime" DATETIME NOT NULL );', [],
					function(tx, results){
						//TODO: non-blocking solution
						$.ajax({
							//Use absolute URL for local testing, Chrome blocks ajax requests to file:///
							"url":"http://mtschoen.github.io/month-of-zen-tracker/episodes/all.json",
							//"url":"http://mtschoen.github.io/month-of-zen-tracker/episodes/" + 1999 + ".json",
							//"url":"episodes/" + episodeLists[i] + ".json",
							"crossDomain":true,
							"async":false,
							"success":function(data){
								episodeNum = data.length - 1;	//-1 for sept11
								var perEpisode = (endDate - startDate) / episodeNum;

								perEpisode = perEpisodeOverride * 60 * 1000;
								var streamTime = 0;
								var query = "INSERT INTO episodes (guest,date,realtime) VALUES (?,?,?)";
								episodeNum = 0;
								console.log(moztrack.startOverride);
								for(var j in data){
									//Skip over the unaired sept11 episode
									if(data[j].extra == "sept11")
										continue;
									episodeNum++;
									data[j].date = new Date(data[j].date);

									progress.innerHTML = j;

									var realtime = moztrack.startOverride.getTime() + streamTime;
									tx.executeSql(query, [data[j].guest, data[j].date.getTime(), realtime],
										function(tx, results){

										},
										function(tx, error){
											console.log(error);
											console.log(query);
											console.log(data[j].guest, data[j].date.format("Y-m-d"));
											throw error;
										}
									);
									streamTime += perEpisode;
								}
							}
						});
					},
					function(tx, error){
						console.log(error);
						throw error;
					}
				);
			});
		});
	};
	moztrack.clearLocalStorage = function(){
		moztrack.db.transaction(function(tx){
			tx.executeSql("DROP TABLE IF EXISTS episodes;",[],
			function(){

			},
			function(tx, error){
				throw error;
			});
		});
		moztrack.createLocalStorage();
		setTimeout(function(){
			realTime.value = new Date().format("Y-m-d H:i:s");
			moztrack.getShowTime(new Date());
		}, 1000);
		ga('send', 'event', 'clearStorage');
	};

	function doIfTableNotExist(db, table, callback){
		db.transaction(function(tx){
			tx.executeSql("SELECT COUNT(*) FROM sqlite_master WHERE type = ? AND name = ?", ["table", table],
				function(tx, results){
					if(results.rows[0]["COUNT(*)"] == 0)
						callback();
				},
				function(tx, error){
					throw error;
				}
			);
		});
	}

	moztrack.getRealTime = function(date){
		if(date < showStartDate || date > showEndDate){
			console.log("Invalid show date: ", date, showStartDate);
			ga('send', 'event', 'getRealTimeInvalid', date.format("Y-m-d H:i:s"));
			return;
		}
		ga('send', 'event', 'getRealTime', date.format("Y-m-d"));
		ga('send', 'event', 'getRealTimeFull', date.format("Y-m-d H:i:s"));
		moztrack.db.transaction(function(tx){
			tx.executeSql("SELECT * FROM episodes WHERE date >= ? ORDER BY date LIMIT 1", [date.getTime()],
			function(tx, results){
				if(results.rows.length > 0){
					progress.innerHTML = "Guest: " + results.rows[0].guest + "";
					realTime.value = new Date(results.rows[0].realtime).format("Y-m-d H:i:s");
				} else {
					console.log("no results?");
				}
			},
			function(tx, error){
				console.log(error);
				throw error;
			});
		});
	};
	moztrack.getShowTime = function(date){
		if(date < startDate || date > endDate){
			console.log("Invalid real date");
			ga('send', 'event', 'getShowTimeInvalid', date.format("Y-m-d H:i:s"));
			return;
		}
		ga('send', 'event', 'getShowTimeFull', date.format("Y-m-d H:i:s"));
		moztrack.db.transaction(function(tx){
			tx.executeSql("SELECT * FROM episodes WHERE realtime <= ? ORDER BY date DESC LIMIT 1", [date.getTime()],
			function(tx, results){
				if(results.rows.length > 0){
					progress.innerHTML = "Guest: " + results.rows[0].guest + "";
					showTime.value = new Date(results.rows[0].date).format("Y-m-d");
				} else {
					console.log("no results?");
				}
			},
			function(tx, error){
				console.log(error);
				throw error;
			});
		});
	};
})();
<commit_msg>Update main.js<commit_after>/**
 * @file MOZTracker main script
 * @author Matt Schoen
 * @version 0.1
 *
 * @namespace moztrack
 */
var moztrack = moztrack || {};
(function(){
	var progress;

	var startDate = new Date(2015, 5, 26, 12);
	var endDate = new Date(2015, 7, 6, 19, 17);

	var episodeNum = 2659;

	var showStartDate = new Date(1999, 0, 11);
	var showEndDate = new Date(2015, 8, 6);

	var showTime, realTime;

	var perEpisode = 28;
	var perEpisodeOverride = 24;
	moztrack.startOverride = new Date(2015,5,25,20,36);

	$(document).ready(function() {
		//Setup local DB
		moztrack.db = openDatabase('moztrack', '0.1', 'Daily show episodes', 1*1024*1024);
		//moztrack.createLocalStorage();
		//Screw it, just reset every time
		moztrack.clearLocalStorage();

		//Create tracker
		var content = document.getElementById("moztrack-content");
		progress = Div();

		content.appendChild(Div({}, ["Stream started at " + startDate]));
		content.appendChild(Div({}, ["Stream ends at " + endDate]));
		content.appendChild(Div({}, [sprintf("Stream duration: %.2f hours", (endDate - startDate) / (60 * 60 * 1000))]));
		content.appendChild(Div({}, ["Episode count: " + episodeNum]));
		perEpisode = (endDate - startDate) / episodeNum;
		content.appendChild(Div({}, [sprintf("Computed %.2f minutes per episode", ((perEpisode / (60 * 1000))))]));
		content.appendChild(Div({}, ["Episode length overridden to: " + perEpisodeOverride]));
		var realEpCount = ((endDate - startDate) / (60 * 1000) / perEpisodeOverride);
		content.appendChild(Div({}, [sprintf("Actual stream length: %.2f episodes", realEpCount)]));
		content.appendChild(Div({}, [sprintf("Skipped about %.2f episodes", (episodeNum - realEpCount))]));
		var overDiff = (startDate - moztrack.startOverride) / (24 * 60 * 1000);
		content.appendChild(Div({}, [sprintf("Start time override: " + moztrack.startOverride + ", which means %.2f/180 skipped episodes so far", overDiff)]));

		showTime = Input({},[],{"onkeyup":function(){
			var date = new Date(this.value);
			moztrack.getRealTime(date);
		}});

		realTime = Input({},[],{"onkeyup":function(){
			var date = new Date(this.value);
			moztrack.getShowTime(date);
		}});

		content.appendChild(Div({"style":"margin-top:25px;"},[
			Div({},[
				"Show Time: ", showTime,
				" Real Time: ", realTime
			]),
			Elm("button", {"type":"button"}, ["Reset Local Storage"], {"onclick":moztrack.clearLocalStorage}),
			progress
		]));

		//start on a delay for the first load
		// setTimeout(function(){
			// realTime.value = new Date().format("Y-m-d H:i:s");
			// moztrack.getShowTime(new Date());
		// }, 1500);
	});
	moztrack.createLocalStorage = function(){
		//If table exists, assume we've done this before
		doIfTableNotExist(moztrack.db, "episodes", function(){
			moztrack.db.transaction(function(tx){
				tx.executeSql('CREATE TABLE IF NOT EXISTS "episodes" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE , "guest" VARCHAR, "date" DATETIME NOT NULL, "realtime" DATETIME NOT NULL );', [],
					function(tx, results){
						//TODO: non-blocking solution
						$.ajax({
							//Use absolute URL for local testing, Chrome blocks ajax requests to file:///
							"url":"http://mtschoen.github.io/month-of-zen-tracker/episodes/all.json",
							//"url":"http://mtschoen.github.io/month-of-zen-tracker/episodes/" + 1999 + ".json",
							//"url":"episodes/" + episodeLists[i] + ".json",
							"crossDomain":true,
							"async":false,
							"success":function(data){
								episodeNum = data.length - 1;	//-1 for sept11
								var perEpisode = (endDate - startDate) / episodeNum;

								perEpisode = perEpisodeOverride * 60 * 1000;
								var streamTime = 0;
								var query = "INSERT INTO episodes (guest,date,realtime) VALUES (?,?,?)";
								episodeNum = 0;
								console.log(moztrack.startOverride);
								for(var j in data){
									//Skip over the unaired sept11 episode
									if(data[j].extra == "sept11")
										continue;
									episodeNum++;
									data[j].date = new Date(data[j].date);

									progress.innerHTML = j;

									var realtime = moztrack.startOverride.getTime() + streamTime;
									tx.executeSql(query, [data[j].guest, data[j].date.getTime(), realtime],
										function(tx, results){

										},
										function(tx, error){
											console.log(error);
											console.log(query);
											console.log(data[j].guest, data[j].date.format("Y-m-d"));
											throw error;
										}
									);
									streamTime += perEpisode;
								}
							}
						});
					},
					function(tx, error){
						console.log(error);
						throw error;
					}
				);
			});
		});
	};
	moztrack.clearLocalStorage = function(){
		moztrack.db.transaction(function(tx){
			tx.executeSql("DROP TABLE IF EXISTS episodes;",[],
			function(){

			},
			function(tx, error){
				throw error;
			});
		});
		moztrack.createLocalStorage();
		setTimeout(function(){
			realTime.value = new Date().format("Y-m-d H:i:s");
			moztrack.getShowTime(new Date());
		}, 1000);
		ga('send', 'event', 'clearStorage');
	};

	function doIfTableNotExist(db, table, callback){
		db.transaction(function(tx){
			tx.executeSql("SELECT COUNT(*) FROM sqlite_master WHERE type = ? AND name = ?", ["table", table],
				function(tx, results){
					if(results.rows[0]["COUNT(*)"] == 0)
						callback();
				},
				function(tx, error){
					throw error;
				}
			);
		});
	}

	moztrack.getRealTime = function(date){
		if(date < showStartDate || date > showEndDate){
			console.log("Invalid show date: ", date, showStartDate);
			ga('send', 'event', 'getRealTimeInvalid', date.format("Y-m-d H:i:s"));
			return;
		}
		ga('send', 'event', 'getRealTime', date.format("Y-m-d"));
		ga('send', 'event', 'getRealTimeFull', date.format("Y-m-d H:i:s"));
		moztrack.db.transaction(function(tx){
			tx.executeSql("SELECT * FROM episodes WHERE date >= ? ORDER BY date LIMIT 1", [date.getTime()],
			function(tx, results){
				if(results.rows.length > 0){
					progress.innerHTML = "Guest: " + results.rows[0].guest + "";
					realTime.value = new Date(results.rows[0].realtime).format("Y-m-d H:i:s");
				} else {
					console.log("no results?");
				}
			},
			function(tx, error){
				console.log(error);
				throw error;
			});
		});
	};
	moztrack.getShowTime = function(date){
		if(date < startDate || date > endDate){
			console.log("Invalid real date");
			ga('send', 'event', 'getShowTimeInvalid', date.format("Y-m-d H:i:s"));
			return;
		}
		ga('send', 'event', 'getShowTimeFull', date.format("Y-m-d H:i:s"));
		moztrack.db.transaction(function(tx){
			tx.executeSql("SELECT * FROM episodes WHERE realtime <= ? ORDER BY date DESC LIMIT 1", [date.getTime()],
			function(tx, results){
				if(results.rows.length > 0){
					progress.innerHTML = "Guest: " + results.rows[0].guest + "";
					showTime.value = new Date(results.rows[0].date).format("Y-m-d");
				} else {
					console.log("no results?");
				}
			},
			function(tx, error){
				console.log(error);
				throw error;
			});
		});
	};
})();
<|endoftext|>


<commit_before>const React = require("react");
const { DOM: dom, PropTypes, createFactory } = React;
const { connect } = require("react-redux");
const { bindActionCreators } = require("redux");
const { isEnabled } = require("devtools-config");
const Svg = require("../shared/Svg");
const ImPropTypes = require("react-immutable-proptypes");

const { getPause, getBreakpoints,
        getBreakpointsDisabled, getBreakpointsLoading
      } = require("../../selectors");
const { prefs } = require("../../utils/prefs");

const actions = require("../../actions");

const WhyPaused = React.createFactory(require("./WhyPaused").default);
const Breakpoints = React.createFactory(require("./Breakpoints").default);

import _Expressions from "./Expressions";
const Expressions = React.createFactory(_Expressions.default);

const SplitBox = createFactory(require("devtools-modules").SplitBox);
const Scopes = isEnabled("chromeScopes")
  ? React.createFactory(require("./ChromeScopes").default)
  : React.createFactory(require("./Scopes").default);

const Frames = React.createFactory(require("./Frames").default);
const EventListeners = React.createFactory(require("./EventListeners").default);
const Accordion = React.createFactory(require("../shared/Accordion"));
const CommandBar = React.createFactory(require("./CommandBar").default);
require("./SecondaryPanes.css");

function debugBtn(onClick, type, className, tooltip) {
  className = `${type} ${className}`;
  return dom.button(
    { onClick, className, key: type, title: tooltip },
    Svg(type, { title: tooltip, "aria-label": tooltip })
  );
}

const SecondaryPanes = React.createClass({
  propTypes: {
    evaluateExpressions: PropTypes.func,
    pauseData: ImPropTypes.map,
    horizontal: PropTypes.bool,
    breakpoints: ImPropTypes.map,
    breakpointsDisabled: PropTypes.bool,
    breakpointsLoading: PropTypes.bool,
    toggleAllBreakpoints: PropTypes.func
  },

  contextTypes: {
    shortcuts: PropTypes.object
  },

  displayName: "SecondaryPanes",

  renderBreakpointsToggle() {
    const { toggleAllBreakpoints, breakpoints,
            breakpointsDisabled, breakpointsLoading } = this.props;
    const boxClassName = "breakpoints-toggle";
    const isIndeterminate = !breakpointsDisabled &&
      breakpoints.some(x => x.disabled);

    if (breakpoints.size == 0) {
      return null;
    }

    return dom.input({
      type: "checkbox",
      "aria-label": breakpointsDisabled ? L10N.getStr("breakpoints.enable") :
        L10N.getStr("breakpoints.disable"),
      className: boxClassName,
      disabled: breakpointsLoading,
      onClick: () => toggleAllBreakpoints(!breakpointsDisabled),
      checked: !breakpointsDisabled && !isIndeterminate,
      ref: (input) => {
        if (input) {
          input.indeterminate = isIndeterminate;
        }
      },
      title: breakpointsDisabled ? L10N.getStr("breakpoints.enable") :
        L10N.getStr("breakpoints.disable")
    });
  },

  watchExpressionHeaderButtons() {
    return [
      debugBtn(
        evt => {
          evt.stopPropagation();
          this.props.evaluateExpressions();
        },
        "refresh",
        "refresh",
        L10N.getStr("watchExpressions.refreshButton")
      )
    ];
  },

  getScopeItem() {
    const isPaused = () => !!this.props.pauseData;

    return {
      header: L10N.getStr("scopes.header"),
      component: Scopes,
      opened: prefs.scopesVisible,
      onToggle: opened => {
        prefs.scopesVisible = opened;
      },
      shouldOpen: isPaused
    };
  },

  getWatchItem() {
    return { header: L10N.getStr("watchExpressions.header"),
      buttons: this.watchExpressionHeaderButtons(),
      component: Expressions,
      opened: true
    };
  },

  getStartItems() {
    const scopesContent = this.props.horizontal ? this.getScopeItem() : null;
    const isPaused = () => !!this.props.pauseData;

    const items = [
      { header: L10N.getStr("breakpoints.header"),
        buttons: this.renderBreakpointsToggle(),
        component: Breakpoints,
        opened: true },
      { header: L10N.getStr("callStack.header"),
        component: Frames,
        opened: prefs.callStackVisible,
        onToggle: opened => {
          prefs.callStackVisible = opened;
        },
        shouldOpen: isPaused },
      scopesContent
    ];

    if (isEnabled("eventListeners")) {
      items.push({
        header: L10N.getStr("eventListenersHeader"),
        component: EventListeners
      });
    }

    if (isEnabled("watchExpressions") && this.props.horizontal) {
      items.unshift(this.getWatchItem());
    }

    return items.filter(item => item);
  },

  renderHorizontalLayout() {
    return Accordion({
      items: this.getItems()
    });
  },

  getEndItems() {
    const items = [];

    if (!this.props.horizontal) {
      items.unshift(this.getScopeItem());
    }

    if (isEnabled("watchExpressions") && !this.props.horizontal) {
      items.unshift(this.getWatchItem());
    }

    return items;
  },

  getItems() {
    return [...this.getStartItems(), ...this.getEndItems()];
  },

  renderVerticalLayout() {
    return SplitBox({
      style: { width: "100vw" },
      initialSize: "300px",
      minSize: 10,
      maxSize: "50%",
      splitterSize: 1,
      startPanel: Accordion({ items: this.getStartItems() }),
      endPanel: Accordion({ items: this.getEndItems() })
    });
  },

  render() {
    return dom.div(
      { className: "secondary-panes",
        style: { overflowX: "hidden" }},
      CommandBar(),
      WhyPaused(),
      this.props.horizontal ?
        this.renderHorizontalLayout() : this.renderVerticalLayout()
    );
  }
});

module.exports = connect(
  state => ({
    pauseData: getPause(state),
    breakpoints: getBreakpoints(state),
    breakpointsDisabled: getBreakpointsDisabled(state),
    breakpointsLoading: getBreakpointsLoading(state)
  }),
  dispatch => bindActionCreators(actions, dispatch)
)(SecondaryPanes);
<commit_msg>Fix import (#1900)<commit_after>const React = require("react");
const { DOM: dom, PropTypes, createFactory } = React;
const { connect } = require("react-redux");
const { bindActionCreators } = require("redux");
const { isEnabled } = require("devtools-config");
const Svg = require("../shared/Svg");
const ImPropTypes = require("react-immutable-proptypes");

const { getPause, getBreakpoints,
        getBreakpointsDisabled, getBreakpointsLoading
      } = require("../../selectors");
const { prefs } = require("../../utils/prefs");

const actions = require("../../actions");

const WhyPaused = React.createFactory(require("./WhyPaused").default);
const Breakpoints = React.createFactory(require("./Breakpoints").default);

import _Expressions from "./Expressions";
const Expressions = React.createFactory(_Expressions);

const SplitBox = createFactory(require("devtools-modules").SplitBox);
const Scopes = isEnabled("chromeScopes")
  ? React.createFactory(require("./ChromeScopes").default)
  : React.createFactory(require("./Scopes").default);

const Frames = React.createFactory(require("./Frames").default);
const EventListeners = React.createFactory(require("./EventListeners").default);
const Accordion = React.createFactory(require("../shared/Accordion"));
const CommandBar = React.createFactory(require("./CommandBar").default);
require("./SecondaryPanes.css");

function debugBtn(onClick, type, className, tooltip) {
  className = `${type} ${className}`;
  return dom.button(
    { onClick, className, key: type, title: tooltip },
    Svg(type, { title: tooltip, "aria-label": tooltip })
  );
}

const SecondaryPanes = React.createClass({
  propTypes: {
    evaluateExpressions: PropTypes.func,
    pauseData: ImPropTypes.map,
    horizontal: PropTypes.bool,
    breakpoints: ImPropTypes.map,
    breakpointsDisabled: PropTypes.bool,
    breakpointsLoading: PropTypes.bool,
    toggleAllBreakpoints: PropTypes.func
  },

  contextTypes: {
    shortcuts: PropTypes.object
  },

  displayName: "SecondaryPanes",

  renderBreakpointsToggle() {
    const { toggleAllBreakpoints, breakpoints,
            breakpointsDisabled, breakpointsLoading } = this.props;
    const boxClassName = "breakpoints-toggle";
    const isIndeterminate = !breakpointsDisabled &&
      breakpoints.some(x => x.disabled);

    if (breakpoints.size == 0) {
      return null;
    }

    return dom.input({
      type: "checkbox",
      "aria-label": breakpointsDisabled ? L10N.getStr("breakpoints.enable") :
        L10N.getStr("breakpoints.disable"),
      className: boxClassName,
      disabled: breakpointsLoading,
      onClick: () => toggleAllBreakpoints(!breakpointsDisabled),
      checked: !breakpointsDisabled && !isIndeterminate,
      ref: (input) => {
        if (input) {
          input.indeterminate = isIndeterminate;
        }
      },
      title: breakpointsDisabled ? L10N.getStr("breakpoints.enable") :
        L10N.getStr("breakpoints.disable")
    });
  },

  watchExpressionHeaderButtons() {
    return [
      debugBtn(
        evt => {
          evt.stopPropagation();
          this.props.evaluateExpressions();
        },
        "refresh",
        "refresh",
        L10N.getStr("watchExpressions.refreshButton")
      )
    ];
  },

  getScopeItem() {
    const isPaused = () => !!this.props.pauseData;

    return {
      header: L10N.getStr("scopes.header"),
      component: Scopes,
      opened: prefs.scopesVisible,
      onToggle: opened => {
        prefs.scopesVisible = opened;
      },
      shouldOpen: isPaused
    };
  },

  getWatchItem() {
    return { header: L10N.getStr("watchExpressions.header"),
      buttons: this.watchExpressionHeaderButtons(),
      component: Expressions,
      opened: true
    };
  },

  getStartItems() {
    const scopesContent = this.props.horizontal ? this.getScopeItem() : null;
    const isPaused = () => !!this.props.pauseData;

    const items = [
      { header: L10N.getStr("breakpoints.header"),
        buttons: this.renderBreakpointsToggle(),
        component: Breakpoints,
        opened: true },
      { header: L10N.getStr("callStack.header"),
        component: Frames,
        opened: prefs.callStackVisible,
        onToggle: opened => {
          prefs.callStackVisible = opened;
        },
        shouldOpen: isPaused },
      scopesContent
    ];

    if (isEnabled("eventListeners")) {
      items.push({
        header: L10N.getStr("eventListenersHeader"),
        component: EventListeners
      });
    }

    if (isEnabled("watchExpressions") && this.props.horizontal) {
      items.unshift(this.getWatchItem());
    }

    return items.filter(item => item);
  },

  renderHorizontalLayout() {
    return Accordion({
      items: this.getItems()
    });
  },

  getEndItems() {
    const items = [];

    if (!this.props.horizontal) {
      items.unshift(this.getScopeItem());
    }

    if (isEnabled("watchExpressions") && !this.props.horizontal) {
      items.unshift(this.getWatchItem());
    }

    return items;
  },

  getItems() {
    return [...this.getStartItems(), ...this.getEndItems()];
  },

  renderVerticalLayout() {
    return SplitBox({
      style: { width: "100vw" },
      initialSize: "300px",
      minSize: 10,
      maxSize: "50%",
      splitterSize: 1,
      startPanel: Accordion({ items: this.getStartItems() }),
      endPanel: Accordion({ items: this.getEndItems() })
    });
  },

  render() {
    return dom.div(
      { className: "secondary-panes",
        style: { overflowX: "hidden" }},
      CommandBar(),
      WhyPaused(),
      this.props.horizontal ?
        this.renderHorizontalLayout() : this.renderVerticalLayout()
    );
  }
});

module.exports = connect(
  state => ({
    pauseData: getPause(state),
    breakpoints: getBreakpoints(state),
    breakpointsDisabled: getBreakpointsDisabled(state),
    breakpointsLoading: getBreakpointsLoading(state)
  }),
  dispatch => bindActionCreators(actions, dispatch)
)(SecondaryPanes);
<|endoftext|>


<commit_before>function shuffle(input) {
  const array = [].concat(input);
  var currentIndex = array.length
    , temporaryValue
    , randomIndex
    ;
  // // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}

export const list = shuffle([
  {
    name: 'Cabela\'s (all over Canada)',
    link: 'http://www.cabelas.ca/',
    img: require('~/assets/cabelas-logo.png'),

  }, {
    name: 'Sail (ON + QC)',
    link: 'https://www.sail.ca/',
    img: require('~/assets/sail-logo.png'),

  }, {
    name: 'Firearms Outlet Canada (Ajax, ON)',
    link: 'http://www.firearmsoutletcanada.com/',
    img: require('~/assets/foc-logo.jpg'),

  }, {
    name: 'Al Flaherty\'s (Toronto, ON)',
    link: 'https://www.alflahertys.com/',
    img: require('~/assets/al-flahertys-logo.png'),

  }, {
    name: 'Bulls Eye London (London. ON)',
    link: 'http://www.bullseyelondon.com/',
    img: require('~/assets/bulls-logo.png'),

  }, {
    name: 'Canadian Tire (all over Canada)',
    link: 'http://www.canadiantire.ca/en/sports-rec/hunting/ammunition.html',
    img: require('~/assets/canadian-tire-logo.png'),

  }, {
    name: 'Reliable Gun (Vancouver, BC)',
    link: 'https://www.reliablegun.com/',
    img: require('~/assets/reliable-gun-logo.jpg'),

  },
  // { // disabled 2018-05-08
  //   name: 'Tenda (Richmond Hill, ON)',
  //   link: 'https://www.gotenda.com/',
  //   img: require('~/assets/tenda-logo.png'),
  // },
  {
    name: 'Canada Ammo  (BC and ON)',
    link: 'https://www.canadaammo.com/',
    img: require('~/assets/canada-ammo-logo.jpg'),

  }, {
    name: 'Wolverine Supplies (Virden, MB)',
    link: 'https://www.wolverinesupplies.com/',
    img: require('~/assets/wolverine-logo.png'),

  }, {
    name: 'Jo Brook Outdoors (Brandon, MB)',
    link: 'https://www.jobrookoutdoors.com/',
    img: require('~/assets/jo-brook-logo.png'),

  }, {
    name: 'The Ammo Source (Harrowsmith, ON)',
    link: 'http://www.theammosource.com/',
    img: require('~/assets/the-ammo-source-logo.png'),

  }, {
    name: 'Hirsch Precision (Lake Echo, NS)',
    link: 'http://www.hirschprecision.com/',
    img: require('~/assets/hirsch-logo.png'),

  }, {
    name: 'Wild West (Edmonton, AB)',
    link: 'https://gun-shop.ca/',
    img: require('~/assets/wild.png'),

  }, {
    name: 'Tiger Arms (Port Coquitlam, BC)',
    link: 'http://www.tigerarms.ca/',
    img: require('~/assets/tigerarms.png'),

    background: true,
  }, {
    name: 'Mag Dump (Sherwood Park, AB)',
    link: 'https://magdump.ca/',
    img: require('~/assets/magdump-logo.png'),

  },
  {
    name: 'Rangeview Sports (Newmarket, ON)',
    link: 'https://www.rangeviewsports.ca/',
    img: require('~/assets/rangeview-sports.png'),
  },
  {
    name: 'Trade Ex Canada (Hawkesbury, ON)',
    link: 'https://www.tradeexcanada.com/',
    img: require('~/assets/tradex-logo.png'),
  }, {
    name: 'Frontier Firearms (Prince Albert, SK)',
    link: 'http://frontierfirearms.ca/',
    img: require('~/assets/frontierfirearms-logo.png'),

  }, {
    name: 'BV Outdoor Essentials (Smithers, BC)',
    link: 'https://www.bvoutdoors.com/',
    img: require('~/assets/bvoutdoors-logo.png'),

  }, {
    name: 'NAS Guns & Ammo (Niagara and Sault Ste. Marie, ON)',
    link: 'https://www.nasgunsandammo.com/',
    img: require('~/assets/nas-logo.jpg'),

  }, {
    name: 'Dante Sports (Montréal QC)',
    link: 'https://www.dantesports.com/en/',
    img: require('~/assets/dante-logo.png'),

  },
  {
    name: 'Lever Arms (Vancouver, BC)',
    link: 'https://www.leverarms.com/',
    img: require('~/assets/leverarms-logo.png'),

  },
  {
    name: 'Calgary Shooting Center (Calgary, AB)',
    link: 'https://store.theshootingcentre.com/',
    img: require('~/assets/shooting-center-logo.jpg'),

  },
  {
    name: 'Western Metal (AB)',
    link: 'https://www.westernmetal.ca/shooting',
    img: require('~/assets/westernmetal-logo.png'),

  },
  {
    name: 'Al Simmons (Hamilton, ON)',
    link: 'https://alsimmonsgunshop.com/',
    img: require('~/assets/al-simmons-logo.jpg'),

  },
  {
    name: 'Vancouver Gun Store (Vancouver, BC)',
    link: 'https://vancouvergunstore.ca/',
    img: require('~/assets/vancouvergunstore-logo.png'),

  },
  {
    name: 'Bartons Big Country (Grande Prairie, AB)',
    link: 'https://www.bartonsbigcountry.ca/',
    img: require('~/assets/logo-bartons.png'),

  },
  {
    name: 'The Shooting Edge (Calgary, AB)',
    link: 'https://theshootingedge.com/',
    img: require('~/assets/shootingedge-logo.png'),

  },
  {
    name: 'Lanz Shooting Supplies (St Ann, ON)',
    link: 'http://www.lanzshootingsupplies.com/',
    img: require('~/assets/lanz-logo.png'),

  },
  {
    name: 'Duram Outdoors (Orono, ON)',
    link: 'https://durhamoutdoors.ca/',
    img: require('~/assets/duram-logo.png'),

  },
  {
    name: 'Soley Outdoors (Markham, ON)',
    link: 'https://www.solelyoutdoors.com/',
    img: require('~/assets/soley-logo.png'),
  },
  {
    name: 'North Pro Sports (Saskatoon, SK)',
    link: 'http://northprosports.com/',
    img: require('~/assets/northpro-logo.png'),
    background: true
  },
  {
    name: 'Wanstalls (Maple Ridge, BC)',
    link: 'https://www.wanstallsonline.com',
    img: require('~/assets/wanstalls.png')
  }
].map((i, index) => {
  i.link += '?utm_source=ammobin.ca'
  i.id = index;
  return i;
}));
<commit_msg>restored tenda<commit_after>function shuffle(input) {
  const array = [].concat(input);
  var currentIndex = array.length
    , temporaryValue
    , randomIndex
    ;
  // // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}

export const list = shuffle([
  {
    name: 'Cabela\'s (all over Canada)',
    link: 'http://www.cabelas.ca/',
    img: require('~/assets/cabelas-logo.png'),

  }, {
    name: 'Sail (ON + QC)',
    link: 'https://www.sail.ca/',
    img: require('~/assets/sail-logo.png'),

  }, {
    name: 'Firearms Outlet Canada (Ajax, ON)',
    link: 'http://www.firearmsoutletcanada.com/',
    img: require('~/assets/foc-logo.jpg'),

  }, {
    name: 'Al Flaherty\'s (Toronto, ON)',
    link: 'https://www.alflahertys.com/',
    img: require('~/assets/al-flahertys-logo.png'),

  }, {
    name: 'Bulls Eye London (London. ON)',
    link: 'http://www.bullseyelondon.com/',
    img: require('~/assets/bulls-logo.png'),

  }, {
    name: 'Canadian Tire (all over Canada)',
    link: 'http://www.canadiantire.ca/en/sports-rec/hunting/ammunition.html',
    img: require('~/assets/canadian-tire-logo.png'),

  }, {
    name: 'Reliable Gun (Vancouver, BC)',
    link: 'https://www.reliablegun.com/',
    img: require('~/assets/reliable-gun-logo.jpg'),

  },
   {
     name: 'Tenda (Richmond Hill, ON)',
     link: 'https://www.gotenda.com/',
     img: require('~/assets/tenda-logo.png'),
   },
  {
    name: 'Canada Ammo  (BC and ON)',
    link: 'https://www.canadaammo.com/',
    img: require('~/assets/canada-ammo-logo.jpg'),

  }, {
    name: 'Wolverine Supplies (Virden, MB)',
    link: 'https://www.wolverinesupplies.com/',
    img: require('~/assets/wolverine-logo.png'),

  }, {
    name: 'Jo Brook Outdoors (Brandon, MB)',
    link: 'https://www.jobrookoutdoors.com/',
    img: require('~/assets/jo-brook-logo.png'),

  }, {
    name: 'The Ammo Source (Harrowsmith, ON)',
    link: 'http://www.theammosource.com/',
    img: require('~/assets/the-ammo-source-logo.png'),

  }, {
    name: 'Hirsch Precision (Lake Echo, NS)',
    link: 'http://www.hirschprecision.com/',
    img: require('~/assets/hirsch-logo.png'),

  }, {
    name: 'Wild West (Edmonton, AB)',
    link: 'https://gun-shop.ca/',
    img: require('~/assets/wild.png'),

  }, {
    name: 'Tiger Arms (Port Coquitlam, BC)',
    link: 'http://www.tigerarms.ca/',
    img: require('~/assets/tigerarms.png'),

    background: true,
  }, {
    name: 'Mag Dump (Sherwood Park, AB)',
    link: 'https://magdump.ca/',
    img: require('~/assets/magdump-logo.png'),

  },
  {
    name: 'Rangeview Sports (Newmarket, ON)',
    link: 'https://www.rangeviewsports.ca/',
    img: require('~/assets/rangeview-sports.png'),
  },
  {
    name: 'Trade Ex Canada (Hawkesbury, ON)',
    link: 'https://www.tradeexcanada.com/',
    img: require('~/assets/tradex-logo.png'),
  }, {
    name: 'Frontier Firearms (Prince Albert, SK)',
    link: 'http://frontierfirearms.ca/',
    img: require('~/assets/frontierfirearms-logo.png'),

  }, {
    name: 'BV Outdoor Essentials (Smithers, BC)',
    link: 'https://www.bvoutdoors.com/',
    img: require('~/assets/bvoutdoors-logo.png'),

  }, {
    name: 'NAS Guns & Ammo (Niagara and Sault Ste. Marie, ON)',
    link: 'https://www.nasgunsandammo.com/',
    img: require('~/assets/nas-logo.jpg'),

  }, {
    name: 'Dante Sports (Montréal QC)',
    link: 'https://www.dantesports.com/en/',
    img: require('~/assets/dante-logo.png'),

  },
  {
    name: 'Lever Arms (Vancouver, BC)',
    link: 'https://www.leverarms.com/',
    img: require('~/assets/leverarms-logo.png'),

  },
  {
    name: 'Calgary Shooting Center (Calgary, AB)',
    link: 'https://store.theshootingcentre.com/',
    img: require('~/assets/shooting-center-logo.jpg'),

  },
  {
    name: 'Western Metal (AB)',
    link: 'https://www.westernmetal.ca/shooting',
    img: require('~/assets/westernmetal-logo.png'),

  },
  {
    name: 'Al Simmons (Hamilton, ON)',
    link: 'https://alsimmonsgunshop.com/',
    img: require('~/assets/al-simmons-logo.jpg'),

  },
  {
    name: 'Vancouver Gun Store (Vancouver, BC)',
    link: 'https://vancouvergunstore.ca/',
    img: require('~/assets/vancouvergunstore-logo.png'),

  },
  {
    name: 'Bartons Big Country (Grande Prairie, AB)',
    link: 'https://www.bartonsbigcountry.ca/',
    img: require('~/assets/logo-bartons.png'),

  },
  {
    name: 'The Shooting Edge (Calgary, AB)',
    link: 'https://theshootingedge.com/',
    img: require('~/assets/shootingedge-logo.png'),

  },
  {
    name: 'Lanz Shooting Supplies (St Ann, ON)',
    link: 'http://www.lanzshootingsupplies.com/',
    img: require('~/assets/lanz-logo.png'),

  },
  {
    name: 'Duram Outdoors (Orono, ON)',
    link: 'https://durhamoutdoors.ca/',
    img: require('~/assets/duram-logo.png'),

  },
  {
    name: 'Soley Outdoors (Markham, ON)',
    link: 'https://www.solelyoutdoors.com/',
    img: require('~/assets/soley-logo.png'),
  },
  {
    name: 'North Pro Sports (Saskatoon, SK)',
    link: 'http://northprosports.com/',
    img: require('~/assets/northpro-logo.png'),
    background: true
  },
  {
    name: 'Wanstalls (Maple Ridge, BC)',
    link: 'https://www.wanstallsonline.com',
    img: require('~/assets/wanstalls.png')
  }
].map((i, index) => {
  i.link += '?utm_source=ammobin.ca'
  i.id = index;
  return i;
}));
<|endoftext|>


<commit_before>var map;
var directionsService;
var bikingDirectionsDisplay;
var walkingDirectionsDisplay;

var cities = [
    { name: "Montréal",
      url: "bikeStations-montreal.xml"
    },
    { name: "Toronto",
      url: "bikeStations-toronto.xml"
    },
    { name: "Ottawa",
      url: "bikeStations-ottawa.xml"
    }
];

var bixiStations = [];
var locationMarker;

function updateCity(cityIndex) {
    var imageCanvas = document.createElement("canvas");
    var geocoder = new google.maps.Geocoder();

    var bixiBounds = new google.maps.LatLngBounds();
    var infoWindow = new google.maps.InfoWindow();
    google.maps.event.addListener(map, 'click', function() {
	infoWindow.close();
    });

    $.ajax({
        type: "GET",
	url: cities[cityIndex].url,
	dataType: "xml",
	success: function(xml) {
	    $(xml).find('station').each(function() {
		var station = {};
		station.name = $(this).find('name').text();
		station.id = $(this).find('terminalName').text();
		station.numBikes = parseInt($(this).find('nbBikes').text());
		station.numEmptyDocks = parseInt($(this).find('nbEmptyDocks').text());
		station.latlng = new google.maps.LatLng(parseFloat($(this).find('lat').text()),
							parseFloat($(this).find('long').text()));
		bixiStations[bixiStations.length] = station;

		function createIcon(numBikes, numEmptyDocks) {
		    var radius;
		    var alpha;
		    if (numBikes == 0 && numEmptyDocks == 0) {
			// edge case: station with nothing in it
			radius = 5;
			alpha = 0.0;
		    } else {
			radius = (numBikes+numEmptyDocks)/2;
			if (radius > 20) {
			    radius = 20;
			} else if (radius < 5) {
			    radius = 5;
			}

			alpha = numBikes / (numBikes+numEmptyDocks);
			if (alpha > 0.5 && alpha < 1.0) {
			    alpha=0.5;
			} else if (alpha < 0.1 && alpha > 0.0) {
			    alpha = 0.1;
			}
		    }
		    imageCanvas.width = radius*2+4;
		    imageCanvas.height = radius*2+4;
		    var context = imageCanvas.getContext("2d");

		    context.clearRect(0,0,radius*2, radius*2);

		    context.fillStyle = "rgba(255,0,0," + alpha + ")";
		    context.beginPath();
		    context.arc(imageCanvas.width/2,imageCanvas.height/2,radius,0,Math.PI*2,true);
		    context.fill();

		    context.strokeStyle = "#f00";
		    context.beginPath();
		    context.arc(imageCanvas.width/2,imageCanvas.height/2,radius,0,Math.PI*2,true);
		    context.stroke();

		    return imageCanvas.toDataURL();

		}
		var iconURL = createIcon(station.numBikes, station.numEmptyDocks);

		bixiBounds.extend(station.latlng);

		station.marker = new google.maps.Marker({
		    position: station.latlng,
		    map: map,
		    icon: iconURL
		});

		google.maps.event.addListener(station.marker, 'click', function() {
		    infoWindow.setContent("" + station.name +
					  "
Bikes: " +
					  station.numBikes + ' - ' +
					  "Docks: " + station.numEmptyDocks);
		    infoWindow.open(map, station.marker);
		});

	    });

	    $("form#nearby-form").submit(function() {
		$("#nearby-input").blur();
		walkingDirectionsDisplay.setMap(null);

		var oldFindButtonVal = $("#find-nearby-button").val();

		$("#find-nearby-button").attr('disabled', 'disabled');
		$("#find-nearby-button").val("Working...");
		geocoder.geocode( {'address': $("#nearby-input").val(), 'bounds': bixiBounds }, function(results, status) {
		    $("#find-nearby-button").val(oldFindButtonVal);
		    $("#find-nearby-button").removeAttr('disabled');

		    var nearbyHTML = "";

		    if (results.length > 0) {
			var latlng = results[0].geometry.location;
			locationMarker.setPosition(latlng);
			locationMarker.setVisible(true);
			map.setCenter(latlng);
			map.setZoom(15);

			var nearby_stations = bixiStations.map(function(station) {
			    var distance = google.maps.geometry.spherical.computeDistanceBetween(latlng,
												 station.latlng);
			    return jQuery.extend({ distance: parseInt(distance) }, station);
			}).filter(function(station) {
			    return station.distance < 1000;
			}).sort(function(station1, station2) {
			    return station1.distance > station2.distance;
			}).slice(0,5);

			$('#nearby-content').replaceWith(ich.stations({
			    location: results[0].formatted_address,
			    stations: nearby_stations }));

			nearby_stations.map(function(station) {
			    $('#station-' + station.id).hover(function() {
				$(this).addClass("nearby-station-hover");
			    }, function() {
				$(this).removeClass("nearby-station-hover");
			    }).click(function() {
				$('.nearby-station').removeClass("nearby-station-selected");
				$(this).addClass("nearby-station-selected");
				directionsService.route({
				    origin: latlng,
				    destination: station.latlng,
				    travelMode: google.maps.DirectionsTravelMode.WALKING
				}, function(response, status) {
				    if (status == google.maps.DirectionsStatus.OK) {
					locationMarker.setVisible(false);
					walkingDirectionsDisplay.setDirections(response);
					walkingDirectionsDisplay.setMap(map);
				    } else {
					console.log("Error processing directions to station!");
				    }
				});

			    });

			    // Create pie chart

			    if (station.numBikes == 0 && station.numEmptyDocks == 0) {
				return;
			    }
			    console.log(station.numBikes + "-" + station.numEmptyDocks);
			    var data = {
				items: []
			    };

			    if (station.numBikes > 0) {
				data.items[data.items.length] = {label: 'bikes', data: station.numBikes };
			    } else {
			    }
			    if (station.numEmptyDocks > 0) {
				data.items[data.items.length] = {label: 'stations', data: station.numEmptyDocks };
			    }

			    var pieChart = new Bluff.Pie('station-graph-' + station.id, '40x40');
			    if (station.numBikes == 0) {
				pieChart.set_theme({
				    colors: ['#fbb' ],
				    background_colors: ['rgba(0,0,0,0)', 'rgba(0,0,0,0)']
				});
			    } else {
				pieChart.set_theme({
				    colors: ['#f00', '#fbb' ],
				    background_colors: ['rgba(0,0,0,0)', 'rgba(0,0,0,0)']
				});
			    }

			    pieChart.hide_labels_less_than = 100;
			    pieChart.hide_legend = true;
			    for (i in data.items) {
				var item = data.items[i];
				pieChart.data(item.label, item.data);
			    }

			    pieChart.draw();
			});
		    }
		});

		return false;
	    });

	    var autocomplete = {
		//This bit uses the geocoder to fetch address values
		source: function(request, response) {
		    geocoder.geocode( {'address': request.term, 'bounds': bixiBounds }, function(results, status) {
			response($.map(results, function(item) {
			    return {
				label: item.formatted_address,
				value: item.formatted_address,
			    }
			}));
		    })},
	    }

	    $("#nearby-input").autocomplete(autocomplete);
	    $("#from-input").autocomplete(autocomplete);
	    $("#to-input").autocomplete(autocomplete);

	    $('#map_canvas').show();
	    google.maps.event.trigger(map, "resize");
	    map.fitBounds(bixiBounds);
	}
    });
}

function init() {
    for (var i in cities) {
	$("#city-selector").append('<option value= ' + i + '>' + cities[i].name + '</option>');
    }

    map = new google.maps.Map(document.getElementById("map_canvas"), {
	zoom: 1,
	mapTypeId: google.maps.MapTypeId.ROADMAP,
	center: new google.maps.LatLng(45.64, -73.4)
    });
    var bikeLayer = new google.maps.BicyclingLayer();
    bikeLayer.setMap(map);

    $('body').layout({ defaults: { spacing_open: 0 },
                       applyDefaultStyles: true,
                       west: { size: 320 },
                       north: { innerHeight: 30 },
                       center: { onresize_end: function () { google.maps.event.trigger(map, "resize"); } } });

    bikingDirectionsDisplay = new google.maps.DirectionsRenderer({ map: map });
    walkingDirectionsDisplay = new google.maps.DirectionsRenderer({ markerOptions: {
	zIndex: google.maps.Marker.MAX_ZINDEX } });
    directionsService = new google.maps.DirectionsService();

    locationMarker = new google.maps.Marker({
	map: map,
	visible: false
    });

    $("#find-nearby-button").button();
    $("#plan-button").button();
    $("form#directions-form").submit(function() {
	$('#error-widget').hide();
	$('#from-input').blur();
	$('#to-input').blur();

	var oldPlanButtonVal = $("#plan-button").val();

	$("#plan-button").attr('disabled', 'disabled');
	$("#plan-button").val("Working...");

	var request = {
            origin: $("#from-input").val(),
            destination: $("#to-input").val(),
            travelMode: google.maps.DirectionsTravelMode.BICYCLING
	};

	directionsService.route(request, function(response, status) {
	    $("#plan-button").removeAttr('disabled');
	    $("#plan-button").val(oldPlanButtonVal);

	    if (status == google.maps.DirectionsStatus.OK) {
		bikingDirectionsDisplay.setDirections(response);
	    } else {
		$('#error-widget').show();
		console.log("Error processing directions!");
	    }
	});

	return false;
    });

    $("#tab-selector").buttonset();
    $('input#trip-planner').click(function()  {
	$('div#nearby-panel').hide();
	$('div#trip-planner-panel').show();
    });

    $('input#find-nearby').click(function() {
	$('div#nearby-panel').show();
	$('div#trip-planner-panel').hide();
    });

    $("#reverse-button").button({
	text: false,
	icons: {
	    primary: 'ui-icon-shuffle'
	}
    }).click(function() {
	var fromval = $("#from-input").val();
	$("#from-input").val($("#to-input").val());
	$("#to-input").val(fromval);
    });

    $("#city-selector").change(function() {
	var cityIndex = $("#city-selector").val();
	updateCity(cityIndex);
	localStorage["defaultCityIndex"] = cityIndex;
    });

    // get city preference from user and update to it. you might think it
    // would make sense to use geolocation for this, but that's actually
    // kinda slow at least with Firefox
    var cityIndex = localStorage["defaultCityIndex"];
    if (cityIndex == undefined) {
	cityIndex = 0;
    }

    updateCity(parseInt(cityIndex)); // set city to default
}
<commit_msg>Ottawa BIXI's website is "capital"<commit_after>var map;
var directionsService;
var bikingDirectionsDisplay;
var walkingDirectionsDisplay;

var cities = [
    { name: "Montréal",
      url: "bikeStations-montreal.xml"
    },
    { name: "Toronto",
      url: "bikeStations-toronto.xml"
    },
    { name: "Ottawa",
      url: "bikeStations-capital.xml"
    }
];

var bixiStations = [];
var locationMarker;

function updateCity(cityIndex) {
    var imageCanvas = document.createElement("canvas");
    var geocoder = new google.maps.Geocoder();

    var bixiBounds = new google.maps.LatLngBounds();
    var infoWindow = new google.maps.InfoWindow();
    google.maps.event.addListener(map, 'click', function() {
	infoWindow.close();
    });

    $.ajax({
        type: "GET",
	url: cities[cityIndex].url,
	dataType: "xml",
	success: function(xml) {
	    $(xml).find('station').each(function() {
		var station = {};
		station.name = $(this).find('name').text();
		station.id = $(this).find('terminalName').text();
		station.numBikes = parseInt($(this).find('nbBikes').text());
		station.numEmptyDocks = parseInt($(this).find('nbEmptyDocks').text());
		station.latlng = new google.maps.LatLng(parseFloat($(this).find('lat').text()),
							parseFloat($(this).find('long').text()));
		bixiStations[bixiStations.length] = station;

		function createIcon(numBikes, numEmptyDocks) {
		    var radius;
		    var alpha;
		    if (numBikes == 0 && numEmptyDocks == 0) {
			// edge case: station with nothing in it
			radius = 5;
			alpha = 0.0;
		    } else {
			radius = (numBikes+numEmptyDocks)/2;
			if (radius > 20) {
			    radius = 20;
			} else if (radius < 5) {
			    radius = 5;
			}

			alpha = numBikes / (numBikes+numEmptyDocks);
			if (alpha > 0.5 && alpha < 1.0) {
			    alpha=0.5;
			} else if (alpha < 0.1 && alpha > 0.0) {
			    alpha = 0.1;
			}
		    }
		    imageCanvas.width = radius*2+4;
		    imageCanvas.height = radius*2+4;
		    var context = imageCanvas.getContext("2d");

		    context.clearRect(0,0,radius*2, radius*2);

		    context.fillStyle = "rgba(255,0,0," + alpha + ")";
		    context.beginPath();
		    context.arc(imageCanvas.width/2,imageCanvas.height/2,radius,0,Math.PI*2,true);
		    context.fill();

		    context.strokeStyle = "#f00";
		    context.beginPath();
		    context.arc(imageCanvas.width/2,imageCanvas.height/2,radius,0,Math.PI*2,true);
		    context.stroke();

		    return imageCanvas.toDataURL();

		}
		var iconURL = createIcon(station.numBikes, station.numEmptyDocks);

		bixiBounds.extend(station.latlng);

		station.marker = new google.maps.Marker({
		    position: station.latlng,
		    map: map,
		    icon: iconURL
		});

		google.maps.event.addListener(station.marker, 'click', function() {
		    infoWindow.setContent("" + station.name +
					  "
Bikes: " +
					  station.numBikes + ' - ' +
					  "Docks: " + station.numEmptyDocks);
		    infoWindow.open(map, station.marker);
		});

	    });

	    $("form#nearby-form").submit(function() {
		$("#nearby-input").blur();
		walkingDirectionsDisplay.setMap(null);

		var oldFindButtonVal = $("#find-nearby-button").val();

		$("#find-nearby-button").attr('disabled', 'disabled');
		$("#find-nearby-button").val("Working...");
		geocoder.geocode( {'address': $("#nearby-input").val(), 'bounds': bixiBounds }, function(results, status) {
		    $("#find-nearby-button").val(oldFindButtonVal);
		    $("#find-nearby-button").removeAttr('disabled');

		    var nearbyHTML = "";

		    if (results.length > 0) {
			var latlng = results[0].geometry.location;
			locationMarker.setPosition(latlng);
			locationMarker.setVisible(true);
			map.setCenter(latlng);
			map.setZoom(15);

			var nearby_stations = bixiStations.map(function(station) {
			    var distance = google.maps.geometry.spherical.computeDistanceBetween(latlng,
												 station.latlng);
			    return jQuery.extend({ distance: parseInt(distance) }, station);
			}).filter(function(station) {
			    return station.distance < 1000;
			}).sort(function(station1, station2) {
			    return station1.distance > station2.distance;
			}).slice(0,5);

			$('#nearby-content').replaceWith(ich.stations({
			    location: results[0].formatted_address,
			    stations: nearby_stations }));

			nearby_stations.map(function(station) {
			    $('#station-' + station.id).hover(function() {
				$(this).addClass("nearby-station-hover");
			    }, function() {
				$(this).removeClass("nearby-station-hover");
			    }).click(function() {
				$('.nearby-station').removeClass("nearby-station-selected");
				$(this).addClass("nearby-station-selected");
				directionsService.route({
				    origin: latlng,
				    destination: station.latlng,
				    travelMode: google.maps.DirectionsTravelMode.WALKING
				}, function(response, status) {
				    if (status == google.maps.DirectionsStatus.OK) {
					locationMarker.setVisible(false);
					walkingDirectionsDisplay.setDirections(response);
					walkingDirectionsDisplay.setMap(map);
				    } else {
					console.log("Error processing directions to station!");
				    }
				});

			    });

			    // Create pie chart

			    if (station.numBikes == 0 && station.numEmptyDocks == 0) {
				return;
			    }
			    console.log(station.numBikes + "-" + station.numEmptyDocks);
			    var data = {
				items: []
			    };

			    if (station.numBikes > 0) {
				data.items[data.items.length] = {label: 'bikes', data: station.numBikes };
			    } else {
			    }
			    if (station.numEmptyDocks > 0) {
				data.items[data.items.length] = {label: 'stations', data: station.numEmptyDocks };
			    }

			    var pieChart = new Bluff.Pie('station-graph-' + station.id, '40x40');
			    if (station.numBikes == 0) {
				pieChart.set_theme({
				    colors: ['#fbb' ],
				    background_colors: ['rgba(0,0,0,0)', 'rgba(0,0,0,0)']
				});
			    } else {
				pieChart.set_theme({
				    colors: ['#f00', '#fbb' ],
				    background_colors: ['rgba(0,0,0,0)', 'rgba(0,0,0,0)']
				});
			    }

			    pieChart.hide_labels_less_than = 100;
			    pieChart.hide_legend = true;
			    for (i in data.items) {
				var item = data.items[i];
				pieChart.data(item.label, item.data);
			    }

			    pieChart.draw();
			});
		    }
		});

		return false;
	    });

	    var autocomplete = {
		//This bit uses the geocoder to fetch address values
		source: function(request, response) {
		    geocoder.geocode( {'address': request.term, 'bounds': bixiBounds }, function(results, status) {
			response($.map(results, function(item) {
			    return {
				label: item.formatted_address,
				value: item.formatted_address,
			    }
			}));
		    })},
	    }

	    $("#nearby-input").autocomplete(autocomplete);
	    $("#from-input").autocomplete(autocomplete);
	    $("#to-input").autocomplete(autocomplete);

	    $('#map_canvas').show();
	    google.maps.event.trigger(map, "resize");
	    map.fitBounds(bixiBounds);
	}
    });
}

function init() {
    for (var i in cities) {
	$("#city-selector").append('<option value= ' + i + '>' + cities[i].name + '</option>');
    }

    map = new google.maps.Map(document.getElementById("map_canvas"), {
	zoom: 1,
	mapTypeId: google.maps.MapTypeId.ROADMAP,
	center: new google.maps.LatLng(45.64, -73.4)
    });
    var bikeLayer = new google.maps.BicyclingLayer();
    bikeLayer.setMap(map);

    $('body').layout({ defaults: { spacing_open: 0 },
                       applyDefaultStyles: true,
                       west: { size: 320 },
                       north: { innerHeight: 30 },
                       center: { onresize_end: function () { google.maps.event.trigger(map, "resize"); } } });

    bikingDirectionsDisplay = new google.maps.DirectionsRenderer({ map: map });
    walkingDirectionsDisplay = new google.maps.DirectionsRenderer({ markerOptions: {
	zIndex: google.maps.Marker.MAX_ZINDEX } });
    directionsService = new google.maps.DirectionsService();

    locationMarker = new google.maps.Marker({
	map: map,
	visible: false
    });

    $("#find-nearby-button").button();
    $("#plan-button").button();
    $("form#directions-form").submit(function() {
	$('#error-widget').hide();
	$('#from-input').blur();
	$('#to-input').blur();

	var oldPlanButtonVal = $("#plan-button").val();

	$("#plan-button").attr('disabled', 'disabled');
	$("#plan-button").val("Working...");

	var request = {
            origin: $("#from-input").val(),
            destination: $("#to-input").val(),
            travelMode: google.maps.DirectionsTravelMode.BICYCLING
	};

	directionsService.route(request, function(response, status) {
	    $("#plan-button").removeAttr('disabled');
	    $("#plan-button").val(oldPlanButtonVal);

	    if (status == google.maps.DirectionsStatus.OK) {
		bikingDirectionsDisplay.setDirections(response);
	    } else {
		$('#error-widget').show();
		console.log("Error processing directions!");
	    }
	});

	return false;
    });

    $("#tab-selector").buttonset();
    $('input#trip-planner').click(function()  {
	$('div#nearby-panel').hide();
	$('div#trip-planner-panel').show();
    });

    $('input#find-nearby').click(function() {
	$('div#nearby-panel').show();
	$('div#trip-planner-panel').hide();
    });

    $("#reverse-button").button({
	text: false,
	icons: {
	    primary: 'ui-icon-shuffle'
	}
    }).click(function() {
	var fromval = $("#from-input").val();
	$("#from-input").val($("#to-input").val());
	$("#to-input").val(fromval);
    });

    $("#city-selector").change(function() {
	var cityIndex = $("#city-selector").val();
	updateCity(cityIndex);
	localStorage["defaultCityIndex"] = cityIndex;
    });

    // get city preference from user and update to it. you might think it
    // would make sense to use geolocation for this, but that's actually
    // kinda slow at least with Firefox
    var cityIndex = localStorage["defaultCityIndex"];
    if (cityIndex == undefined) {
	cityIndex = 0;
    }

    updateCity(parseInt(cityIndex)); // set city to default
}
<|endoftext|>


<commit_before>/* eslint-disable no-undef, no-underscore-dangle */

import React from 'react'
import PropTypes from 'prop-types'
import { intlShape } from 'react-intl'
import { Icon, Menu } from 'semantic-ui-react'
import { Query, Mutation } from 'react-apollo'
import Router from 'next/router'

import { AccountSummaryQuery, LogoutMutation } from '../../../graphql'

import AccountArea from './AccountArea'
import SearchArea from './SearchArea'
import SessionArea from './SessionArea'

const propTypes = {
  // filters: PropTypes.object,
  handleSidebarToggle: PropTypes.func.isRequired,
  intl: intlShape.isRequired,
  search: PropTypes.shape({
    handleSearch: PropTypes.func.isRequired,
    handleSortByChange: PropTypes.func.isRequired,
    handleSortOrderToggle: PropTypes.func.isRequired,
    sortBy: PropTypes.string.isRequired,
    sortingTypes: PropTypes.arrayOf(
      PropTypes.shape({
        content: PropTypes.string,
        id: PropTypes.string,
        labelStart: PropTypes.string,
      }),
    ).isRequired,
    sortOrder: PropTypes.bool.isRequired,
  }),
  sidebarVisible: PropTypes.bool,
  title: PropTypes.string.isRequired,
}

const defaultProps = {
  search: undefined,
  sidebarVisible: false,
}

export const NavbarPres = ({
  intl, search, sidebarVisible, title, handleSidebarToggle,
}) => (

      <Menu borderless className="noBorder">
        <Menu.Item
          icon
          active={sidebarVisible}
          className="sidebar"
          name="sidebar"
          onClick={handleSidebarToggle}
        >
          <Icon name="sidebar" />
        </Menu.Item>

{title}

      </Menu>

    {search && (

        <SearchArea
          handleSearch={search.handleSearch}
          handleSortByChange={search.handleSortByChange}
          handleSortOrderToggle={search.handleSortOrderToggle}
          intl={intl}
          sortBy={search.sortBy}
          sortOrder={search.sortOrder}
          sortingTypes={search.sortingTypes}
          withSorting={search.withSorting}
        />

    )}

      <Query query={AccountSummaryQuery}>
        {({ data }) => {
          const accountId = data.user?.id
          const userEmail = data.user?.email
          const accountShort = data.user?.shortname
          const runningSessionId = data.user?.runningSession?.id

          if (typeof window !== 'undefined') {
            if (window.INIT_LR) {
              const LogRocket = require('logrocket')
              LogRocket.identify(accountId, {
                email: userEmail,
                name: accountShort,
              })
            }

            if (typeof window._chatlio !== 'undefined') {
              window._chatlio.identify(accountId, {
                email: userEmail,
                name: accountShort,
              })
            }

            if (window.INIT_RAVEN) {
              const Raven = require('raven-js')
              Raven.identify(accountId, {
                name: accountShort,
              })
            }
          }

          return (
            <Menu borderless className="loginArea noBorder">
              <Menu.Menu position="right">
                {accountShort && <SessionArea intl={intl} sessionId={runningSessionId} />}

                <Mutation mutation={LogoutMutation}>
                  {logout => (
                    <AccountArea
                      accountShort={accountShort}
                      onLogout={async () => {
                        // logout
                        await logout()

                        // redirect to the landing page
                        Router.push('/')
                      }}
                    />
                  )}
                </Mutation>
              </Menu.Menu>
            </Menu>
          )
        }}
      </Query>

)

NavbarPres.propTypes = propTypes
NavbarPres.defaultProps = defaultProps

export default NavbarPres
<commit_msg>(fix) try/catch for all .identify functions<commit_after>/* eslint-disable no-undef, no-underscore-dangle */

import React from 'react'
import PropTypes from 'prop-types'
import { intlShape } from 'react-intl'
import { Icon, Menu } from 'semantic-ui-react'
import { Query, Mutation } from 'react-apollo'
import Router from 'next/router'

import { AccountSummaryQuery, LogoutMutation } from '../../../graphql'

import AccountArea from './AccountArea'
import SearchArea from './SearchArea'
import SessionArea from './SessionArea'

const propTypes = {
  // filters: PropTypes.object,
  handleSidebarToggle: PropTypes.func.isRequired,
  intl: intlShape.isRequired,
  search: PropTypes.shape({
    handleSearch: PropTypes.func.isRequired,
    handleSortByChange: PropTypes.func.isRequired,
    handleSortOrderToggle: PropTypes.func.isRequired,
    sortBy: PropTypes.string.isRequired,
    sortingTypes: PropTypes.arrayOf(
      PropTypes.shape({
        content: PropTypes.string,
        id: PropTypes.string,
        labelStart: PropTypes.string,
      }),
    ).isRequired,
    sortOrder: PropTypes.bool.isRequired,
  }),
  sidebarVisible: PropTypes.bool,
  title: PropTypes.string.isRequired,
}

const defaultProps = {
  search: undefined,
  sidebarVisible: false,
}

export const NavbarPres = ({
  intl, search, sidebarVisible, title, handleSidebarToggle,
}) => (

      <Menu borderless className="noBorder">
        <Menu.Item
          icon
          active={sidebarVisible}
          className="sidebar"
          name="sidebar"
          onClick={handleSidebarToggle}
        >
          <Icon name="sidebar" />
        </Menu.Item>

{title}

      </Menu>

    {search && (

        <SearchArea
          handleSearch={search.handleSearch}
          handleSortByChange={search.handleSortByChange}
          handleSortOrderToggle={search.handleSortOrderToggle}
          intl={intl}
          sortBy={search.sortBy}
          sortOrder={search.sortOrder}
          sortingTypes={search.sortingTypes}
          withSorting={search.withSorting}
        />

    )}

      <Query query={AccountSummaryQuery}>
        {({ data }) => {
          const accountId = data.user?.id
          const userEmail = data.user?.email
          const accountShort = data.user?.shortname
          const runningSessionId = data.user?.runningSession?.id

          if (typeof window !== 'undefined') {
            if (window.INIT_LR) {
              try {
                const LogRocket = require('logrocket')

                LogRocket.identify(accountId, {
                  email: userEmail,
                  name: accountShort,
                })
              } catch (e) {
                //
              }
            }

            if (typeof window._chatlio !== 'undefined') {
              try {
                window._chatlio.identify(accountId, {
                  email: userEmail,
                  name: accountShort,
                })
              } catch (e) {
                //
              }
            }

            if (window.INIT_RAVEN) {
              try {
                const Raven = require('raven-js')
                Raven.identify(accountId, {
                  name: accountShort,
                })
              } catch (e) {
                //
              }
            }
          }

          return (
            <Menu borderless className="loginArea noBorder">
              <Menu.Menu position="right">
                {accountShort && <SessionArea intl={intl} sessionId={runningSessionId} />}

                <Mutation mutation={LogoutMutation}>
                  {logout => (
                    <AccountArea
                      accountShort={accountShort}
                      onLogout={async () => {
                        // logout
                        await logout()

                        // redirect to the landing page
                        Router.push('/')
                      }}
                    />
                  )}
                </Mutation>
              </Menu.Menu>
            </Menu>
          )
        }}
      </Query>

)

NavbarPres.propTypes = propTypes
NavbarPres.defaultProps = defaultProps

export default NavbarPres
<|endoftext|>