<commit_before>angular.module('rnacentralApp').controller('GenoverseGenomeBrowser', ['$scope', '$location', function($scope, $location) {

    /* Constructor */

    $scope.browser = {};
    $scope.browser.genome = genome;
    $scope.browser.chromosome = chromosome;
    $scope.browser.start = start;
    $scope.browser.end = end;

    // handle form submit button
    $('#genome-display').on('click', showGenome);

    // handle copy to clipboard button
    new Clipboard('#copy-genome-location', {
        "text": function() {
            return document.location.href;
        }
    });

    showGenome();

    // Listen to global browser object.
    // Note: third argument (true) means that we require objectEquality, not just referentialEquality
    $scope.$watch(browser, function(newValue, oldValue, scope) { scope.browser = newValue; }, true);

    /* Method definitions */

    /**
     * Show genome location using Genoverse.
     * Create a hidden button with data attributes and trigger the click event.
     * Update coordinates in the user interface.
     */
    function showGenome() {
        // delete previous instance of browser completely
        $('.genoverse-xref').remove();
        delete window.browser;

        // get species name with whitespaces replaced with hyphens, handle dog as a special case
        var species = $scope.browser.genome.species;
        if (species == 'Canis familiaris') { species = 'Canis lupus familiaris'; }
        species = species.replace(/ /g,'_').toLowerCase();

        // set all data attributes and initialize plugin by clicking invisible button
        $('<button class="genoverse-xref"></button>').
            hide().
            appendTo('.genoverse-wrap').
            data('chromosome', $scope.chromosome).
            data('genomic-start', $scope.start).
            data('genomic-end', $scope.end).
            data('strand', 1).
            data('species', species).
            data('description', '').
            data('species-label', $scope.browser.genome.species).
            click(); // this initializes plugin
    }

    /**
    * Show Ensembl and UCSC links for the currently displayed region.
    */
    function updateExternalLinks(){
        var option = species.find('option:selected'),
            division = option.data('division'),
            ucsc_db = option.data('ucsc-db'),
            ucsc = $('.ucsc-link'),
            domain = '',
            ucsc_chr = '',
            url = '';

        if (division == 'Ensembl') {
            domain = 'http://ensembl.org/';
        } else if (division == 'Ensembl Plants') {
            domain = 'http://plants.ensembl.org/';
        } else if (division == 'Ensembl Metazoa') {
            domain = 'http://metazoa.ensembl.org/';
        } else if (division == 'Ensembl Bacteria') {
            domain = 'http://bacteria.ensembl.org/';
        } else if (division == 'Ensembl Fungi') {
            domain = 'http://fungi.ensembl.org/';
        } else if (division == 'Ensembl Protists') {
            domain = 'http://protists.ensembl.org/';
        }

        // update Ensembl link
        url = domain + species.val().replace(/ /g,'_') + '/Location/View?r=' + browser.chr + ':' + browser.start + '-' + browser.end;
        $('#ensembl-link').attr('href', url).text(division);

        // update UCSC link if UCSC assembly is available
        if (ucsc_db) {
            if (browser.chr.match(/^\d+$|^[XY]$/)) {
                ucsc_chr = 'chr' + browser.chr;
            }
            else {
                ucsc_chr = browser.chr;
            }
            url = 'http://genome.ucsc.edu/cgi-bin/hgTracks?db='+ ucsc_db +'&position=' + ucsc_chr + '%3A' + browser.start + '-' + browser.end;
            ucsc.show().find('a').attr('href', url);
        }
        else {
            ucsc.hide();
        }
    }

    /**
     * Synchronize coordinates in Genoverse, in address bar, in form inputs and in the text line
     * above genoverse genome browser.
     *
     * We need to find out, which one was actually changed by the user since last run and modify
     * the others.
     */
    function updateCoordinates() {
        // update form start/end inputs
        start.val(browser.start);
        end.val(browser.end);

        // update location string right above genoverse
        var species = $('#genomic-species-select');
        text = '' + species.val() + '' + ' ' + browser.chr + ':' + browser.start + '-' + browser.end;
        if ($('#genomic-location').html() != text) {
            $('#genomic-location').html(text);
        }

        // update get param in browser, if they changed
        var searchParams = "chromosome=" + browser.chr;
        searchParams = searchParams.concat("&start=" + browser.start);
        searchParams = searchParams.concat("&end=" + browser.end);

        if (document.location.search != searchParams) {
            history.pushState({}, document.title, document.location.pathname + "?" + searchParams);
        }

        // update url if species changed
        var species = species.val().replace(/ /g,'-');

        var pathname = document.location.pathname;
        var hasTrailingSlash = false;
        if (document.location.pathname.substr(-1) === '/') {
            hasTrailingSlash = true;
            pathname = document.location.pathname.substr(0, document.location.pathname.length - 1);
        }

        if (document.location.pathname.search(/genome-browser\/.+/) == -1) { // if url is like genome-browser/smth.
            var newPathname = pathname + "/" + species;
            if (hasTrailingSlash) { newPathname = newPathname + "/"; }
            history.pushState({}, document.title, newPathname + "?" + searchParams);
        }
        else { // if url is like /genome-browser/homo-sapiens
            var pathElements = pathname.split("/");
            var urlBeginning = pathElements.slice(0, pathElements.length-1);
            var urlEnding = pathElements.slice(-1)[0];

            if (urlEnding != species) {
                urlBeginning.push(species);
                var newPathname = urlBeginning.join("/");
                if (hasTrailingSlash) { newPathname = newPathname + "/"; }
                history.pushState({}, document.title, newPathname + "?" + searchParams);
            }
        }
    }
}]);<commit_msg> #94 Added a license and IIFE to keep johnpapa happy.<commit_after>/*
Copyright [2009-2017] EMBL-European Bioinformatics Institute
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

(function() {

angular.module('rnacentralApp').controller('GenoverseGenomeBrowser', ['$scope', '$location', function ($scope, $location) {

    /* Constructor */

    $scope.browser = {};
    $scope.browser.genome = genome;
    $scope.browser.chromosome = chromosome;
    $scope.browser.start = start;
    $scope.browser.end = end;

    // handle form submit button
    $('#genome-display').on('click', showGenome);

    // handle copy to clipboard button
    new Clipboard('#copy-genome-location', {
        "text": function () {
            return document.location.href;
        }
    });

    showGenome();

    // Listen to global browser object.
    // Note: third argument (true) means that we require objectEquality, not just referentialEquality
    $scope.$watch(browser, function (newValue, oldValue, scope) { scope.browser = newValue; }, true);

    /* Method definitions */

    /**
     * Show genome location using Genoverse.
     * Create a hidden button with data attributes and trigger the click event.
     * Update coordinates in the user interface.
     */
    function showGenome() {
        // delete previous instance of browser completely
        $('.genoverse-xref').remove();
        delete window.browser;

        // get species name with whitespaces replaced with hyphens, handle dog as a special case
        var species = $scope.browser.genome.species;
        if (species == 'Canis familiaris') { species = 'Canis lupus familiaris'; }
        species = species.replace(/ /g, '_').toLowerCase();

        // set all data attributes and initialize plugin by clicking invisible button
        $('<button class="genoverse-xref"></button>').hide().appendTo('.genoverse-wrap').data('chromosome', $scope.chromosome).data('genomic-start', $scope.start).data('genomic-end', $scope.end).data('strand', 1).data('species', species).data('description', '').data('species-label', $scope.browser.genome.species).click(); // this initializes plugin
    }

    /**
     * Show Ensembl and UCSC links for the currently displayed region.
     */
    function updateExternalLinks() {
        var option = species.find('option:selected'),
            division = option.data('division'),
            ucsc_db = option.data('ucsc-db'),
            ucsc = $('.ucsc-link'),
            domain = '',
            ucsc_chr = '',
            url = '';

        if (division == 'Ensembl') {
            domain = 'http://ensembl.org/';
        } else if (division == 'Ensembl Plants') {
            domain = 'http://plants.ensembl.org/';
        } else if (division == 'Ensembl Metazoa') {
            domain = 'http://metazoa.ensembl.org/';
        } else if (division == 'Ensembl Bacteria') {
            domain = 'http://bacteria.ensembl.org/';
        } else if (division == 'Ensembl Fungi') {
            domain = 'http://fungi.ensembl.org/';
        } else if (division == 'Ensembl Protists') {
            domain = 'http://protists.ensembl.org/';
        }

        // update Ensembl link
        url = domain + species.val().replace(/ /g, '_') + '/Location/View?r=' + browser.chr + ':' + browser.start + '-' + browser.end;
        $('#ensembl-link').attr('href', url).text(division);

        // update UCSC link if UCSC assembly is available
        if (ucsc_db) {
            if (browser.chr.match(/^\d+$|^[XY]$/)) {
                ucsc_chr = 'chr' + browser.chr;
            }
            else {
                ucsc_chr = browser.chr;
            }
            url = 'http://genome.ucsc.edu/cgi-bin/hgTracks?db=' + ucsc_db + '&position=' + ucsc_chr + '%3A' + browser.start + '-' + browser.end;
            ucsc.show().find('a').attr('href', url);
        }
        else {
            ucsc.hide();
        }
    }

    /**
     * Synchronize coordinates in Genoverse, in address bar, in form inputs and in the text line
     * above genoverse genome browser.
     *
     * We need to find out, which one was actually changed by the user since last run and modify
     * the others.
     */
    function updateCoordinates() {
        // update form start/end inputs
        start.val(browser.start);
        end.val(browser.end);

        // update location string right above genoverse
        var species = $('#genomic-species-select');
        text = '' + species.val() + '' + ' ' + browser.chr + ':' + browser.start + '-' + browser.end;
        if ($('#genomic-location').html() != text) {
            $('#genomic-location').html(text);
        }

        // update get param in browser, if they changed
        var searchParams = "chromosome=" + browser.chr;
        searchParams = searchParams.concat("&start=" + browser.start);
        searchParams = searchParams.concat("&end=" + browser.end);

        if (document.location.search != searchParams) {
            history.pushState({}, document.title, document.location.pathname + "?" + searchParams);
        }

        // update url if species changed
        var species = species.val().replace(/ /g, '-');

        var pathname = document.location.pathname;
        var hasTrailingSlash = false;
        if (document.location.pathname.substr(-1) === '/') {
            hasTrailingSlash = true;
            pathname = document.location.pathname.substr(0, document.location.pathname.length - 1);
        }

        if (document.location.pathname.search(/genome-browser\/.+/) == -1) { // if url is like genome-browser/smth.
            var newPathname = pathname + "/" + species;
            if (hasTrailingSlash) { newPathname = newPathname + "/"; }
            history.pushState({}, document.title, newPathname + "?" + searchParams);
        }
        else { // if url is like /genome-browser/homo-sapiens
            var pathElements = pathname.split("/");
            var urlBeginning = pathElements.slice(0, pathElements.length - 1);
            var urlEnding = pathElements.slice(-1)[0];

            if (urlEnding != species) {
                urlBeginning.push(species);
                var newPathname = urlBeginning.join("/");
                if (hasTrailingSlash) {
                    newPathname = newPathname + "/";
                }
                history.pushState({}, document.title, newPathname + "?" + searchParams);
            }
        }
    }
}]);

})();<|endoftext|>


<commit_before>let trackThrottle;

import API from 'src/util/api';
import _ from 'lodash';

export default function trackMove(action) {
  if (!trackThrottle) {
    trackThrottle = _.throttle((action) => {
      generateTrackAnnotations(action);
    }, 100);
  }
  trackThrottle(action);
}

function generateTrackAnnotations(action) {
  const trackMove = action.value.data;
  const preferences = API.getData('preferences').resurrect();
  if (!API.getData('chart')) return;
  const chart = API.getData('chart').resurrect();
  const spectrumIDs = chart.series.map((serie) => serie.id);
  if (
    !preferences.display ||
    !preferences.display.trackingInfo ||
    !trackMove ||
    Object.keys(trackMove).length === 0
  ) {
    API.createData('trackAnnotations', []);
    return;
  }
  const selectedSpectra = API.getData('selectedSpectra');
  const analysesManager = API.cache('analysesManager');

  let data;
  if (analysesManager.getAnalysisBySpectrumId) {
    function getColor(spectrumId) {
      const analysis = analysesManager.getAnalysisBySpectrumId(spectrumId);
      if (!analysis) return;
      // selectedSpectra is actually selectedAnalyses
      const currentSpectrum = selectedSpectra.filter(
        (spectrum) => spectrum.id === analysis.id,
      );
      if (currentSpectrum.length === 0) return;
      return currentSpectrum[0].color;
    }

    function getLabel(spectrumId) {
      const analysis = analysesManager.getAnalysisBySpectrumId(spectrumId);
      if (!analysis) return;
      console.log(analysis);
      return analysis.label;
    }

    // we will get the index for all the charts
    let keys = Object.keys(trackMove);
    data = new Array(keys.length);
    for (let key of keys) {
      let index = Number(key.replace(/chart-?/, '') || 0);
      let spectrumId = spectrumIDs[index];
      data[index] = {
        x: trackMove[key].xClosest,
        y: trackMove[key].yClosest,
        color: getColor(spectrumId),
        label: getLabel(spectrumId),
        spectrum: analysesManager.getSpectrumById(spectrumId),
      };
    }
  } else {
    let ids = selectedSpectra
      .filter((entry) => DataObject.resurrect(entry.display))
      .map((entry) => String(entry.id));
    let colors = selectedSpectra
      .filter((entry) => DataObject.resurrect(entry.display))
      .map((entry) => String(entry.color));
    const spectra = API.cache('analysesManager').getAnalyses({ ids });
    // we will get the index for all the charts
    let keys = Object.keys(trackMove);
    data = new Array(keys.length);
    for (let key of keys) {
      let index = Number(key.replace(/chart-?/, '') || 0);
      data[index] = {
        x: trackMove[key].xClosest,
        y: trackMove[key].yClosest,
        color: colors[index],
        label: spectra[index].label,
        spectrum: spectra[index],
      };
    }
  }

  let trackAnnotations = getTrackAnnotations(data);
  API.createData('trackAnnotations', trackAnnotations);

  function getTrackAnnotations(data, options = {}) {
    const { showSpectrumID = true, startX = 300 } = options;
    let annotations = [];

    let line = 0;

    if (isNaN(data[0].x)) return;
    annotations.push({
      type: 'line',
      position: [
        { x: `${startX}px`, y: `${15 + 15 * line}px` },
        { x: `${startX + 15}px`, y: `${15 + 15 * line}px` },
      ],
      strokeWidth: 0.0000001,
      label: {
        size: 16,
        text: `x: ${data[0].x.toPrecision(6)}`,
        position: { x: `${startX + 60}px`, y: `${20 + 15 * line}px` },
      },
    });
    line++;

    for (let datum of data) {
      if (isNaN(datum.y)) continue;
      annotations.push({
        type: 'line',
        position: [
          { x: `${startX}px`, y: `${15 + 15 * line}px` },
          { x: `${startX + 15}px`, y: `${15 + 15 * line}px` },
        ],
        strokeColor: datum.color,
        strokeWidth: 2,
        label: {
          text: `${datum.y.toPrecision(4)}${
            showSpectrumID ? ` - ${datum.label}` : ''
          }`,
          position: { x: `${startX + 20}px`, y: `${20 + 15 * line}px` },
        },
      });
      line++;
    }

    return annotations;
  }
}
<commit_msg>chore: remove console.log<commit_after>let trackThrottle;

import API from 'src/util/api';
import _ from 'lodash';

export default function trackMove(action) {
  if (!trackThrottle) {
    trackThrottle = _.throttle((action) => {
      generateTrackAnnotations(action);
    }, 100);
  }
  trackThrottle(action);
}

function generateTrackAnnotations(action) {
  const trackMove = action.value.data;
  const preferences = API.getData('preferences').resurrect();
  if (!API.getData('chart')) return;
  const chart = API.getData('chart').resurrect();
  const spectrumIDs = chart.series.map((serie) => serie.id);
  if (
    !preferences.display ||
    !preferences.display.trackingInfo ||
    !trackMove ||
    Object.keys(trackMove).length === 0
  ) {
    API.createData('trackAnnotations', []);
    return;
  }
  const selectedSpectra = API.getData('selectedSpectra');
  const analysesManager = API.cache('analysesManager');

  let data;
  if (analysesManager.getAnalysisBySpectrumId) {
    function getColor(spectrumId) {
      const analysis = analysesManager.getAnalysisBySpectrumId(spectrumId);
      if (!analysis) return;
      // selectedSpectra is actually selectedAnalyses
      const currentSpectrum = selectedSpectra.filter(
        (spectrum) => spectrum.id === analysis.id,
      );
      if (currentSpectrum.length === 0) return;
      return currentSpectrum[0].color;
    }

    function getLabel(spectrumId) {
      const analysis = analysesManager.getAnalysisBySpectrumId(spectrumId);
      if (!analysis) return;
      return analysis.label;
    }

    // we will get the index for all the charts
    let keys = Object.keys(trackMove);
    data = new Array(keys.length);
    for (let key of keys) {
      let index = Number(key.replace(/chart-?/, '') || 0);
      let spectrumId = spectrumIDs[index];
      data[index] = {
        x: trackMove[key].xClosest,
        y: trackMove[key].yClosest,
        color: getColor(spectrumId),
        label: getLabel(spectrumId),
        spectrum: analysesManager.getSpectrumById(spectrumId),
      };
    }
  } else {
    let ids = selectedSpectra
      .filter((entry) => DataObject.resurrect(entry.display))
      .map((entry) => String(entry.id));
    let colors = selectedSpectra
      .filter((entry) => DataObject.resurrect(entry.display))
      .map((entry) => String(entry.color));
    const spectra = API.cache('analysesManager').getAnalyses({ ids });
    // we will get the index for all the charts
    let keys = Object.keys(trackMove);
    data = new Array(keys.length);
    for (let key of keys) {
      let index = Number(key.replace(/chart-?/, '') || 0);
      data[index] = {
        x: trackMove[key].xClosest,
        y: trackMove[key].yClosest,
        color: colors[index],
        label: spectra[index].label,
        spectrum: spectra[index],
      };
    }
  }

  let trackAnnotations = getTrackAnnotations(data);
  API.createData('trackAnnotations', trackAnnotations);

  function getTrackAnnotations(data, options = {}) {
    const { showSpectrumID = true, startX = 300 } = options;
    let annotations = [];

    let line = 0;

    if (isNaN(data[0].x)) return;
    annotations.push({
      type: 'line',
      position: [
        { x: `${startX}px`, y: `${15 + 15 * line}px` },
        { x: `${startX + 15}px`, y: `${15 + 15 * line}px` },
      ],
      strokeWidth: 0.0000001,
      label: {
        size: 16,
        text: `x: ${data[0].x.toPrecision(6)}`,
        position: { x: `${startX + 60}px`, y: `${20 + 15 * line}px` },
      },
    });
    line++;

    for (let datum of data) {
      if (isNaN(datum.y)) continue;
      annotations.push({
        type: 'line',
        position: [
          { x: `${startX}px`, y: `${15 + 15 * line}px` },
          { x: `${startX + 15}px`, y: `${15 + 15 * line}px` },
        ],
        strokeColor: datum.color,
        strokeWidth: 2,
        label: {
          text: `${datum.y.toPrecision(4)}${
            showSpectrumID ? ` - ${datum.label}` : ''
          }`,
          position: { x: `${startX + 20}px`, y: `${20 + 15 * line}px` },
        },
      });
      line++;
    }

    return annotations;
  }
}
<|endoftext|>


<commit_before>module.exports = {
  title: 'Foal TS',
  tagline: 'Node.JS and TypeScript framework for building web applications',
  url: 'https://foalts.github.io',
  baseUrl: '/foal/',
  onBrokenLinks: 'throw',
  onBrokenMarkdownLinks: 'warn',
  favicon: 'img/logo_400.png',
  organizationName: 'FoalTS', // Usually your GitHub org/user name.
  projectName: 'foal', // Usually your repo name.
  themeConfig: {
    image: 'img/logo_400.png',
    googleAnalytics: {
      trackingID: 'UA-112613053-1',
      anonymizeIP: true,
    },
    hideableSidebar: true,
    announcementBar: {
      id: 'supportus',
      content:
        '⭐ Foal TS version 2 has been released! 🎉',
    },
    navbar: {
      title: 'Foal TS',
      style: 'dark',
      hideOnScroll: true,
      logo: {
        alt: 'Foal TS Logo',
        src: 'img/logo_400.png',
      },
      items: [
        {
          to: 'docs/',
          activeBasePath: 'docs',
          label: 'Docs',
          position: 'left',
        },
        {
          to: 'blog',
          label: 'Blog',
          position: 'left'
        },
        {
          href: 'https://github.com/FoalTS/foal',
          position: 'right',
          className: 'header-github-link',
          'aria-label': 'GitHub repository',
        },
        {
          href: 'https://twitter.com/FoalTs',
          position: 'right',
          className: 'header-twitter-link',
          'aria-label': 'Twitter profile',
        },
        {
          href: 'https://www.youtube.com/channel/UCQFojM334E0YdoDq56MjfOQ',
          position: 'right',
          className: 'header-youtube-link',
          'aria-label': 'Youtube channel',
        },
        {
          href: 'https://discord.gg/QUrJv98',
          position: 'right',
          className: 'header-chat-link',
          'aria-label': 'Discord chat server',
        },
        {
          type: 'docsVersionDropdown',
          position: 'right',
          dropdownActiveClassDisabled: true,
        },
      ],
    },
    // footer: {
    //   style: 'dark',
    //   links: [
    //     {
    //       title: 'Docs',
    //       items: [
    //         {
    //           label: 'Style Guide',
    //           to: 'docs/',
    //         },
    //         {
    //           label: 'Second Doc',
    //           to: 'docs/doc2/',
    //         },
    //       ],
    //     },
    //     {
    //       title: 'Community',
    //       items: [
    //         {
    //           label: 'Stack Overflow',
    //           href: 'https://stackoverflow.com/questions/tagged/docusaurus',
    //         },
    //         {
    //           label: 'Discord',
    //           href: 'https://discordapp.com/invite/docusaurus',
    //         },
    //         {
    //           label: 'Twitter',
    //           href: 'https://twitter.com/docusaurus',
    //         },
    //       ],
    //     },
    //     {
    //       title: 'More',
    //       items: [
    //         {
    //           label: 'Blog',
    //           to: 'blog',
    //         },
    //         {
    //           label: 'GitHub',
    //           href: 'https://github.com/facebook/docusaurus',
    //         },
    //       ],
    //     },
    //   ],
    //   copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`,
    // },
  },
  plugins: [
    'docusaurus-plugin-sass',
  ],
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        docs: {
          sidebarPath: require.resolve('./sidebars.js'),
          editUrl:
            'https://github.com/FoalTS/foal/edit/master/docs/',
          lastVersion: "current",
          versions: {
            current: {
              "label": require('../lerna.json').version + ' (latest)',
            },
            '1.x': {
              'label': '1.x'
            }
          }
        },
        blog: {
          showReadingTime: true,
          editUrl:
            'https://github.com/FoalTS/foal/edit/master/docs',
        },
        theme: {
          customCss: require.resolve('./src/css/custom.scss'),
        },
      },
    ],
  ],
};
<commit_msg>Use only one color theme<commit_after>module.exports = {
  title: 'Foal TS',
  tagline: 'Node.JS and TypeScript framework for building web applications',
  url: 'https://foalts.github.io',
  baseUrl: '/foal/',
  onBrokenLinks: 'throw',
  onBrokenMarkdownLinks: 'warn',
  favicon: 'img/logo_400.png',
  organizationName: 'FoalTS', // Usually your GitHub org/user name.
  projectName: 'foal', // Usually your repo name.
  themeConfig: {
    image: 'img/logo_400.png',
    googleAnalytics: {
      trackingID: 'UA-112613053-1',
      anonymizeIP: true,
    },
    hideableSidebar: true,
    announcementBar: {
      id: 'supportus',
      content:
        '⭐ Foal TS version 2 has been released! 🎉',
    },
    colorMode: {
      defaultMode: 'light',
      disableSwitch: true,
      respectPrefersColorScheme: false,
    },
    navbar: {
      title: 'Foal TS',
      style: 'dark',
      hideOnScroll: true,
      logo: {
        alt: 'Foal TS Logo',
        src: 'img/logo_400.png',
      },
      items: [
        {
          to: 'docs/',
          activeBasePath: 'docs',
          label: 'Docs',
          position: 'left',
        },
        {
          to: 'blog',
          label: 'Blog',
          position: 'left'
        },
        {
          href: 'https://github.com/FoalTS/foal',
          position: 'right',
          className: 'header-github-link',
          'aria-label': 'GitHub repository',
        },
        {
          href: 'https://twitter.com/FoalTs',
          position: 'right',
          className: 'header-twitter-link',
          'aria-label': 'Twitter profile',
        },
        {
          href: 'https://www.youtube.com/channel/UCQFojM334E0YdoDq56MjfOQ',
          position: 'right',
          className: 'header-youtube-link',
          'aria-label': 'Youtube channel',
        },
        {
          href: 'https://discord.gg/QUrJv98',
          position: 'right',
          className: 'header-chat-link',
          'aria-label': 'Discord chat server',
        },
        {
          type: 'docsVersionDropdown',
          position: 'right',
          dropdownActiveClassDisabled: true,
        },
      ],
    },
    // footer: {
    //   style: 'dark',
    //   links: [
    //     {
    //       title: 'Docs',
    //       items: [
    //         {
    //           label: 'Style Guide',
    //           to: 'docs/',
    //         },
    //         {
    //           label: 'Second Doc',
    //           to: 'docs/doc2/',
    //         },
    //       ],
    //     },
    //     {
    //       title: 'Community',
    //       items: [
    //         {
    //           label: 'Stack Overflow',
    //           href: 'https://stackoverflow.com/questions/tagged/docusaurus',
    //         },
    //         {
    //           label: 'Discord',
    //           href: 'https://discordapp.com/invite/docusaurus',
    //         },
    //         {
    //           label: 'Twitter',
    //           href: 'https://twitter.com/docusaurus',
    //         },
    //       ],
    //     },
    //     {
    //       title: 'More',
    //       items: [
    //         {
    //           label: 'Blog',
    //           to: 'blog',
    //         },
    //         {
    //           label: 'GitHub',
    //           href: 'https://github.com/facebook/docusaurus',
    //         },
    //       ],
    //     },
    //   ],
    //   copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`,
    // },
  },
  plugins: [
    'docusaurus-plugin-sass',
  ],
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        docs: {
          sidebarPath: require.resolve('./sidebars.js'),
          editUrl:
            'https://github.com/FoalTS/foal/edit/master/docs/',
          lastVersion: "current",
          versions: {
            current: {
              "label": require('../lerna.json').version + ' (latest)',
            },
            '1.x': {
              'label': '1.x'
            }
          }
        },
        blog: {
          showReadingTime: true,
          editUrl:
            'https://github.com/FoalTS/foal/edit/master/docs',
        },
        theme: {
          customCss: require.resolve('./src/css/custom.scss'),
        },
      },
    ],
  ],
};
<|endoftext|>


<commit_before>/* jshint newcap: false */
import Promise from "./promise";
import Ember from "ember";
import Velocity from "velocity";

// Make sure Velocity always has promise support by injecting our own
// RSVP-based implementation if it doesn't already have one.
if (!Velocity.Promise) {
  Velocity.Promise = Promise;
}

export function animate(elt, props, opts, label) {
  // These numbers are just sane defaults in the probably-impossible
  // case where somebody tries to read our state before the first
  // 'progress' callback has fired.
  var state = { percentComplete: 0, timeRemaining: 100, timeSpent: 0 };

  if (!elt || elt.length === 0) {
    return Promise.resolve();
  }

  if (!opts) {
    opts = {};
  } else {
    opts = Ember.copy(opts);
  }

  // By default, we ask velocity to clear the element's `display`
  // and `visibility` properties at the start of animation. Our
  // animated divs are all initially rendered with `display:none`
  // and `visibility:hidden` to prevent a flash of before-animated
  // content.
  if (typeof(opts.display) === 'undefined') {
    opts.display = '';
  }
  if (typeof(opts.visibility) === 'undefined') {
    opts.visibility = 'visible';
  }

  if (opts.progress) {
    throw new Error("liquid-fire's 'animate' function reserves the use of Velocity's 'progress' option for its own nefarious purposes.");
  }

  opts.progress = function(){
    state.percentComplete = arguments[1];
    state.timeRemaining = arguments[2];
    state.timeSpent = state.timeRemaining / (1/state.percentComplete - 1);
  };

  state.promise = Promise.resolve(Velocity.animate(elt[0], props, opts));

  if (label) {
    state.promise = state.promise.then(function(){
      clearLabel(elt, label);
    }, function(err) {
      clearLabel(elt, label);
      throw err;
    });
    applyLabel(elt, label, state);
  }

  return state.promise;
}

export function stop(elt) {
  if (elt) {
    Velocity(elt[0], 'stop', true);
  }
}

export function setDefaults(props) {
  for (var key in props) {
    if (props.hasOwnProperty(key)) {
      if (key === 'progress') {
        throw new Error("liquid-fire's 'animate' function reserves the use of Velocity's '" + key + "' option for its own nefarious purposes.");
      }
      Velocity.defaults[key] = props[key];
    }
  }
}

export function isAnimating(elt, animationLabel) {
  return elt && elt.data('lfTags_' + animationLabel);
}

export function finish(elt, animationLabel) {
  return stateForLabel(elt, animationLabel).promise;
}

export function timeSpent(elt, animationLabel) {
  return stateForLabel(elt, animationLabel).timeSpent;
}

export function timeRemaining(elt, animationLabel) {
  return stateForLabel(elt, animationLabel).timeRemaining;
}

function stateForLabel(elt, label) {
  var state = isAnimating(elt, label);
  if (!state) {
    throw new Error("no animation labeled " + label + " is in progress");
  }
  return state;
}

function applyLabel(elt, label, state) {
  if (elt){
    elt.data('lfTags_' + label, state);
  }
}

function clearLabel(elt, label) {
  if (elt) {
    elt.data('lfTags_' + label, null);
  }
}
<commit_msg>Opt-in RAF high res timestamp<commit_after>/* jshint newcap: false */
import Promise from "./promise";
import Ember from "ember";
import Velocity from "velocity";

// Make sure Velocity always has promise support by injecting our own
// RSVP-based implementation if it doesn't already have one.
if (!Velocity.Promise) {
  Velocity.Promise = Promise;
}

// Velocity's tick() defaults to RAF's high resolution timestamp. If the browser
// is under high stress the RAF timestamp may have a significant offset which
// can result in dropping a large chunk of frames. Because of this, the use of
// the RAF timestamp should be opt-in.
Velocity.timestamp = false;

export function animate(elt, props, opts, label) {
  // These numbers are just sane defaults in the probably-impossible
  // case where somebody tries to read our state before the first
  // 'progress' callback has fired.
  var state = { percentComplete: 0, timeRemaining: 100, timeSpent: 0 };

  if (!elt || elt.length === 0) {
    return Promise.resolve();
  }

  if (!opts) {
    opts = {};
  } else {
    opts = Ember.copy(opts);
  }

  // By default, we ask velocity to clear the element's `display`
  // and `visibility` properties at the start of animation. Our
  // animated divs are all initially rendered with `display:none`
  // and `visibility:hidden` to prevent a flash of before-animated
  // content.
  if (typeof(opts.display) === 'undefined') {
    opts.display = '';
  }
  if (typeof(opts.visibility) === 'undefined') {
    opts.visibility = 'visible';
  }

  if (opts.progress) {
    throw new Error("liquid-fire's 'animate' function reserves the use of Velocity's 'progress' option for its own nefarious purposes.");
  }

  opts.progress = function(){
    state.percentComplete = arguments[1];
    state.timeRemaining = arguments[2];
    state.timeSpent = state.timeRemaining / (1/state.percentComplete - 1);
  };

  state.promise = Promise.resolve(Velocity.animate(elt[0], props, opts));

  if (label) {
    state.promise = state.promise.then(function(){
      clearLabel(elt, label);
    }, function(err) {
      clearLabel(elt, label);
      throw err;
    });
    applyLabel(elt, label, state);
  }

  return state.promise;
}

export function stop(elt) {
  if (elt) {
    Velocity(elt[0], 'stop', true);
  }
}

export function setDefaults(props) {
  for (var key in props) {
    if (props.hasOwnProperty(key)) {
      if (key === 'progress') {
        throw new Error("liquid-fire's 'animate' function reserves the use of Velocity's '" + key + "' option for its own nefarious purposes.");
      }
      Velocity.defaults[key] = props[key];
    }
  }
}

export function isAnimating(elt, animationLabel) {
  return elt && elt.data('lfTags_' + animationLabel);
}

export function finish(elt, animationLabel) {
  return stateForLabel(elt, animationLabel).promise;
}

export function timeSpent(elt, animationLabel) {
  return stateForLabel(elt, animationLabel).timeSpent;
}

export function timeRemaining(elt, animationLabel) {
  return stateForLabel(elt, animationLabel).timeRemaining;
}

function stateForLabel(elt, label) {
  var state = isAnimating(elt, label);
  if (!state) {
    throw new Error("no animation labeled " + label + " is in progress");
  }
  return state;
}

function applyLabel(elt, label, state) {
  if (elt){
    elt.data('lfTags_' + label, state);
  }
}

function clearLabel(elt, label) {
  if (elt) {
    elt.data('lfTags_' + label, null);
  }
}
<|endoftext|>


<commit_before>// ==UserScript==
// @author      Robert Slifka (github @rslifka)
// @connect     docs.google.com
// @connect     rslifka.github.io
// @copyright   2017-2018, Robert Slifka (https://github.com/rslifka/fate_of_all_fools)
// @description Enhancements to the Destiny Item Manager
// @grant       GM_addStyle
// @grant       GM_getResourceText
// @grant       GM_getValue
// @grant       GM_log
// @grant       GM_setValue
// @grant       GM_xmlhttpRequest
// @homepage    https://github.com/rslifka/fate_of_all_fools
// @license     MIT; https://raw.githubusercontent.com/rslifka/fate_of_all_fools/master/LICENSE.txt
// @match       https://*.destinyitemmanager.com/*
// @name        Fate of All Fools
// @require     https://rslifka.github.io/fate_of_all_fools/fateOfAllFools.js
// @resource    fateOfAllFoolsCSS https://rslifka.github.io/fate_of_all_fools/fateOfAllFools.css
// @run-at      document-start
// @supportURL  https://github.com/rslifka/fate_of_all_fools/issues
// @version     457
// ==/UserScript==
<commit_msg>AUTO-CREATED Release Artifact v458 c/o Travis<commit_after>// ==UserScript==
// @author      Robert Slifka (github @rslifka)
// @connect     docs.google.com
// @connect     rslifka.github.io
// @copyright   2017-2018, Robert Slifka (https://github.com/rslifka/fate_of_all_fools)
// @description Enhancements to the Destiny Item Manager
// @grant       GM_addStyle
// @grant       GM_getResourceText
// @grant       GM_getValue
// @grant       GM_log
// @grant       GM_setValue
// @grant       GM_xmlhttpRequest
// @homepage    https://github.com/rslifka/fate_of_all_fools
// @license     MIT; https://raw.githubusercontent.com/rslifka/fate_of_all_fools/master/LICENSE.txt
// @match       https://*.destinyitemmanager.com/*
// @name        Fate of All Fools
// @require     https://rslifka.github.io/fate_of_all_fools/fateOfAllFools.js
// @resource    fateOfAllFoolsCSS https://rslifka.github.io/fate_of_all_fools/fateOfAllFools.css
// @run-at      document-start
// @supportURL  https://github.com/rslifka/fate_of_all_fools/issues
// @version     458
// ==/UserScript==
<|endoftext|>


<commit_before>/**
 * Module Name: Github
 * Description: Retrieves interesting Github information
 */
var request = require('request'),
    _ = require('underscore')._;

var github = function(dbot) {
    var commands = {
        '~repocount': function(event) {
        // TODO: add handling for non existent user
            var reqUrl = "https://api.github.com/users/" + event.params[1] + "/repos";
            request(reqUrl, function(error, response, body) {
            var result = JSON.parse(body);
			event.reply(event.params[1] + " has " + result.length + " public repositories.");
            });
        },
        '~repo': function(event) {
            var repo = "";
            if (typeof event.params[1] == 'undefined') {
                repo = dbot.config.github.defaultrepo;
            } else {
                repo = event.params[1];
            }

            var reqUrl = "https://api.github.com/";
            reqUrl += "repos/" + repo;

            request(reqUrl, function(error, response, body) {
                var data = JSON.parse(body);
                if (data["fork"] == true) {
                   event.reply(dbot.t("forkedrepo",data));
                } else {
                    event.reply(dbot.t("unforkedrepo",data));
                }
                // TODO: move this shizz into an api call
                var longurl = "http://github.com/" + repo;
                request({method: 'POST', uri: 'http://git.io', form:{url: longurl}}, function(error, response, body){
                    event.reply(dbot.t('location')+" "+response.headers["location"]);
                });
            });
        },
        '~gstatus': function(event) {
            var reqUrl = "https://status.github.com/api/last-message.json";
            request(reqUrl, function(error,response,body){
                var data = JSON.parse(body);
                event.reply(dbot.t("status"+data["status"]));
                event.reply(data["body"]);
            });
        },
        '~milestone': function(event) {
            var repo = dbot.config.github.defaultrepo;
            var reqUrl = "https://api.github.com/repos/";
            reqUrl += repo + "/milestones";

            request(reqUrl, function(error, response, body) {
                var data = JSON.parse(body);
                for (var section in data) {
                    var milestone = data[section];
                    if (milestone["title"] == event.params[1]){
                        var str = "Milestone " + milestone["title"];
                        var progress = milestone["closed_issues"] / (milestone["open_issues"] + milestone["closed_issues"]);
                        progress = Math.round(progress*100);
                        var bar = "[";
                        for (var i = 1; i < 10; i++) {
                            if  ((progress / (i*10)) > 1) {
                                bar += "█";
                            } else {
                                bar += " ";
                            }
                        }
                        bar += "]";
                        str += " is " + bar + progress + "% complete";

                        var longurl = "http://github.com/" + repo + "/issues?milestone=" + milestone["number"];
                        request({method: 'POST', uri: 'http://git.io', form:{url: longurl}}, function(error, response, body){
                            event.reply(response.headers["location"]);
                        });
                        event.reply(str);
                        break;
                    }
                }
           });
        },
        '~repocount': function(event) {
        // TODO: add handling for non existent user
            var reqUrl = "https://api.github.com/users/" + event.params[1] + "/repos";
            request(reqUrl, function(error, response, body) {
            var result = JSON.parse(body);
			event.reply(event.params[1] + " has " + result.length + " public repositories.");
            });
        }
    };
    this.commands = commands;

    this.on = 'PRIVMSG';
};

exports.fetch = function(dbot) {
    return new github(dbot);
};
<commit_msg>simplify code<commit_after>/**
 * Module Name: Github
 * Description: Retrieves interesting Github information
 */
var request = require('request'),
    _ = require('underscore')._;

var github = function(dbot) {
    var commands = {
        '~repocount': function(event) {
        // TODO: add handling for non existent user
            var reqUrl = "https://api.github.com/users/" + event.params[1] + "/repos";
            request(reqUrl, function(error, response, body) {
            var result = JSON.parse(body);
			event.reply(event.params[1] + " has " + result.length + " public repositories.");
            });
        },
        '~repo': function(event) {
            var repo = event.params[1];
            if (typeof repo == 'undefined') {
                repo = dbot.config.github.defaultrepo;
            }

            var reqUrl = "https://api.github.com/";
            reqUrl += "repos/" + repo;

            request(reqUrl, function(error, response, body) {
                var data = JSON.parse(body);
                if (data["fork"] == true) {
                   event.reply(dbot.t("forkedrepo",data));
                } else {
                    event.reply(dbot.t("unforkedrepo",data));
                }
                // TODO: move this shizz into an api call
                var longurl = "http://github.com/" + repo;
                request({method: 'POST', uri: 'http://git.io', form:{url: longurl}}, function(error, response, body){
                    event.reply(dbot.t('location')+" "+response.headers["location"]);
                });
            });
        },
        '~gstatus': function(event) {
            var reqUrl = "https://status.github.com/api/last-message.json";
            request(reqUrl, function(error,response,body){
                var data = JSON.parse(body);
                event.reply(dbot.t("status"+data["status"]));
                event.reply(data["body"]);
            });
        },
        '~milestone': function(event) {
            var repo = dbot.config.github.defaultrepo;
            var reqUrl = "https://api.github.com/repos/";
            reqUrl += repo + "/milestones";

            request(reqUrl, function(error, response, body) {
                var data = JSON.parse(body);
                for (var section in data) {
                    var milestone = data[section];
                    if (milestone["title"] == event.params[1]){
                        var str = "Milestone " + milestone["title"];
                        var progress = milestone["closed_issues"] / (milestone["open_issues"] + milestone["closed_issues"]);
                        progress = Math.round(progress*100);
                        var bar = "[";
                        for (var i = 10; i < 100; i += 10) {
                            if  ((progress/i) > 1) {
                                bar += "█";
                            } else {
                                bar += " ";
                            }
                        }
                        bar += "]";
                        str += " is " + bar + progress + "% complete";

                        var longurl = "http://github.com/" + repo + "/issues?milestone=" + milestone["number"];
                        request({method: 'POST', uri: 'http://git.io', form:{url: longurl}}, function(error, response, body){
                            event.reply(response.headers["location"]);
                        });
                        event.reply(str);
                        break;
                    }
                }
           });
        },
        '~repocount': function(event) {
        // TODO: add handling for non existent user
            var reqUrl = "https://api.github.com/users/" + event.params[1] + "/repos";
            request(reqUrl, function(error, response, body) {
            var result = JSON.parse(body);
			event.reply(event.params[1] + " has " + result.length + " public repositories.");
            });
        }
    };
    this.commands = commands;

    this.on = 'PRIVMSG';
};

exports.fetch = function(dbot) {
    return new github(dbot);
};
<|endoftext|>


<commit_before>module.exports = function (grunt) {
    var config = require("../config.js");

    grunt.registerTask("test", function () {
        var args = [];
        for (var i = 0; i < arguments.length; ++i)
            args.push(arguments[i]);

        grunt.task.run(["default", "shell:runTests:" + args.join(":")]);
    });

    // Generate QUnit test pages
    var fs = require("fs");

    function clean(path) {
        var files = [];
        if( fs.existsSync(path) ) {
            files = fs.readdirSync(path);
            files.forEach(function(file,index){
                var curPath = path + "/" + file;
                if(fs.lstatSync(curPath).isDirectory()) {
                    clean(curPath);
                } else {
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    }

    function extractDependencies(fileContents) {
        var deps = [];

        var lines = fileContents.split("\r\n");
        for (var i = 0; i < lines.length; i++) {
            var line = lines[i];
            var processedOne = false;
            if (line.indexOf("<reference") < 0 || line.indexOf("ms-appx") >= 0) {
                if (processedOne) {
                    break;
                } else {
                    continue;
                }
            }

            var startIndex = line.indexOf('path="') + 6;
            var endIndex = line.indexOf('"', startIndex);

            deps.push(line.substring(startIndex, endIndex));

            processedOne = true;
        }
        return deps;
    }

    function arrayIndexOf(arr, obj) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] === obj) {
                return i;
            }
        }
        return -1;
    }

    var testMenuTemplate =
'<!DOCTYPE html>                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
    <title>WinJS Tests</title>                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
@@TESTS                                                                                \r\n\
                                                                                \r\n\
';

    var testPageTemplate =
'\r\n\
<!DOCTYPE html>                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
    <title>@@TITLE</title>                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
    <link type="text/css" rel="stylesheet" href="../../Microsoft.WinJS.2.1/css/ui-dark.css" />                              \r\n\
                                                                  \r\n\
                                                                    \r\n\
                                                    \r\n\
                                                      \r\n\
                                                                                \r\n\
                                                                                \r\n\
    <link type="text/css" rel="stylesheet" href="../TestLib/liveToQ/qunit-1.14.0.css" />                                    \r\n\
                                                                  \r\n\
                                                                       \r\n\
                                                                                \r\n\
                                                                                \r\n\
@@TESTREFERENCES                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\

  \r\n\

                                                                                \r\n\
                                                                                \r\n\
'.replace(/@@TARGETFRAMEWORK/g, config.targetFramework);

    clean("./bin/");
    fs.mkdirSync("./bin/");
    fs.mkdirSync("./bin/tests/");

    var dirs = fs.readdirSync("./tests");
    var tests = "";
    dirs.forEach(function (dir) {
        if (!fs.lstatSync("./tests/" + dir).isDirectory() || dir === "TestData" || dir === "TestLib") {
            return;
        }

        var html = testPageTemplate;
        html = html.replace("@@TITLE", dir);

        var testReferences = "";

        var srcs = [];
        var csss = [];
        var files = fs.readdirSync("./tests/" + dir);
        for (var i = files.length - 1; i >= 0; i --) {
            // Some folders have .html test assets, we can ignore those
            var file = files[i];
            if (file.indexOf(".css") >= 0) {
                csss.push(file);
            } else if (file.indexOf(".js") >= 0) {
                srcs.push(file);
            }
        }
        var done = false;
        while (!done) {
            done = true;
            var srcsCopy = srcs.slice(0);
            for (var i = 0; i < srcs.length; i++) {
                var fc = fs.readFileSync("./tests/" + dir + "/" + srcs[i], "utf-8");
                var deps = extractDependencies(fc);
                var length = srcsCopy.length;
                deps.forEach(function (dep) {
                    if (dep === srcs[i]) {
                        // Some files reference themselves, this check breaks an infinite loop
                        return;
                    }
                    if (dep.indexOf(".css") >= 0) {
                        if (arrayIndexOf(csss, dep) < 0) {
                            csss.push(dep);
                        }
                    } else {
                        var index = arrayIndexOf(srcsCopy, dep);
                        if (index >= 0) {
                            // If this dependency already exists, we need to reorder it to the bottom
                            // of the array so it gets loaded first. This usually happens when a dependency
                            // is in the same folder as the test folder but appears alphabetically before it.
                            srcsCopy.splice(index, 1);
                            length--;
                        } else {
                            done = false;
                        }
                        // Since the \r\n';
        }
        testReferences = testReferences.substr(0, testReferences.length - 2);
        html = html.replace("@@TESTREFERENCES", testReferences);
        fs.mkdirSync("./bin/tests/" + dir);
        fs.writeFileSync("./bin/tests/" + dir + "/test.html", html);
        tests += '
' + dir + " tests
\r\n";
    });
    tests = tests.substr(0, tests.length - 2);
    fs.writeFileSync("./bin/tests/tests.html", testMenuTemplate.replace("@@TESTS", tests));
};<commit_msg>Updated unittests.jsproj Changed to always build QUnit test pages<commit_after>module.exports = function (grunt) {
    var config = require("../config.js");

    grunt.registerTask("test", function () {
        var args = [];
        for (var i = 0; i < arguments.length; ++i)
            args.push(arguments[i]);

        grunt.task.run(["default", "clean:qunit", "shell:runTests:" + args.join(":")]);
    });

    // Generate QUnit test pages
    var fs = require("fs");

    function clean(path) {
        var files = [];
        if( fs.existsSync(path) ) {
            files = fs.readdirSync(path);
            files.forEach(function(file,index){
                var curPath = path + "/" + file;
                if(fs.lstatSync(curPath).isDirectory()) {
                    clean(curPath);
                } else {
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    }

    function extractDependencies(fileContents) {
        var deps = [];

        var lines = fileContents.split("\r\n");
        for (var i = 0; i < lines.length; i++) {
            var line = lines[i];
            var processedOne = false;
            if (line.indexOf("<reference") < 0 || line.indexOf("ms-appx") >= 0) {
                if (processedOne) {
                    break;
                } else {
                    continue;
                }
            }

            var startIndex = line.indexOf('path="') + 6;
            var endIndex = line.indexOf('"', startIndex);

            deps.push(line.substring(startIndex, endIndex));

            processedOne = true;
        }
        return deps;
    }

    function arrayIndexOf(arr, obj) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] === obj) {
                return i;
            }
        }
        return -1;
    }

    var testMenuTemplate =
'<!DOCTYPE html>                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
    <title>WinJS Tests</title>                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
@@TESTS                                                                                \r\n\
                                                                                \r\n\
';

    var testPageTemplate =
'\r\n\
<!DOCTYPE html>                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
    <title>@@TITLE</title>                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\
    <link type="text/css" rel="stylesheet" href="../../Microsoft.WinJS.2.1/css/ui-dark.css" />                              \r\n\
                                                                  \r\n\
                                                                    \r\n\
                                                    \r\n\
                                                      \r\n\
                                                                                \r\n\
                                                                                \r\n\
    <link type="text/css" rel="stylesheet" href="../TestLib/liveToQ/qunit-1.14.0.css" />                                    \r\n\
                                                                  \r\n\
                                                                       \r\n\
                                                                                \r\n\
                                                                                \r\n\
@@TESTREFERENCES                                                                                \r\n\
                                                                                \r\n\
                                                                                \r\n\

  \r\n\

                                                                                \r\n\
                                                                                \r\n\
'.replace(/@@TARGETFRAMEWORK/g, config.targetFramework);

    clean("./bin/");
    fs.mkdirSync("./bin/");
    fs.mkdirSync("./bin/tests/");

    var dirs = fs.readdirSync("./tests");
    var tests = "";
    dirs.forEach(function (dir) {
        if (!fs.lstatSync("./tests/" + dir).isDirectory() || dir === "TestData" || dir === "TestLib") {
            return;
        }

        var html = testPageTemplate;
        html = html.replace("@@TITLE", dir);

        var testReferences = "";

        var srcs = [];
        var csss = [];
        var files = fs.readdirSync("./tests/" + dir);
        for (var i = files.length - 1; i >= 0; i --) {
            // Some folders have .html test assets, we can ignore those
            var file = files[i];
            if (file.indexOf(".css") >= 0) {
                csss.push(file);
            } else if (file.indexOf(".js") >= 0) {
                srcs.push(file);
            }
        }
        var done = false;
        while (!done) {
            done = true;
            var srcsCopy = srcs.slice(0);
            for (var i = 0; i < srcs.length; i++) {
                var fc = fs.readFileSync("./tests/" + dir + "/" + srcs[i], "utf-8");
                var deps = extractDependencies(fc);
                var length = srcsCopy.length;
                deps.forEach(function (dep) {
                    if (dep === srcs[i]) {
                        // Some files reference themselves, this check breaks an infinite loop
                        return;
                    }
                    if (dep.indexOf(".css") >= 0) {
                        if (arrayIndexOf(csss, dep) < 0) {
                            csss.push(dep);
                        }
                    } else {
                        var index = arrayIndexOf(srcsCopy, dep);
                        if (index >= 0) {
                            // If this dependency already exists, we need to reorder it to the bottom
                            // of the array so it gets loaded first. This usually happens when a dependency
                            // is in the same folder as the test folder but appears alphabetically before it.
                            srcsCopy.splice(index, 1);
                            length--;
                        } else {
                            done = false;
                        }
                        // Since the \r\n';
        }
        testReferences = testReferences.substr(0, testReferences.length - 2);
        html = html.replace("@@TESTREFERENCES", testReferences);
        fs.mkdirSync("./bin/tests/" + dir);
        fs.writeFileSync("./bin/tests/" + dir + "/test.html", html);
        tests += '
' + dir + " tests
\r\n";
    });
    tests = tests.substr(0, tests.length - 2);
    fs.writeFileSync("./bin/tests/tests.html", testMenuTemplate.replace("@@TESTS", tests));
};<|endoftext|>


<commit_before>//= require jquery
//= require jquery_ujs
//= require jquery-ui/draggable
//= require jquery-ui/droppable
//= require jquery-collision.min
//= require jquery-ui-draggable-collision
//= require sinon-1.17.2

// set the Mocha test interface
// see http://mochajs.org/#interfaces
mocha.ui('bdd');

// ignore the following globals during leak detection
mocha.globals(['YUI']);

// Show stack trace on failing assertion.
chai.config.includeStack = true;

ENV = {
  TESTING: true
};<commit_msg>Remove Sinon from spec_helper<commit_after>//= require jquery
//= require jquery_ujs
//= require jquery-ui/draggable
//= require jquery-ui/droppable
//= require jquery-collision.min
//= require jquery-ui-draggable-collision

// set the Mocha test interface
// see http://mochajs.org/#interfaces
mocha.ui('bdd');

// ignore the following globals during leak detection
mocha.globals(['YUI']);

// Show stack trace on failing assertion.
chai.config.includeStack = true;

ENV = {
  TESTING: true
};<|endoftext|>


<commit_before>import _ from "underscore";
import React from "react";
import ReactDOM from "react-dom";

import { connect } from "react-redux";

// Hack! If 1px lines are drawn on whole numbers with shape-rendering set to
// crispEdges, it's drawing a 2px line ... so offset it by a fraction.
function roundUp(x) {
  if (Math.floor(x) === x) {
    return x + 0.25;
  } else {
    return x
  }
}

class Stone extends React.Component {
  render() {
    let radius = 0.9 * (this.props.unit / 2);

    let style = {
      fill: this.props.color === "B" ? "#333333" : "white",
      filter: this.props.color === "B" ? "url(#black-stone-shadows)" : "url(#white-stone-shadows)"
      // fill: color === "B" ? "black" : "white",
      // stroke: "black",
      // strokeWidth: "0.25px",
    };

    return <circle r={radius} style={style} />
  }
}

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {height: 480, width: 480};
  }

  handleResize() {
    let svg = ReactDOM.findDOMNode(this);
    let height = svg.offsetHeight,
        width = svg.offsetWidth;

    this.setState({height, width});
  }

  handleMouseMove(e) {
    // console.log(e);
  }

  getDefs() {
    return { __html: `
      <filter id="white-stone-shadows" x="-50%" y="-50%" width="200%" height="200%">
        <feComponentTransfer in=SourceAlpha>
          <feFuncA type="table" tableValues="1 0" />
        </feComponentTransfer>
        <feGaussianBlur stdDeviation="4"/>
        <feOffset dx="-2" dy="-2" result="offsetblur"/>
        <feFlood flood-color="#d0d0d0"/>
        <feComposite in2="offsetblur" operator="in"/>
        <feComposite in2="SourceAlpha" operator="in" />
        <feMerge result="inset">
          <feMergeNode in="SourceGraphic" />
          <feMergeNode />
        </feMerge>

      	<feGaussianBlur in="SourceAlpha" stdDeviation="1"/>
    		<feOffset dx="2" dy="2" result="offsetblur"/>
        <feComponentTransfer>
          <feFuncA type="linear" slope="0.5"/>
        </feComponentTransfer>
        <feComposite in2="offsetblur" operator="in" result="drop"/>

    		<feMerge>
          <feMergeNode in="drop"/>
          <feMergeNode in="SourceGraphic"/>
    			<feMergeNode in="inset"/>
    		</feMerge>
    	</filter>

      <filter id="black-stone-shadows" x="-50%" y="-50%" width="200%" height="200%">
        <feComponentTransfer in=SourceAlpha>
          <feFuncA type="table" tableValues="1 0" />
        </feComponentTransfer>
        <feGaussianBlur stdDeviation="4"/>
        <feOffset dx="2" dy="2" result="offsetblur"/>
        <feFlood flood-color="black"/>
        <feComposite in2="offsetblur" operator="in"/>
        <feComposite in2="SourceAlpha" operator="in" />
        <feMerge result="inset">
          <feMergeNode in="SourceGraphic" />
          <feMergeNode />
        </feMerge>

      	<feGaussianBlur in="SourceAlpha" stdDeviation="1"/>
    		<feOffset dx="2" dy="2" result="offsetblur"/>
        <feComponentTransfer>
          <feFuncA type="linear" slope="0.5"/>
        </feComponentTransfer>
        <feComposite in2="offsetblur" operator="in" result="drop"/>

    		<feMerge>
          <feMergeNode in="drop"/>
          <feMergeNode in="SourceGraphic"/>
    			<feMergeNode in="inset"/>
    		</feMerge>
    	</filter>
    `};
  }

  mergeBoardElements(...args) {
    let keys = _.union(..._.map(args, _.keys));

    let values = _.map(keys, k => {
      return _.chain(args)
        .map(_.property(k))
        .filter(Boolean)
        .value()
    })

    return _.object(keys, values)
  }

  renderGrid(boardSize, unit, margin) {
    let gridSize = (boardSize - 1) * unit;

    let style = {
      stroke: "black",
      strokeWidth: "1px",
      fill: "None",
      shapeRendering: "crispEdges"
    };

    let horizontalLines = _.range(1, boardSize-1).map( (i) => {
      return `M${roundUp(margin)} ${roundUp(margin + i*unit)} h ${gridSize}`;
    });

    let verticalLines = _.range(1, boardSize-1).map( (i) => {
      return `M${roundUp(margin + i*unit)} ${roundUp(margin)} v ${gridSize}`;
    });

    let grid = [
      `M${roundUp(margin)} ${roundUp(margin)}`,
      `h ${gridSize}`,
      `v ${gridSize}`,
      `h ${-gridSize}`,
      `v ${-gridSize}`,
      "Z",
      ...verticalLines,
      ...horizontalLines
    ]

    return <path d={grid.join(" ")} style={style} />
  }

  renderStones(stones, boardSize, unit, margin) {
    function parseColor(m) {
      if (m.B) return 'B';
      if (m.W) return 'W'
    }
    function parseCoordinate(coords) {
      let offset = 'a'.charCodeAt(0);
      let x = coords.charCodeAt(0) - offset,
          y = coords.charCodeAt(1) - offset;

      return [x, y];
    }

    return _.chain(stones).keys().map(coords => {
      let color = stones[coords];
      let [x, y] = parseCoordinate(coords);

      let radius = 0.9 * (unit / 2);

      let style = {
        fill: color === "B" ? "#333333" : "white",
        filter: color === "B" ? "url(#black-stone-shadows)" : "url(#white-stone-shadows)"
        // fill: color === "B" ? "black" : "white",
        // stroke: "black",
        // strokeWidth: "0.25px",

      };

      return (
        <circle key={`move-${coords}`}
                r={radius}
                cx={margin + unit * x}
                cy={margin + unit * y}
                style={style} />
      );
    }).value();
  }

  renderBoardElements(boardSize, unit, margin, boardElements) {
    function parseCoordinate(coords) {
      let offset = 'a'.charCodeAt(0);
      let x = coords.charCodeAt(0) - offset,
          y = coords.charCodeAt(1) - offset;

      return [x, y];
    }

    return _.chain(boardElements).keys().map(coords => {
      let elements = boardElements[coords];
      let [x, y] = parseCoordinate(coords);

      let props = {
        key: coords,
        transform: `translate(${margin + unit * x}, ${margin + unit * y})`,
      };

      let children = _.map(boardElements[coords], (el, i) => {
        if (el == "B") {
          return <Stone key={i} color="B" unit={unit} />
        } else if (el = "W") {
          return <Stone key={i} color="W" unit={unit} />
        }
        // else if (el = "circle") {
        //   // return <circle key={i}
        //   <circle key={`move-${coords}`}
        //           r={radius}
        //
        // }
      });

      return React.createElement("g", props, children)
    }).value();

  }

  render() {
    let svgSize = Math.min(this.state.height, this.state.width);
    let size = svgSize;

    let unit = size / (this.props.boardSize + 0.5);
    let margin = unit * 0.75;

    let rectStyle = {
      fill: "#ffcc66",
    };

    let boardElements = this.mergeBoardElements(this.props.stones, this.props.decoration)

    // _.chain([this.props.stones, this.props.decoration])
    //   .map(pairs)
    //   .map(())

    // {this.renderStones(this.props.stones, this.props.boardSize, unit, margin)}
    // {this.renderDecoration(this.props.decoration, this.props.boardSize, unit, margin)}

    return (
      <svg height={svgSize} width={svgSize}>
        <defs dangerouslySetInnerHTML={this.getDefs()} />

        <g onMouseMove={this.handleMouseMove}>
          <rect width={size} height={size} style={rectStyle} />
          {this.renderGrid(this.props.boardSize, unit, margin)}
          {this.renderBoardElements(this.props.boardSize, unit, margin, boardElements)}
        </g>
      </svg>
    )
  }
}

function getLastMove(node) {
  if (!node) return undefined
  if (node.B || node.W) return node;
  if (node._parent) return getLastMove(node._parent);
}

function getCoords(node) {
  if (!node) return undefined
  if (node.B) return node.B;
  if (node.W) return node.W;
}

function mapStateToProps(state) {
  let lastMove = getCoords(getLastMove(state.sgf.currentNode));
  let decoration = lastMove ? {[lastMove]: "circle"} : {}

  let {boardSize, stones} = state.sgf.board
  // let stones = state.sgf.board.stones
  // console.log(lastMove);

  return {
    boardSize,
    stones,
    decoration
    // currentTurn: state.sgf.board.currentTurn
  };
}

export default connect(mapStateToProps)(Board);
<commit_msg>set mouseover in state<commit_after>import _ from "underscore";
import React from "react";
import ReactDOM from "react-dom";

import { connect } from "react-redux";

// Hack! If 1px lines are drawn on whole numbers with shape-rendering set to
// crispEdges, it's drawing a 2px line ... so offset it by a fraction.
function roundUp(x) {
  if (Math.floor(x) === x) {
    return x + 0.25;
  } else {
    return x
  }
}

class Stone extends React.Component {
  render() {
    let radius = 0.9 * (this.props.unit / 2);

    let style = {
      fill: this.props.color === "B" ? "#333333" : "white",
      filter: this.props.color === "B" ? "url(#black-stone-shadows)" : "url(#white-stone-shadows)"
      // fill: color === "B" ? "black" : "white",
      // stroke: "black",
      // strokeWidth: "0.25px",
    };

    return <circle r={radius} style={style} />
  }
}

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {size: 480};
  }

  svg() {
    ReactDOM.findDOMNode(this);
  }

  margin() {
    return this.state.size / (this.props.boardSize + 1);
  }

  unit() {
    return (this.state.size - this.margin() * 2) / (this.props.boardSize - 1)
  }

  parseCoordinate(coords) {
    let offset = 'a'.charCodeAt();
    let x = coords.charCodeAt(0) - offset,
        y = coords.charCodeAt(1) - offset;

    return [x, y];
  }

  toCoordinates(x, y) {
    let offset = 'a'.charCodeAt();
    return String.fromCharCode(offset + x) + String.fromCharCode(offset + y);
  }

  handleResize() {
    let svg = ReactDOM.findDOMNode(this);
    let height = svg.offsetHeight,
        width = svg.offsetWidth;

    this.setState({height, width});
  }

  handleMouseMove(e) {
    let svg = ReactDOM.findDOMNode(this);
    let margin = this.margin();
    let unit = this.unit();

    let {clientX, clientY} = e;
    let {offsetLeft, offsetTop} = svg;

    let x = parseInt((clientX - offsetLeft - margin + unit / 2) / unit);
    let y = parseInt((clientY - offsetTop - margin + unit / 2) / unit);

    console.log(this.toCoordinates(x, y));
    this.setState({preview: this.toCoordinates(x, y)});
  }

  getDefs() {
    return { __html: `
      <filter id="white-stone-shadows" x="-50%" y="-50%" width="200%" height="200%">
        <feComponentTransfer in=SourceAlpha>
          <feFuncA type="table" tableValues="1 0" />
        </feComponentTransfer>
        <feGaussianBlur stdDeviation="4"/>
        <feOffset dx="-2" dy="-2" result="offsetblur"/>
        <feFlood flood-color="#d0d0d0"/>
        <feComposite in2="offsetblur" operator="in"/>
        <feComposite in2="SourceAlpha" operator="in" />
        <feMerge result="inset">
          <feMergeNode in="SourceGraphic" />
          <feMergeNode />
        </feMerge>

      	<feGaussianBlur in="SourceAlpha" stdDeviation="1"/>
    		<feOffset dx="2" dy="2" result="offsetblur"/>
        <feComponentTransfer>
          <feFuncA type="linear" slope="0.5"/>
        </feComponentTransfer>
        <feComposite in2="offsetblur" operator="in" result="drop"/>

    		<feMerge>
          <feMergeNode in="drop"/>
          <feMergeNode in="SourceGraphic"/>
    			<feMergeNode in="inset"/>
    		</feMerge>
    	</filter>

      <filter id="black-stone-shadows" x="-50%" y="-50%" width="200%" height="200%">
        <feComponentTransfer in=SourceAlpha>
          <feFuncA type="table" tableValues="1 0" />
        </feComponentTransfer>
        <feGaussianBlur stdDeviation="4"/>
        <feOffset dx="2" dy="2" result="offsetblur"/>
        <feFlood flood-color="black"/>
        <feComposite in2="offsetblur" operator="in"/>
        <feComposite in2="SourceAlpha" operator="in" />
        <feMerge result="inset">
          <feMergeNode in="SourceGraphic" />
          <feMergeNode />
        </feMerge>

      	<feGaussianBlur in="SourceAlpha" stdDeviation="1"/>
    		<feOffset dx="2" dy="2" result="offsetblur"/>
        <feComponentTransfer>
          <feFuncA type="linear" slope="0.5"/>
        </feComponentTransfer>
        <feComposite in2="offsetblur" operator="in" result="drop"/>

    		<feMerge>
          <feMergeNode in="drop"/>
          <feMergeNode in="SourceGraphic"/>
    			<feMergeNode in="inset"/>
    		</feMerge>
    	</filter>
    `};
  }

  mergeBoardElements(...args) {
    let keys = _.union(..._.map(args, _.keys));

    let values = _.map(keys, k => {
      return _.chain(args)
        .map(_.property(k))
        .filter(Boolean)
        .value()
    })

    return _.object(keys, values)
  }

  renderGrid(boardSize, unit, margin) {
    let gridSize = (boardSize - 1) * unit;

    let style = {
      stroke: "black",
      strokeWidth: "1px",
      fill: "None",
      shapeRendering: "crispEdges"
    };

    let horizontalLines = _.range(1, boardSize-1).map( (i) => {
      return `M${roundUp(margin)} ${roundUp(margin + i*unit)} h ${gridSize}`;
    });

    let verticalLines = _.range(1, boardSize-1).map( (i) => {
      return `M${roundUp(margin + i*unit)} ${roundUp(margin)} v ${gridSize}`;
    });

    let grid = [
      `M${roundUp(margin)} ${roundUp(margin)}`,
      `h ${gridSize}`,
      `v ${gridSize}`,
      `h ${-gridSize}`,
      `v ${-gridSize}`,
      "Z",
      ...verticalLines,
      ...horizontalLines
    ]

    return <path d={grid.join(" ")} style={style} />
  }

  renderBoardElements(boardSize, unit, margin, boardElements) {

    return _.chain(boardElements).keys().map(coords => {
      let elements = boardElements[coords];
      let [x, y] = this.parseCoordinate(coords);

      let props = {
        key: coords,
        transform: `translate(${margin + unit * x}, ${margin + unit * y})`,
      };

      let children = _.map(boardElements[coords], (el, i, list) => {
        if (el == "B") {
          return <Stone key={i} color="B" unit={unit} />
        } else if (el == "W") {
          return <Stone key={i} color="W" unit={unit} />
        }
        else if (el == "circle") {
          let radius = 0.28 * unit;
          let color = _.contains(list.slice(0, i), "B") ? "white" : "black";

          let style = {
            fill: "None",
            stroke: color,
            strokeWidth: unit / 12
          };
          return <circle key={`move-${coords}`} r={radius} style={style} />
        }
      });

      return React.createElement("g", props, children)
    }).value();

  }

  render() {
    let size = this.state.size;
    let unit = this.unit();
    let margin = this.margin();

    let rectStyle = {
      fill: "#ffcc66",
    };

    let boardElements = this.mergeBoardElements(this.props.stones, this.props.decoration)

    return (
      <svg height={size} width={size} onMouseMove={this.handleMouseMove.bind(this)}>
        <defs dangerouslySetInnerHTML={this.getDefs()} />

        <g>
          <rect width={size} height={size} style={rectStyle} />
          {this.renderGrid(this.props.boardSize, unit, margin)}
          {this.renderBoardElements(this.props.boardSize, unit, margin, boardElements)}
        </g>
      </svg>
    )
  }
}

function getLastMove(node) {
  if (!node) return undefined
  if (node.B || node.W) return node;
  if (node._parent) return getLastMove(node._parent);
}

function getCoords(node) {
  if (!node) return undefined
  if (node.B) return node.B;
  if (node.W) return node.W;
}

function mapStateToProps(state) {
  let lastMove = getCoords(getLastMove(state.sgf.currentNode));
  let decoration = lastMove ? {[lastMove]: "circle"} : {}

  let {boardSize, stones} = state.sgf.board
  // let stones = state.sgf.board.stones
  // console.log(lastMove);

  return {
    boardSize,
    stones,
    decoration
    // currentTurn: state.sgf.board.currentTurn
  };
}

export default connect(mapStateToProps)(Board);
<|endoftext|>


<commit_before>// Import the APIs we need.

var pageMod = require("page-mod");
var Request = require("request").Request;
var notifications = require("notifications");
var self = require("self");
var tabs = require("tabs");
var ss = require("simple-storage");
var workers = [];
var contextMenu = require("context-menu");
var priv = require("private-browsing");
var windows = require("sdk/windows").browserWindows;

// require chrome allows us to use XPCOM objects...
const {Cc, Ci, Cu, Cr} = require("chrome");

var historyService = Cc["@mozilla.org/browser/history;1"].getService(Ci.mozIAsyncHistory);

// this function takes in a string (and optional charset, paseURI) and creates an nsURI object, which is required by historyService.addURI...
function makeURI(aURL, aOriginCharset, aBaseURI) {
	var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
	return ioService.newURI(aURL, aOriginCharset, aBaseURI);
}

function detachWorker(worker, workerArray) {
	var index = workerArray.indexOf(worker);
	if(index != -1) {
		workerArray.splice(index, 1);
	}
}
var localStorage = ss.storage;

// these aliases are just for simplicity, so that the code here looks just like background code
// for all of the other browsers...
localStorage.getItem = function(key) {
	return ss.storage[key];
};
localStorage.setItem = function(key, value) {
	ss.storage[key] = value;
};
localStorage.removeItem = function(key) {
	delete ss.storage[key];
};

pageMod.PageMod({
  include: ["*.babelext.com"],
  contentScriptWhen: 'ready',
  contentScriptFile: [self.data.url('BabelExt.js'), self.data.url('extension.js')],
  onAttach: function(worker) {
	tabs.on('activate', function(tab) {
		// run some code when a tab is activated...
	});

	workers.push(worker);
	worker.on('detach', function () {
		detachWorker(this, workers);
		// console.log('worker detached, total now: ' + workers.length);
    });

	worker.on('message', function(data) {
		var request = data;
		switch(request.requestType) {
			case 'xmlhttpRequest':
				var responseObj = {
					callbackID: request.callbackID,
					name: request.requestType
				};
				if (request.method == 'POST') {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							};
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).post();
				} else {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							};
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).get();
				}
				break;
			case 'createTab':
				var focus = (request.background !== true);
				tabs.open({url: request.url, inBackground: !focus });
				worker.postMessage({status: "success"});
				break;
			case 'createNotification':
				if (!request.icon) {
					// if no icon specified, make a single pixel empty gif so we don't get a broken image link.
					request.icon = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
				}
				notifications.notify({
					title: request.title,
					text: request.text,
					iconURL: request.icon
				});
				break;
			case 'localStorage':
				switch (request.operation) {
					case 'getItem':
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: localStorage.getItem(request.itemName)
						});
						break;
					case 'removeItem':
						localStorage.removeItem(request.itemName);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							value: null
						});
						break;
					case 'setItem':
						localStorage.setItem(request.itemName, request.itemValue);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: request.itemValue
						});
						break;
				}
				break;
			case 'addURLToHistory':
				var isPrivate = priv.isPrivate(windows.activeWindow);
				if (isPrivate) {
					// do not add to history if in private browsing mode!
					return false;
				}
				var uri = makeURI(request.url);
				historyService.updatePlaces({
					uri: uri,
					visits: [{
						transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
						visitDate: Date.now() * 1000
					}]
				});
				break;
			case 'contextMenus.create':
				contextMenu.Item({
					label: request.obj.title,
					context: contextMenu.PageContext(),
					data: request.obj.onclick,
					contentScript: 'self.on("click", function (node, data) {' +
									'self.postMessage(data);' +
									'});',
					onMessage: function(onclick) {
						worker.postMessage({
							name: 'contextMenus.click',
							callbackID: onclick
						});
					}

				});
				break;
			default:
				worker.postMessage({status: "unrecognized request type"});
				break;
		}

	});
  }
});
<commit_msg>Add sdk/ prefix to Firefox/lib/main.js require()s<commit_after>// Import the APIs we need.

var pageMod = require("sdk/page-mod");
var Request = require("sdk/request").Request;
var notifications = require("sdk/notifications");
var self = require("sdk/self");
var tabs = require("sdk/tabs");
var ss = require("sdk/simple-storage");
var workers = [];
var contextMenu = require("sdk/context-menu");
var priv = require("sdk/private-browsing");
var windows = require("sdk/windows").browserWindows;

// require chrome allows us to use XPCOM objects...
const {Cc, Ci, Cu, Cr} = require("chrome");

var historyService = Cc["@mozilla.org/browser/history;1"].getService(Ci.mozIAsyncHistory);

// this function takes in a string (and optional charset, paseURI) and creates an nsURI object, which is required by historyService.addURI...
function makeURI(aURL, aOriginCharset, aBaseURI) {
	var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
	return ioService.newURI(aURL, aOriginCharset, aBaseURI);
}

function detachWorker(worker, workerArray) {
	var index = workerArray.indexOf(worker);
	if(index != -1) {
		workerArray.splice(index, 1);
	}
}
var localStorage = ss.storage;

// these aliases are just for simplicity, so that the code here looks just like background code
// for all of the other browsers...
localStorage.getItem = function(key) {
	return ss.storage[key];
};
localStorage.setItem = function(key, value) {
	ss.storage[key] = value;
};
localStorage.removeItem = function(key) {
	delete ss.storage[key];
};

pageMod.PageMod({
  include: ["*.babelext.com"],
  contentScriptWhen: 'ready',
  contentScriptFile: [self.data.url('BabelExt.js'), self.data.url('extension.js')],
  onAttach: function(worker) {
	tabs.on('activate', function(tab) {
		// run some code when a tab is activated...
	});

	workers.push(worker);
	worker.on('detach', function () {
		detachWorker(this, workers);
		// console.log('worker detached, total now: ' + workers.length);
    });

	worker.on('message', function(data) {
		var request = data;
		switch(request.requestType) {
			case 'xmlhttpRequest':
				var responseObj = {
					callbackID: request.callbackID,
					name: request.requestType
				};
				if (request.method == 'POST') {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							};
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).post();
				} else {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							};
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).get();
				}
				break;
			case 'createTab':
				var focus = (request.background !== true);
				tabs.open({url: request.url, inBackground: !focus });
				worker.postMessage({status: "success"});
				break;
			case 'createNotification':
				if (!request.icon) {
					// if no icon specified, make a single pixel empty gif so we don't get a broken image link.
					request.icon = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
				}
				notifications.notify({
					title: request.title,
					text: request.text,
					iconURL: request.icon
				});
				break;
			case 'localStorage':
				switch (request.operation) {
					case 'getItem':
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: localStorage.getItem(request.itemName)
						});
						break;
					case 'removeItem':
						localStorage.removeItem(request.itemName);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							value: null
						});
						break;
					case 'setItem':
						localStorage.setItem(request.itemName, request.itemValue);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: request.itemValue
						});
						break;
				}
				break;
			case 'addURLToHistory':
				var isPrivate = priv.isPrivate(windows.activeWindow);
				if (isPrivate) {
					// do not add to history if in private browsing mode!
					return false;
				}
				var uri = makeURI(request.url);
				historyService.updatePlaces({
					uri: uri,
					visits: [{
						transitionType: Ci.nsINavHistoryService.TRANSITION_LINK,
						visitDate: Date.now() * 1000
					}]
				});
				break;
			case 'contextMenus.create':
				contextMenu.Item({
					label: request.obj.title,
					context: contextMenu.PageContext(),
					data: request.obj.onclick,
					contentScript: 'self.on("click", function (node, data) {' +
									'self.postMessage(data);' +
									'});',
					onMessage: function(onclick) {
						worker.postMessage({
							name: 'contextMenus.click',
							callbackID: onclick
						});
					}

				});
				break;
			default:
				worker.postMessage({status: "unrecognized request type"});
				break;
		}

	});
  }
});
<|endoftext|>


<commit_before>// Import the APIs we need.
var pageMod = require("page-mod");
var Request = require("request").Request;
var notifications = require("notifications");
var self = require("self");
var tabs = require("tabs");
var ss = require("simple-storage");
var workers = new Array();

// require chrome allows us to use XPCOM objects...
var {Cc, Cu, Cr} = require("chrome");
// from XPCOM, use the NSIGlobalHistory2 service...
var historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"] .getService(Components.interfaces.nsIGlobalHistory2)

// this function takes in a string (and optional charset, paseURI) and creates an nsURI object, which is required by historyService.addURI...
function makeURI(aURL, aOriginCharset, aBaseURI) {
  var ioService = Components.classes["@mozilla.org/network/io-service;1"]
                  .getService(Components.interfaces.nsIIOService);
  return ioService.newURI(aURL, aOriginCharset, aBaseURI);
}

function detachWorker(worker, workerArray) {
	var index = workerArray.indexOf(worker);
	if(index != -1) {
		workerArray.splice(index, 1);
	}
}
var localStorage = ss.storage;

// these aliases are just for simplicity, so that the code here looks just like background code
// for all of the other browsers...
localStorage.getItem = function(key) {
	return ss.storage[key];
}
localStorage.setItem = function(key, value) {
	ss.storage[key] = value;
}
localStorage.removeItem = function(key) {
	delete ss.storage[key];
}

pageMod.PageMod({
  include: ["*.babelext.com"],
  contentScriptWhen: 'ready',
  contentScriptFile: [self.data.url('BabelExt.js'), self.data.url('extension.js')],
  onAttach: function(worker) {
	tabs.on('activate', function(tab) {
		// run some code when a tab is activated...
	});

	workers.push(worker);
	worker.on('detach', function () {
		detachWorker(this, workers);
		// console.log('worker detached, total now: ' + workers.length);
    });

	worker.on('message', function(data) {
		var request = data;
		switch(request.requestType) {
			case 'xmlhttpRequest':
				var responseObj = {
					XHRID: request.XHRID,
					name: request.requestType
				}
				if (request.method == 'POST') {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							}
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).post();
				} else {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							}
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).get();
				}

				break;
			case 'createTab':
				var focus = (request.background != true);
				tabs.open({url: request.url, inBackground: !focus });
				worker.postMessage({status: "success"});
				break;
			case 'createNotification':
				if (!request.icon) {
					// if no icon specified, make a single pixel empty gif so we don't get a broken image link.
					request.icon = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
				}
				notifications.notify({
				  title: request.title,
				  text: request.text,
				  iconURL: request.icon
				});
				break;
			case 'localStorage':
				switch (request.operation) {
					case 'getItem':
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: localStorage.getItem(request.itemName)
						});
						break;
					case 'removeItem':
						localStorage.removeItem(request.itemName);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							value: null
						});
						break;
					case 'setItem':
						localStorage.setItem(request.itemName, request.itemValue);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: request.itemValue
						});
						break;
				}
				break;
			case 'addURLToHistory':
				var uri = makeURI(request.url);
				historyService.addURI(uri, false, true, null);
				break;
			default:
				worker.postMessage({status: "unrecognized request type"});
				break;
		}

	});
  }
});

<commit_msg>updating firefox chrome authority acquiring<commit_after>// Import the APIs we need.
var pageMod = require("page-mod");
var Request = require("request").Request;
var notifications = require("notifications");
var self = require("self");
var tabs = require("tabs");
var ss = require("simple-storage");
var workers = new Array();

// require chrome allows us to use XPCOM objects...
const {Cc, Ci, Cu, Cr} = require("chrome");
// from XPCOM, use the NSIGlobalHistory2 service...
var historyService = Cc["@mozilla.org/browser/nav-history-service;1"] .getService(Ci.nsIGlobalHistory2)

// this function takes in a string (and optional charset, paseURI) and creates an nsURI object, which is required by historyService.addURI...
function makeURI(aURL, aOriginCharset, aBaseURI) {
  var ioService = Cc["@mozilla.org/network/io-service;1"]
                  .getService(Ci.nsIIOService);
  return ioService.newURI(aURL, aOriginCharset, aBaseURI);
}

function detachWorker(worker, workerArray) {
	var index = workerArray.indexOf(worker);
	if(index != -1) {
		workerArray.splice(index, 1);
	}
}
var localStorage = ss.storage;

// these aliases are just for simplicity, so that the code here looks just like background code
// for all of the other browsers...
localStorage.getItem = function(key) {
	return ss.storage[key];
}
localStorage.setItem = function(key, value) {
	ss.storage[key] = value;
}
localStorage.removeItem = function(key) {
	delete ss.storage[key];
}

pageMod.PageMod({
  include: ["*.babelext.com"],
  contentScriptWhen: 'ready',
  contentScriptFile: [self.data.url('BabelExt.js'), self.data.url('extension.js')],
  onAttach: function(worker) {
	tabs.on('activate', function(tab) {
		// run some code when a tab is activated...
	});

	workers.push(worker);
	worker.on('detach', function () {
		detachWorker(this, workers);
		// console.log('worker detached, total now: ' + workers.length);
    });

	worker.on('message', function(data) {
		var request = data;
		switch(request.requestType) {
			case 'xmlhttpRequest':
				var responseObj = {
					XHRID: request.XHRID,
					name: request.requestType
				}
				if (request.method == 'POST') {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							}
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).post();
				} else {
					Request({
						url: request.url,
						onComplete: function(response) {
							responseObj.response = {
								responseText: response.text,
								status: response.status
							}
							worker.postMessage(responseObj);
						},
						headers: request.headers,
						content: request.data
					}).get();
				}

				break;
			case 'createTab':
				var focus = (request.background != true);
				tabs.open({url: request.url, inBackground: !focus });
				worker.postMessage({status: "success"});
				break;
			case 'createNotification':
				if (!request.icon) {
					// if no icon specified, make a single pixel empty gif so we don't get a broken image link.
					request.icon = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
				}
				notifications.notify({
				  title: request.title,
				  text: request.text,
				  iconURL: request.icon
				});
				break;
			case 'localStorage':
				switch (request.operation) {
					case 'getItem':
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: localStorage.getItem(request.itemName)
						});
						break;
					case 'removeItem':
						localStorage.removeItem(request.itemName);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							value: null
						});
						break;
					case 'setItem':
						localStorage.setItem(request.itemName, request.itemValue);
						worker.postMessage({
							name: 'localStorage',
							callbackID: request.callbackID,
							status: true,
							key: request.itemName,
							value: request.itemValue
						});
						break;
				}
				break;
			case 'addURLToHistory':
				var uri = makeURI(request.url);
				historyService.addURI(uri, false, true, null);
				break;
			default:
				worker.postMessage({status: "unrecognized request type"});
				break;
		}

	});
  }
});

<|endoftext|>