<commit_before>/*
  Copyright 2016 Google Inc. All Rights Reserved.

  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.
*/

'use strict';

/* eslint-disable max-len, no-console, padded-blocks, no-multiple-empty-lines */
/* eslint-env node,mocha */

// These tests make use of selenium-webdriver. You can find the relevant
// documentation here: http://selenium.googlecode.com/git/docs/api/javascript/index.html

require('chai').should();
const path = require('path');
const seleniumAssistant = require('selenium-assistant');
const mochaUtils = require('sw-testing-helpers').mochaUtils;

const testServer = require('./server/index.js');

describe('Test SW-Toolbox', function() {
  // Browser tests can be slow
  // 2016-03-29 FF v45 keeps exceeding timeouts of 60000,
  // so bumped up the limit
  this.timeout(100000);

  // Driver is initialised to null to handle scenarios
  // where the desired browser isn't installed / fails to load
  // Null allows afterEach a safe way to skip quiting the driver
  let globalDriverReference = null;
  let testServerURL;

  before(function() {
    return testServer.startServer(path.join(__dirname, '..'))
    .then(portNumber => {
      testServerURL = `http://localhost:${portNumber}`;
    });
  });

  after(function() {
    testServer.killServer();
  });

  afterEach(function() {
    this.timeout(10000);

    return seleniumAssistant.killWebDriver(globalDriverReference);
  });

  const queueUnitTest = browserInfo => {
    it(`should pass all tests in ${browserInfo.getPrettyName()}`, () => {
      return browserInfo.getSeleniumDriver()
      .then(driver => {
        globalDriverReference = driver;
        return mochaUtils.startWebDriverMochaTests(
          browserInfo.getPrettyName(),
          globalDriverReference,
          `${testServerURL}/test/browser-tests/`
        );
      })
      .then(testResults => {
        if (testResults.failed.length > 0) {
          const errorMessage = mochaUtils.prettyPrintErrors(
            browserInfo.prettyName,
            testResults
          );

          throw new Error(errorMessage);
        }
      });
    });
  };

  seleniumAssistant.printAvailableBrowserInfo();

  const automatedBrowsers = seleniumAssistant.getAvailableBrowsers();
  automatedBrowsers.forEach(browserInfo => {
    // Tests are running a differently from mocha compared to gulp test:manual
    // :( Results in errors that can't be debugged
    if (browserInfo.getSeleniumBrowserId() === 'firefox' &&
      browserInfo.getVersionNumber() <= 50) {
      console.log('Skipping ' + browserInfo.getRawVersionString());
      return;
    }

    // Block non-service worker browsers from being included in the tests
    if (browserInfo.getSeleniumBrowserId() !== 'firefox' &&
      browserInfo.getSeleniumBrowserId() !== 'chrome') {
      return;
    }

    queueUnitTest(browserInfo);
  });
});
<commit_msg>automated-suite: minor comment updates<commit_after>/*
  Copyright 2016 Google Inc. All Rights Reserved.

  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.
*/

'use strict';

/* eslint-disable max-len, no-console, padded-blocks, no-multiple-empty-lines */
/* eslint-env node,mocha */

// These tests make use of selenium-webdriver. You can find the relevant
// documentation here: http://selenium.googlecode.com/git/docs/api/javascript/index.html

require('chai').should();
const path = require('path');
const seleniumAssistant = require('selenium-assistant');
const mochaUtils = require('sw-testing-helpers').mochaUtils;

const testServer = require('./server/index.js');

describe('Test SW-Toolbox', function() {
  // Browser tests can be slow
  // 2016-03-29 FF v45 keeps exceeding timeouts of 60000,
  // so bumped up the limit
  // TODO: Verify FF.latest no longer has these timeout issues
  this.timeout(100000);

  // Driver is initialised to `null` to handle scenarios
  // where the desired browser isn't installed / fails to load
  // `null` allows afterEach a safe way to skip quiting the driver
  let globalDriverReference = null;
  let testServerURL;

  before(function() {
    return testServer.startServer(path.join(__dirname, '..'))
    .then(portNumber => {
      testServerURL = `http://localhost:${portNumber}`;
    });
  });

  after(function() {
    testServer.killServer();
  });

  afterEach(function() {
    this.timeout(10000);

    return seleniumAssistant.killWebDriver(globalDriverReference);
  });

  const queueUnitTest = browserInfo => {
    it(`should pass all tests in ${browserInfo.getPrettyName()}`, () => {
      return browserInfo.getSeleniumDriver()
      .then(driver => {
        globalDriverReference = driver;
        return mochaUtils.startWebDriverMochaTests(
          browserInfo.getPrettyName(),
          globalDriverReference,
          `${testServerURL}/test/browser-tests/`
        );
      })
      .then(testResults => {
        if (testResults.failed.length > 0) {
          const errorMessage = mochaUtils.prettyPrintErrors(
            browserInfo.prettyName,
            testResults
          );

          throw new Error(errorMessage);
        }
      });
    });
  };

  seleniumAssistant.printAvailableBrowserInfo();

  const automatedBrowsers = seleniumAssistant.getAvailableBrowsers();
  automatedBrowsers.forEach(browserInfo => {
    // Tests are running differently from mocha compared to gulp test:manual
    // :( Results in errors that can't be debugged
    if (browserInfo.getSeleniumBrowserId() === 'firefox' &&
      browserInfo.getVersionNumber() <= 50) {
      console.log('Skipping ' + browserInfo.getRawVersionString());
      return;
    }

    // Block browsers w/o Service Worker support from being included in the tests
    if (browserInfo.getSeleniumBrowserId() !== 'firefox' &&
      browserInfo.getSeleniumBrowserId() !== 'chrome') {
      return;
    }

    queueUnitTest(browserInfo);
  });
});
<|endoftext|>


<commit_before>// ==UserScript==
// @name         MixerBox+
// @namespace    https://github.com/happydenn/mixerbox-plus
// @version      0.3.0
// @description  Custom controls for MixerBox Web.
// @author       happydenn
// @grant        none
// @match        *://www.mixerbox.com/*
// @match        *://spider1.cdn-network1.com/*
// ==/UserScript==

!function(e){function t(o){if(n[o])return n[o].exports;var a=n[o]={i:o,l:!1,exports:{}};return e[o].call(a.exports,a,a.exports,t),a.l=!0,a.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=2)}([function(e,t,n){"use strict";function o(){console.log("MixerBox+ loaded."),(i=document.getElementById("MB-player-iframe"))&&(i.setAttribute("allowfullscreen",""),setInterval(a,350))}function a(){var e=document.querySelectorAll(".playlist-item-container:not(.mbplus-annotated)");0!==e.length&&e.forEach(function(e){e.querySelectorAll(".song-row").forEach(function(e){var t=e.querySelector(".thumbnailContainer > img"),o=t.src.match(/.+:\/\/i\.ytimg\.com\/vi\/(.+)\/hqdefault\.jpg/i)[1],a=e.querySelector(".title"),i=n.i(r.a)(o);a.appendChild(i)}),e.classList.add("mbplus-annotated")})}t.a=o;var r=n(3),i=void 0},function(e,t,n){"use strict";function o(){window.onYouTubeIframeAPIReady=function(){window.MBYTPlayer=new YT.Player("yt-player-div",{height:"100%",width:"100%",playerVars:{playsinline:1,controls:1,showinfo:0,rel:0,start:0,enablejsapi:1,iv_load_policy:3,origin:window.MB_DOMAIN_NAME},events:{onReady:window.onPlayerReady,onStateChange:window.onPlayerStateChange,onError:window.onPlayerError}}),a=window.MBYTPlayer,a.addEventListener("onStateChange",function(e){if(e.data===YT.PlayerState.PLAYING){var t=a.getAvailableQualityLevels(),n=a.getPlaybackQuality();t[0]!==n&&(console.log("Automatically changing quality level to "+t[0]),a.setPlaybackQuality(t[0]))}})}}t.a=o;var a=void 0},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0),a=n(1);window.location.host.includes("cdn-network1.com")?n.i(a.a)():window.location.host.includes("mixerbox.com")&&n.i(o.a)()},function(e,t,n){"use strict";function o(e){var t=document.createElement("a");return t.setAttribute("href","#"),t.textContent="Download MP3",t.style.marginLeft="10px",t.style.display="inline-block",t.style.borderBottom="1px dotted #37b9eb",t.style.color="#37b9eb",t.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation(),window.open("https://www.youtubeinmp3.com/fetch/?video="+encodeURIComponent("https://www.youtube.com/watch?v="+e))}),t}t.a=o}]);<commit_msg>bump version to 0.3.1<commit_after>// ==UserScript==
// @name         MixerBox+
// @namespace    https://github.com/happydenn/mixerbox-plus
// @version      0.3.1
// @description  Custom controls for MixerBox Web.
// @author       happydenn
// @grant        none
// @match        *://www.mixerbox.com/*
// @match        *://spider1.cdn-network1.com/*
// ==/UserScript==

!function(e){function t(o){if(n[o])return n[o].exports;var a=n[o]={i:o,l:!1,exports:{}};return e[o].call(a.exports,a,a.exports,t),a.l=!0,a.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=2)}([function(e,t,n){"use strict";function o(){console.log("MixerBox+ loaded."),(i=document.getElementById("MB-player-iframe"))&&(i.setAttribute("allowfullscreen",""),setInterval(a,350))}function a(){var e=document.querySelectorAll(".playlist-item-container:not(.mbplus-annotated)");0!==e.length&&e.forEach(function(e){e.querySelectorAll(".song-row").forEach(function(e){var t=e.querySelector(".thumbnailContainer > img"),o=t.src.match(/.+:\/\/i\.ytimg\.com\/vi\/(.+)\/hqdefault\.jpg/i)[1],a=e.querySelector(".title"),i=n.i(r.a)(o);a.appendChild(i)}),e.classList.add("mbplus-annotated")})}t.a=o;var r=n(3),i=void 0},function(e,t,n){"use strict";function o(){window.onYouTubeIframeAPIReady=function(){window.MBYTPlayer=new YT.Player("yt-player-div",{height:"100%",width:"100%",playerVars:{playsinline:1,controls:1,showinfo:0,rel:0,start:0,enablejsapi:1,iv_load_policy:3,origin:window.MB_DOMAIN_NAME},events:{onReady:window.onPlayerReady,onStateChange:window.onPlayerStateChange,onError:window.onPlayerError}}),a=window.MBYTPlayer,a.addEventListener("onStateChange",function(e){if(e.data===YT.PlayerState.PLAYING){var t=a.getAvailableQualityLevels(),n=a.getPlaybackQuality();t[0]!==n&&(console.log("Automatically changing quality level to "+t[0]),a.setPlaybackQuality(t[0]))}})}}t.a=o;var a=void 0},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(0),a=n(1);window.location.host.includes("cdn-network1.com")?n.i(a.a)():window.location.host.includes("mixerbox.com")&&n.i(o.a)()},function(e,t,n){"use strict";function o(e){var t=document.createElement("a");return t.setAttribute("href","#"),t.textContent="Download MP3",t.style.marginLeft="10px",t.style.display="inline-block",t.style.borderBottom="1px dotted #37b9eb",t.style.color="#37b9eb",t.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation(),window.open("https://www.youtubeinmp3.com/fetch/?video="+encodeURIComponent("https://www.youtube.com/watch?v="+e))}),t}t.a=o}]);<|endoftext|>


<commit_before>import { createSelector as defaultCreateSelector, createSelectorCreator } from 'reselect'
import createCachedSelector from 're-reselect'
import memoizeWithCacheSize from './lib/memoizeWithCacheSize'

const shallowEqual = (a, b) => a === b
const nativeIsArray = Array.isArray
const toString = Object.prototype.toString
const isArray = nativeIsArray || ((o) => toString.call(o) === '[object Array]')

const defineSelector = ( key, selectors, definedSelectors ) => {
  if( definedSelectors[ key ] === 'ing' ) {
    throw new Error('FOUND_CIRCULAR_REFERENCE')
  }

  if( typeof definedSelectors[key] === 'function' ) {
    return definedSelectors[key]
  }

  definedSelectors[key] = 'ing'

  const data = selectors[key]
  const isArrayData = isArray(data)

  let inputSelectors, resultFunc, resolverFunc, cacheSize, createSelector

  if( isArrayData ) {
    inputSelectors = data[0]
    resultFunc = data[1]
    resolverFunc = data[2]
    cacheSize = data[3] || 1
    createSelector = data[4]
  } else {
    inputSelectors = data.inputSelectors
    resultFunc = data.resultFunc
    resolverFunc = data.resolverFunc
    cacheSize = data.cacheSize
    createSelector = data.customSelectorCreator
  }

  if( createSelector && cacheSize > 1 ) {
    console.error('when cacheSize > 1, built-in createSelector is used. You can not define cacheSize and customSelectorCreator at the same time.')
    throw new Error('WRONG_CACHE_SIZE_AND_CUSTOM_SELECTOR_CREATOR')
  }

  createSelector = cacheSize > 1 ?
    createSelectorCreator( memoizeWithCacheSize, shallowEqual, cacheSize ) :
    defaultCreateSelector

  // magic
  inputSelectors = inputSelectors.map( s => {
    if( s === void 0 ) {
      console.error( 'selector key: ' + key )
      throw new Error('FOUND_UNDEFINED_INPUT_SELECTOR')
    }
    return typeof s === 'string' ? defineSelector( s, selectors, definedSelectors ) : s
  })

  if( resolverFunc ) {
    definedSelectors[key] = createCachedSelector( inputSelectors, resultFunc )( resolverFunc, createSelector )
  } else {
    definedSelectors[key] = createSelector( inputSelectors, resultFunc )
  }

  return definedSelectors[key]
}

export default ( selectors ) => {
  const definedSelectors = {}
  Object.keys( selectors ).map( key => {
    defineSelector( key, selectors, definedSelectors )
  })

 return definedSelectors
}
<commit_msg>for code coverage test<commit_after>import { createSelector as defaultCreateSelector, createSelectorCreator } from 'reselect'
import createCachedSelector from 're-reselect'
import memoizeWithCacheSize from './lib/memoizeWithCacheSize'

const shallowEqual = (a, b) => a === b
const nativeIsArray = Array.isArray
const toString = Object.prototype.toString
const isArray = nativeIsArray ||
  ((o) => toString.call(o) === '[object Array]')

const defineSelector = ( key, selectors, definedSelectors ) => {
  if( definedSelectors[ key ] === 'ing' ) {
    throw new Error('FOUND_CIRCULAR_REFERENCE')
  }

  if( typeof definedSelectors[key] === 'function' ) {
    return definedSelectors[key]
  }

  definedSelectors[key] = 'ing'

  const data = selectors[key]
  const isArrayData = isArray(data)

  let inputSelectors, resultFunc, resolverFunc, cacheSize, createSelector

  if( isArrayData ) {
    inputSelectors = data[0]
    resultFunc = data[1]
    resolverFunc = data[2]
    cacheSize = data[3] || 1
    createSelector = data[4]
  } else {
    inputSelectors = data.inputSelectors
    resultFunc = data.resultFunc
    resolverFunc = data.resolverFunc
    cacheSize = data.cacheSize
    createSelector = data.customSelectorCreator
  }

  if( createSelector && cacheSize > 1 ) {
    console.error('when cacheSize > 1, built-in createSelector is used. You can not define cacheSize and customSelectorCreator at the same time.')
    throw new Error('WRONG_CACHE_SIZE_AND_CUSTOM_SELECTOR_CREATOR')
  }

  createSelector = cacheSize > 1 ?
    createSelectorCreator( memoizeWithCacheSize, shallowEqual, cacheSize ) :
    defaultCreateSelector

  // magic
  inputSelectors = inputSelectors.map( s => {
    if( s === void 0 ) {
      console.error( 'selector key: ' + key )
      throw new Error('FOUND_UNDEFINED_INPUT_SELECTOR')
    }
    return typeof s === 'string' ? defineSelector( s, selectors, definedSelectors ) : s
  })

  if( resolverFunc ) {
    definedSelectors[key] = createCachedSelector( inputSelectors, resultFunc )( resolverFunc, createSelector )
  } else {
    definedSelectors[key] = createSelector( inputSelectors, resultFunc )
  }

  return definedSelectors[key]
}

export default ( selectors ) => {
  const definedSelectors = {}
  Object.keys( selectors ).map( key => {
    defineSelector( key, selectors, definedSelectors )
  })

 return definedSelectors
}
<|endoftext|>


<commit_before>describe("Beautylist", function() {

  beforeEach(createBeautyList)
  afterEach(resetHtml)

  it("exposes an api", function() {
    expect(originalInput().data('beautyList')).toBeTruthy()
  })

  it("creates dom elements for tag list and input", function() {
    expect($('.beautylist-input').length).toEqual(1)
    expect($('.beautylist').length).toEqual(1)
  })

  describe("creates list elements", function() {

    it('does not create element when no comma entered', function() {
      beautyListInput().val('lol').trigger('keyup')
      expect(beautyListItems().length).toEqual(0)
      expect(originalInput().val()).toEqual('')
    })

    it('creates an element on blur', function() {
      beautyListInput().val('lol').trigger('blur')
      expect(beautyListItems().length).toEqual(1)
      expect($('.beautylist .beautylist-item:first').data('beautylist-value')).toEqual('lol')
      expect(originalInput().val()).toEqual('lol')
    })

    it('does not create an element on blur when no text entered', function() {
      beautyListInput().val('').trigger('blur')
      expect(beautyListItems().length).toEqual(0)
      expect(originalInput().val()).toEqual('')
    })

    it('creates multiple elements when string with commas entered', function() {
      beautyListInput().val('lol,bal,bar').trigger('keyup')
      expect(beautyListItems().length).toEqual(3)
      expect(originalInput().val()).toEqual('lol, bal, bar')
    })

    it('creates multiple elements when string with spaces entered', function() {
      beautyListInput().val('lol bal bar').trigger('keyup')
      expect(beautyListItems().length).toEqual(3)
      expect(originalInput().val()).toEqual('lol, bal, bar')
    })

    it('creates multiple elements when string with semicolons entered', function() {
      beautyListInput().val('lol;bal; bar').trigger('keyup')
      expect(beautyListItems().length).toEqual(3)
      expect(originalInput().val()).toEqual('lol, bal, bar')
    })
  })

  describe('deleting list elements', function(){
    beforeEach(function() {
      beautyListInput().val('lol,bal,bar').trigger('keyup')
    })

    it('deletes an item when clicked on delete icon', function() {
      beautyListItems().eq(0).find('.beautylist-delete-item').trigger('click')

      waitsFor(function() { return beautyListItems().length === 2 }, 500)
      runs(function() {
        expect(beautyListItems().length).toEqual(2)
        expect(originalInput().val()).toEqual('bal, bar')
      })
    })

    it('does not delete an item when pressing backspace on input with text', function() {
      beautyListInput().val('lol').trigger({type: 'keydown', which : 8 })

      waitsFor(function() { return beautyListItems().length === 3 }, 500)
      runs(function() {
        expect(beautyListItems().length).toEqual(3)
        expect(originalInput().val()).toEqual('lol, bal, bar')
      })
    })

    it('deletes a focused item on backspace', function() {
      beautyListInput().val('').trigger({type: 'keydown', which : 8 })
      beautyListItems().last().find('a:focus').trigger({type: 'keydown', which : 8 })
      waitsFor(function() { return beautyListItems().length === 2 }, 500)
      runs(function() {
        expect(beautyListItems().length).toEqual(2)
        expect(originalInput().val()).toEqual('lol, bal')
      })
    })
  })

  describe('keyboard events', function(){
    beforeEach(function() { beautyListInput().val('lol,bal,bar').trigger('keyup')})

    it('focuses on list element when backspacing on empty input', function() {
      beautyListInput().focus().val('').trigger({type: 'keydown', which : 8 })
      expect(beautyListItems().last().find('a:focus').length).toEqual(1)
    })

    it('moves to previous item when pressing left arrow', function() {
      beautyListInput().val('').trigger({type: 'keydown', which : 8 })
      beautyListItems().last().find(' a:focus').trigger({type: 'keydown', which : 37 })
      expect($('.beautylist-item').eq(1).find('a').is(':focus')).toBeTruthy()
    })

    it('moves to next item when pressing right arrow', function() {
      beautyListInput().val('').trigger({type: 'keydown', which : 8 })
      beautyListItems().last().find(' a')
        .trigger({type: 'keydown', which : 37 }) // move left
        .trigger({type: 'keydown', which : 37 }) // move left
        .trigger({type: 'keydown', which : 39 }) // ...and then right

      expect(beautyListItems().eq(1).find('a').is(':focus')).toBeTruthy()
    })
  })

  describe('in-place edit', function() {
    beforeEach(function() {
      beautyListInput().val('a').trigger({type: 'keydown', which : 13 })
      beautyListContainer().find('.beautylist-item a').trigger('click')
    })

    it('creates an in-place-edit when clicked', function() {
      expect($('.beautylist-item .beautylist-in-place-edit').length).toEqual(1)
    })

    it('changes the value', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('bal').blur()
      var item = beautyListItems().eq(0)
      expect(item.data('beautylist-value')).toEqual('bal')
      expect(item.find('span').text()).toEqual('bal')
      expect(item.find('span:visible').length).toEqual(1)
      expect(item.find('.beautylist-in-place-edit').length).toEqual(0)
      expect(originalInput().val()).toEqual('bal')
    })

    it('marks the value as invalid after edit', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('bal').blur()
      var item = beautyListItems().eq(0)
      expect(beautyListItems().data('beautylist-value')).toEqual('bal')
      expect(item.find('span').text()).toEqual('bal')
      expect(item.find('span:visible').length).toEqual(1)
      expect(item).toHaveClass('invalid')
      expect(originalInput().val()).toEqual('bal')
    })

    it('marks the value as invalid after adding separators', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('bal lol').blur()
      var item = beautyListItems().eq(0)
      expect(beautyListItems().data('beautylist-value')).toEqual('bal lol')
      expect(item.find('span').text()).toEqual('bal lol')
      expect(item.find('span:visible').length).toEqual(1)
      expect(item).toHaveClass('invalid')
      expect(originalInput().val()).toEqual('bal lol')
    })

    it('does not delete the item when backspacing on empty in-place-edit', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('').trigger({type: 'keydown', which : 8 })
      expect(beautyListItems().length).toEqual(1)
    })

    it('deletes the item blurring from empty in-place-edit', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('').blur()
      waitsFor(function() { return beautyListItems().length === 0 }, 500)
      runs(function() { expect(beautyListItems().length).toEqual(0) })
    })
  })

  describe('keyboard events', function() {
    beforeEach(function() { beautyListInput().val('lol') })

    it('creates an item when pressing enter', function() {
      beautyListInput().trigger({type: 'keydown', which : 13 })
      expect(beautyListItems().length).toEqual(1)
    })
  })
})

describe("Beautylist with options", function() {

  afterEach(resetHtml)

  describe('using validators', function(){
    beforeEach(createBeautyList)

    it('does not add invalid class with valid input', function() {
      beautyListInput().val('a').trigger('blur')
      expect($('.beautylist .beautylist-item.invalid').length).toEqual(0)
    })
    it('adds invalid class with invalid input', function() {
      beautyListInput().val('b').trigger('blur')
      expect($('.beautylist .beautylist-item.invalid').length).toEqual(1)
    })
  })

  describe('using allowDuplicates:false', function(){
    beforeEach(function() { createBeautyList({allowDuplicates: false}) })

    it('does not add invalid class on items with different values', function() {
      beautyListInput().val('a b c').trigger('blur')
      expect($('.beautylist .beautylist-item.invalid').length).toEqual(0)
    })

    it('adds invalid class on items with same values', function() {
      beautyListInput().val('a a b').trigger('blur')
      expect(beautyListItems().eq(0)).toHaveClass('invalid')
      expect(beautyListItems().eq(1)).toHaveClass('invalid')
      expect(beautyListItems().eq(2)).not.toHaveClass('invalid')
    })
  })

  describe('using inPlaceEdit: false', function(){
    beforeEach(function() { createBeautyList({inPlaceEdit: false}) })

    it('does not add in-place edit when clicked on element', function() {
      beautyListInput().val('lol').trigger({type: 'keydown', which : 13 })
      beautyListContainer().find('.beautylist-item span').trigger('click')
      expect($('.beautylist-item .beautylist-in-place-edit').length).toEqual(0)
    })

    it('focuses on item when clicked', function() {
      beautyListInput().val('lol').trigger({type: 'keydown', which : 13 })
      beautyListContainer().find('.beautylist-item a').trigger('click')
      expect($('.beautylist-item .beautylist-in-place-edit').length).toEqual(0)
      expect($('.beautylist-item a:focus').length).toEqual(1)
    })
  })
})

describe('input behavior', function() {

  describe("Dynamically changing input size", function() {
    afterEach(function() { $('#wrapper, .beautylist').remove() })

    describe('using validators', function(){
      beforeEach(function() {  createBeautyList({dynamicInputSizing: true}) })
      // TODO: $(elem).css returns pixels, not percents
      xit('initally sets input width to 100%', function() {
        expect(blInput.css('width')).toEqual('400px')
        expect(blInput.parent().css('width')).toEqual('400px')
      })

      it('resizes on keydown', function() {
        beautyListInput().val('b').trigger('keydown')
        expect(beautyListInput().width()).toBeLessThan(400)
      })

      // TODO: pick a correct width... or something
      xit('resizes to auto on blur', function() {
        beautyListInput().val('').trigger('blur')
        expect(beautyListInput().css('width')).toEqual('auto')
      })
    })
  })
})

describe('with pre-existing values', function() {
  describe('with space as a separator', function() {
    beforeEach(function() {
      stubHtml()
      $('#element-1').val('foo bar baz')
      initBeautyList()
    })
    afterEach(resetHtml)

    it('creates elements', function() {
      expect(beautyListItems().length).toEqual(3)
      expect(beautyListItems().eq(0).data('beautylist-value')).toEqual('foo')
      expect(beautyListItems().eq(1).data('beautylist-value')).toEqual('bar')
      expect(beautyListItems().eq(2).data('beautylist-value')).toEqual('baz')
    })
  })

  describe('with comma as a separator', function() {
    beforeEach(function() {
      stubHtml()
      $('#element-1').val('foo,bar,baz')
      initBeautyList()
    })
    afterEach(resetHtml)

    it('creates elements and sets their beautylist-value data attributes', function() {
      expect(beautyListItems().length).toEqual(3)
      expect(beautyListItems().eq(0).data('beautylist-value')).toEqual('foo')
      expect(beautyListItems().eq(1).data('beautylist-value')).toEqual('bar')
      expect(beautyListItems().eq(2).data('beautylist-value')).toEqual('baz')
    })
  })
})

function createBeautyList(params) {
  stubHtml()
  initBeautyList(params)
}

function initBeautyList(params) {
  if(!params) params = { inPlaceEdit: true, validators: [ function(equalsA) { return equalsA === 'a'}] }
  $('#element-1').beautyList(params)
}
function stubHtml() {
  $('#test-area').append('
<input id="element-1" type="text" />
')
}
function resetHtml(){ $('#element-1, .beautylist').remove() }
function beautyListInput() { return $('.beautylist-input') }
function originalInput() { return $('#element-1') }
function beautyListContainer() { return $('.beautylist ul') }
function beautyListItems() { return $('.beautylist .beautylist-item') }<commit_msg>Extract element creations and deletions in spec to functions<commit_after>describe("Beautylist", function() {

  beforeEach(createBeautyList)
  afterEach(resetHtml)

  it("exposes an api", function() {
    expect(originalInput().data('beautyList')).toBeTruthy()
  })

  it("creates dom elements for tag list and input", function() {
    expect($('.beautylist-input').length).toEqual(1)
    expect($('.beautylist').length).toEqual(1)
  })

  describe("creates list elements", function() {
    testElementCreation()
  })

  describe('deleting list elements', function(){
    beforeEach(function() {
      beautyListInput().val('lol,bal,bar').trigger('keyup')
    })
    testElementDeletion()
  })

  describe('keyboard events', function(){
    beforeEach(function() { beautyListInput().val('lol,bal,bar').trigger('keyup')})

    it('focuses on list element when backspacing on empty input', function() {
      beautyListInput().focus().val('').trigger({type: 'keydown', which : 8 })
      expect(beautyListItems().last().find('a:focus').length).toEqual(1)
    })

    it('moves to previous item when pressing left arrow', function() {
      beautyListInput().val('').trigger({type: 'keydown', which : 8 })
      beautyListItems().last().find(' a:focus').trigger({type: 'keydown', which : 37 })
      expect($('.beautylist-item').eq(1).find('a').is(':focus')).toBeTruthy()
    })

    it('moves to next item when pressing right arrow', function() {
      beautyListInput().val('').trigger({type: 'keydown', which : 8 })
      beautyListItems().last().find(' a')
        .trigger({type: 'keydown', which : 37 }) // move left
        .trigger({type: 'keydown', which : 37 }) // move left
        .trigger({type: 'keydown', which : 39 }) // ...and then right

      expect(beautyListItems().eq(1).find('a').is(':focus')).toBeTruthy()
    })
  })

  describe('in-place edit', function() {
    beforeEach(function() {
      beautyListInput().val('a').trigger({type: 'keydown', which : 13 })
      beautyListContainer().find('.beautylist-item a').trigger('click')
    })

    it('creates an in-place-edit when clicked', function() {
      expect($('.beautylist-item .beautylist-in-place-edit').length).toEqual(1)
    })

    it('changes the value', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('bal').blur()
      var item = beautyListItems().eq(0)
      expect(item.data('beautylist-value')).toEqual('bal')
      expect(item.find('span').text()).toEqual('bal')
      expect(item.find('span:visible').length).toEqual(1)
      expect(item.find('.beautylist-in-place-edit').length).toEqual(0)
      expect(originalInput().val()).toEqual('bal')
    })

    it('marks the value as invalid after edit', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('bal').blur()
      var item = beautyListItems().eq(0)
      expect(beautyListItems().data('beautylist-value')).toEqual('bal')
      expect(item.find('span').text()).toEqual('bal')
      expect(item.find('span:visible').length).toEqual(1)
      expect(item).toHaveClass('invalid')
      expect(originalInput().val()).toEqual('bal')
    })

    it('marks the value as invalid after adding separators', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('bal lol').blur()
      var item = beautyListItems().eq(0)
      expect(beautyListItems().data('beautylist-value')).toEqual('bal lol')
      expect(item.find('span').text()).toEqual('bal lol')
      expect(item.find('span:visible').length).toEqual(1)
      expect(item).toHaveClass('invalid')
      expect(originalInput().val()).toEqual('bal lol')
    })

    it('does not delete the item when backspacing on empty in-place-edit', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('').trigger({type: 'keydown', which : 8 })
      expect(beautyListItems().length).toEqual(1)
    })

    it('deletes the item blurring from empty in-place-edit', function() {
      $('.beautylist-item .beautylist-in-place-edit').val('').blur()
      waitsFor(function() { return beautyListItems().length === 0 }, 500)
      runs(function() { expect(beautyListItems().length).toEqual(0) })
    })
  })

  describe('keyboard events', function() {
    beforeEach(function() { beautyListInput().val('lol') })

    it('creates an item when pressing enter', function() {
      beautyListInput().trigger({type: 'keydown', which : 13 })
      expect(beautyListItems().length).toEqual(1)
    })
  })
})

describe("Beautylist with options", function() {

  afterEach(resetHtml)

  describe('using validators', function(){
    beforeEach(createBeautyList)

    it('does not add invalid class with valid input', function() {
      beautyListInput().val('a').trigger('blur')
      expect($('.beautylist .beautylist-item.invalid').length).toEqual(0)
    })
    it('adds invalid class with invalid input', function() {
      beautyListInput().val('b').trigger('blur')
      expect($('.beautylist .beautylist-item.invalid').length).toEqual(1)
    })
  })

  describe('using allowDuplicates:false', function(){
    beforeEach(function() { createBeautyList({allowDuplicates: false}) })

    it('does not add invalid class on items with different values', function() {
      beautyListInput().val('a b c').trigger('blur')
      expect($('.beautylist .beautylist-item.invalid').length).toEqual(0)
    })

    it('adds invalid class on items with same values', function() {
      beautyListInput().val('a a b').trigger('blur')
      expect(beautyListItems().eq(0)).toHaveClass('invalid')
      expect(beautyListItems().eq(1)).toHaveClass('invalid')
      expect(beautyListItems().eq(2)).not.toHaveClass('invalid')
    })
  })

  describe('using inPlaceEdit: false', function(){
    beforeEach(function() { createBeautyList({inPlaceEdit: false}) })

    it('does not add in-place edit when clicked on element', function() {
      beautyListInput().val('lol').trigger({type: 'keydown', which : 13 })
      beautyListContainer().find('.beautylist-item span').trigger('click')
      expect($('.beautylist-item .beautylist-in-place-edit').length).toEqual(0)
    })

    it('focuses on item when clicked', function() {
      beautyListInput().val('lol').trigger({type: 'keydown', which : 13 })
      beautyListContainer().find('.beautylist-item a').trigger('click')
      expect($('.beautylist-item .beautylist-in-place-edit').length).toEqual(0)
      expect($('.beautylist-item a:focus').length).toEqual(1)
    })
  })
})

describe('input behavior', function() {

  describe("Dynamically changing input size", function() {
    afterEach(function() { $('#wrapper, .beautylist').remove() })

    describe('using validators', function(){
      beforeEach(function() {  createBeautyList({dynamicInputSizing: true}) })
      // TODO: $(elem).css returns pixels, not percents
      xit('initally sets input width to 100%', function() {
        expect(blInput.css('width')).toEqual('400px')
        expect(blInput.parent().css('width')).toEqual('400px')
      })

      it('resizes on keydown', function() {
        beautyListInput().val('b').trigger('keydown')
        expect(beautyListInput().width()).toBeLessThan(400)
      })

      // TODO: pick a correct width... or something
      xit('resizes to auto on blur', function() {
        beautyListInput().val('').trigger('blur')
        expect(beautyListInput().css('width')).toEqual('auto')
      })
    })
  })
})

describe('with pre-existing values', function() {
  describe('with space as a separator', function() {
    beforeEach(function() {
      stubHtml()
      $('#element-1').val('foo bar baz')
      initBeautyList()
    })
    afterEach(resetHtml)

    it('creates elements', function() {
      expect(beautyListItems().length).toEqual(3)
      expect(beautyListItems().eq(0).data('beautylist-value')).toEqual('foo')
      expect(beautyListItems().eq(1).data('beautylist-value')).toEqual('bar')
      expect(beautyListItems().eq(2).data('beautylist-value')).toEqual('baz')
    })
  })

  describe('with comma as a separator', function() {
    beforeEach(function() {
      stubHtml()
      $('#element-1').val('foo,bar,baz')
      initBeautyList()
    })
    afterEach(resetHtml)

    it('creates elements and sets their beautylist-value data attributes', function() {
      expect(beautyListItems().length).toEqual(3)
      expect(beautyListItems().eq(0).data('beautylist-value')).toEqual('foo')
      expect(beautyListItems().eq(1).data('beautylist-value')).toEqual('bar')
      expect(beautyListItems().eq(2).data('beautylist-value')).toEqual('baz')
    })
  })
})

function createBeautyList(params) {
  stubHtml()
  initBeautyList(params)
}

function initBeautyList(params) {
  if(!params) params = { inPlaceEdit: true, validators: [ function(equalsA) { return equalsA === 'a'}] }
  $('#element-1').beautyList(params)
}
function stubHtml() {
  $('#test-area').append('
<input id="element-1" type="text" />
')
}

function resetHtml(){ $('#element-1, .beautylist').remove() }
function beautyListInput() { return $('.beautylist-input') }
function originalInput() { return $('#element-1') }
function beautyListContainer() { return $('.beautylist ul') }
function beautyListItems() { return $('.beautylist .beautylist-item') }

function testElementCreation() {
  it('does not create element when no comma entered', function() {
    beautyListInput().val('lol').trigger('keyup')
    expect(beautyListItems().length).toEqual(0)
    expect(originalInput().val()).toEqual('')
  })

  it('creates an element on blur', function() {
    beautyListInput().val('lol').trigger('blur')
    expect(beautyListItems().length).toEqual(1)
    expect($('.beautylist .beautylist-item:first').data('beautylist-value')).toEqual('lol')
    expect(originalInput().val()).toEqual('lol')
  })

  it('does not create an element on blur when no text entered', function() {
    beautyListInput().val('').trigger('blur')
    expect(beautyListItems().length).toEqual(0)
    expect(originalInput().val()).toEqual('')
  })

  it('creates multiple elements when string with commas entered', function() {
    beautyListInput().val('lol,bal,bar').trigger('keyup')
    expect(beautyListItems().length).toEqual(3)
    expect(originalInput().val()).toEqual('lol, bal, bar')
  })

  it('creates multiple elements when string with spaces entered', function() {
    beautyListInput().val('lol bal bar').trigger('keyup')
    expect(beautyListItems().length).toEqual(3)
    expect(originalInput().val()).toEqual('lol, bal, bar')
  })

  it('creates multiple elements when string with semicolons entered', function() {
    beautyListInput().val('lol;bal; bar').trigger('keyup')
    expect(beautyListItems().length).toEqual(3)
    expect(originalInput().val()).toEqual('lol, bal, bar')
  })
}

function testElementDeletion() {
  it('deletes an item when clicked on delete icon', function() {
    beautyListItems().eq(0).find('.beautylist-delete-item').trigger('click')

    waitsFor(function() { return beautyListItems().length === 2 }, 500)
    runs(function() {
      expect(beautyListItems().length).toEqual(2)
      expect(originalInput().val()).toEqual('bal, bar')
    })
  })

  it('does not delete an item when pressing backspace on input with text', function() {
    beautyListInput().val('lol').trigger({type: 'keydown', which : 8 })

    waitsFor(function() { return beautyListItems().length === 3 }, 500)
    runs(function() {
      expect(beautyListItems().length).toEqual(3)
      expect(originalInput().val()).toEqual('lol, bal, bar')
    })
  })

  it('deletes a focused item on backspace', function() {
    beautyListInput().val('').trigger({type: 'keydown', keyCode: 8, which : 8 })
    beautyListItems().last().find('a:focus').trigger({type: 'keydown', keyCode: 8, which : 8 })
    waitsFor(function() { return beautyListItems().length === 2 }, 5000)
    runs(function() {
      expect(beautyListItems().length).toEqual(2)
      expect(originalInput().val()).toEqual('lol, bal')
    })
  })
}<|endoftext|>


<commit_before>var port = 1340;
// Downgrade from root
if (process.getuid() === 0)
    require('fs').stat(__filename, function(err, stats) {
            if (err)
                return console.log(err);
            process.setuid(stats.uid);
        });
console.log("Started practice server");
var io = require('socket.io').listen(port);
var games = {},
    gameBySocketId = {},
    gamesPerProcess = 32;
io.sockets.on('connection',function(socket){
        socket.on('subscribe',function(type,gameId){
		var g = games[gameId];
		if(typeof g == 'undefined'){
		    if(gamesPerProcess > 0){
			games[gameId] = new PGame(gameId,socket);
			gamesPerProcess--;
		    }else{
			socket.emit('error','No more practice rooms available');
			return;
		    }
		}else{
		    if(type == 'controller'){
			if(g.c0 === null){
			    g.connect(0,socket);
			}else if(g.c1 === null){
			    g.connect(1,socket);
			}else{
			    socket.emit('error','This room already has two controllers');
			}
		    }else{
			socket.emit('error','This id is taken');
		    }
		}
            });
        socket.on('disconnect',function(){
		var g = gameBySocketId[socket.id];
		if(g.host.id == socket.id){
		    if(g.c0){
			g.c0.emit('disconnect');
			delete gameBySocketId[g.c0.id];
		    }
		    if(g.c1){
			g.c1.emit('disconnect');
			delete gameBySocketId[g.c1.id];
		    }
		    delete gameBySocketId[g.host.id];
		    delete games[g.gid];
		}else if(g.c0.id == socket.id){
		    g.c0 = null;
		}else if(g.c1.id == socket.id){
		    g.c1 = null;
		}
            });
    });
PGame = function(id,host){
    this.host = host;
    this.gid = id;
    this.c0 = null;
    this.c1 = null;
    gameBySocketId[host.id] = this;
};
PGame.prototype.connect = function(id,socket){
    if(id == 0){
	this.c0 = socket;
    }
    if(id == 1){
	this.c1 = socket;
    }
    (function(pgame){
	socket.on('paddle',function(point){
		pgame.host.emit('paddle',id,point);
	    });
	socket.on('dbl',function(){
		pgame.host.emit('dlb',id);
	    });
    })(this);
    socket.emit('connected',id);
    gameBySocketId[socket.id] = this;
};
<commit_msg>rewrote connection logic<commit_after>var port = 1340;
// Downgrade from root
if (process.getuid() === 0)
    require('fs').stat(__filename, function(err, stats) {
            if (err)
                return console.log(err);
            process.setuid(stats.uid);
        });
console.log("Started practice server");
var io = require('socket.io').listen(port);
var games = {},
    gameBySocketId = {},
    gamesPerProcess = 32;
io.sockets.on('connection',function(socket){
        socket.on('subscribe',function(type,gameId){
		var g = games[gameId];
		if(typeof g == 'undefined'){
		    if(gamesPerProcess > 0){
			g = games[gameId] = new PGame(gameId);
			gamesPerProcess--;
		    }else{
			socket.emit('error','No more practice rooms available');
			return;
		    }
		}
		g.connect(type,socket);
            });
        socket.on('disconnect',function(){
		var g = gameBySocketId[socket.id];
		if(g.host.id == socket.id){
		    if(g.c0){
			g.c0.emit('disconnect');
			delete gameBySocketId[g.c0.id];
		    }
		    if(g.c1){
			g.c1.emit('disconnect');
			delete gameBySocketId[g.c1.id];
		    }
		    delete gameBySocketId[g.host.id];
		    delete games[g.gid];
		}else if(g.c0.id == socket.id){
		    g.c0 = null;
		}else if(g.c1.id == socket.id){
		    g.c1 = null;
		}
            });
    });
PGame = function(id){
    this.host = null;
    this.gid = id;
    this.c0 = null;
    this.c1 = null;
    gameBySocketId[host.id] = this;
};

PGame.prototype.connect = function(type,socket){
    if(type=='viewer' && this.host==null){
	this.host = socket;
	gameBySocketId[socket.id] = this;
    }else if(type == 'controller'){
	var id;
	if(this.c0 == null){
	    this.c0 = socket;
	    id = 0;
	}else if(this.c1 == null){
	    this.c1 = socket;
	    id = 1;
	}else{
	    socket.emit('error','This room already has two controllers');
	    return;
	}
	(function(pgame){
	    socket.on('paddle',function(point){
		    if(pgame.host) pgame.host.emit('paddle',id,point);
		});
	    socket.on('dbl',function(){
		    if(pgame.host) pgame.host.emit('dlb',id);
		});
	})(this)
	gameBySocketId[socket.id] = this;
    }else{
	socket.emit('error','This room is full');
    }
};<|endoftext|>


<commit_before>'use strict';

var data = module.exports = {
  jquery: {
    versions: ['2.1.3', '2.1.2', '2.1.1', '2.1.0', '2.0.3', '2.0.2', '2.0.1', '2.0.0', '1.11.1', '1.11.0', '1.10.2', '1.10.1', '1.10.0', '1.9.1', '1.9.0', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.2', '1.7.1', '1.7.0', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.2', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.6', '1.2.3'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/jquery/' + version + '/jquery.min.js';
    }
  },
  'jquery-ui': {
    versions: ['1.11.2', '1.11.1', '1.11.0', '1.10.4', '1.10.3', '1.10.2', '1.10.1', '1.10.0', '1.9.2', '1.9.1', '1.9.0', '1.8.24', '1.8.23', '1.8.22', '1.8.21', '1.8.20', '1.8.19', '1.8.18', '1.8.17', '1.8.16', '1.8.15', '1.8.14', '1.8.13', '1.8.12', '1.8.11', '1.8.10', '1.8.9', '1.8.8', '1.8.7', '1.8.6', '1.8.5', '1.8.4', '1.8.2', '1.8.1', '1.8.0', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.0', '1.5.3', '1.5.2'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/jqueryui/' + version + '/jquery-ui.min.js';
    }
  },
  dojo: {
    versions: ['1.10.3', '1.10.2', '1.10.1', '1.10.0', '1.9.3', '1.9.2', '1.9.1', '1.9.0', '1.8.5', '1.8.4', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.5', '1.7.4', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.3', '1.2.0', '1.1.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/dojo/' + version + '/dojo/dojo.js';
    }
  },
  swfobject: {
    versions: ['2.2', '2.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/swfobject/' + version + '/swfobject.js';
    }
  }
};

// AngularJS

var angularFiles = [
  'angular',
  'angular-animate',
  'angular-cookies',
  'angular-loader',
  'angular-resource',
  'angular-route',
  'angular-sanitize',
  'angular-touch'
];

angularFiles.forEach(function (item) {
  var stableVersions = ['1.3.8', '1.3.7', '1.3.6', '1.3.5', '1.3.4', '1.3.3', '1.3.2', '1.3.1', '1.3.0', '1.2.26', '1.2.25', '1.2.24', '1.2.23', '1.2.22', '1.2.21', '1.2.20', '1.2.19', '1.2.18', '1.2.17', '1.2.16', '1.2.15', '1.2.14', '1.2.13', '1.2.12', '1.2.11', '1.2.10', '1.2.9', '1.2.8', '1.2.7', '1.2.6', '1.2.5', '1.2.4', '1.2.3', '1.2.2', '1.2.1', '1.2.0', '1.0.8', '1.0.7', '1.0.6', '1.0.5', '1.0.4', '1.0.3', '1.0.2', '1.0.1'];
  var unstableVersions = ['1.3.0-rc.5', '1.3.0-rc.4', '1.3.0-rc.3', '1.3.0-rc.2', '1.3.0-rc.1', '1.3.0-rc.0', '1.3.0-beta.19', '1.3.0-beta.18', '1.3.0-beta.17', '1.3.0-beta.16', '1.3.0-beta.15', '1.3.0-beta.14', '1.3.0-beta.13', '1.3.0-beta.12', '1.3.0-beta.11', '1.3.0-beta.10', '1.3.0-beta.9', '1.3.0-beta.8', '1.3.0-beta.7', '1.3.0-beta.6', '1.3.0-beta.5', '1.3.0-beta.4', '1.3.0-beta.3', '1.3.0-beta.2', '1.3.0-beta.1'];
  data[item] = {
    versions: [].concat(stableVersions).concat(unstableVersions),
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/angularjs/' + version + '/' + item + '.min.js';
    }
  };
});
<commit_msg>Updated Angular stable to 1.3.9<commit_after>'use strict';

var data = module.exports = {
  jquery: {
    versions: ['2.1.3', '2.1.2', '2.1.1', '2.1.0', '2.0.3', '2.0.2', '2.0.1', '2.0.0', '1.11.1', '1.11.0', '1.10.2', '1.10.1', '1.10.0', '1.9.1', '1.9.0', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.2', '1.7.1', '1.7.0', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.2', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.6', '1.2.3'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/jquery/' + version + '/jquery.min.js';
    }
  },
  'jquery-ui': {
    versions: ['1.11.2', '1.11.1', '1.11.0', '1.10.4', '1.10.3', '1.10.2', '1.10.1', '1.10.0', '1.9.2', '1.9.1', '1.9.0', '1.8.24', '1.8.23', '1.8.22', '1.8.21', '1.8.20', '1.8.19', '1.8.18', '1.8.17', '1.8.16', '1.8.15', '1.8.14', '1.8.13', '1.8.12', '1.8.11', '1.8.10', '1.8.9', '1.8.8', '1.8.7', '1.8.6', '1.8.5', '1.8.4', '1.8.2', '1.8.1', '1.8.0', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.0', '1.5.3', '1.5.2'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/jqueryui/' + version + '/jquery-ui.min.js';
    }
  },
  dojo: {
    versions: ['1.10.3', '1.10.2', '1.10.1', '1.10.0', '1.9.3', '1.9.2', '1.9.1', '1.9.0', '1.8.5', '1.8.4', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.5', '1.7.4', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.3', '1.2.0', '1.1.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/dojo/' + version + '/dojo/dojo.js';
    }
  },
  swfobject: {
    versions: ['2.2', '2.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/swfobject/' + version + '/swfobject.js';
    }
  }
};

// AngularJS

var angularFiles = [
  'angular',
  'angular-animate',
  'angular-cookies',
  'angular-loader',
  'angular-resource',
  'angular-route',
  'angular-sanitize',
  'angular-touch'
];

angularFiles.forEach(function (item) {
  var stableVersions = ['1.3.9', '1.3.8', '1.3.7', '1.3.6', '1.3.5', '1.3.4', '1.3.3', '1.3.2', '1.3.1', '1.3.0', '1.2.26', '1.2.25', '1.2.24', '1.2.23', '1.2.22', '1.2.21', '1.2.20', '1.2.19', '1.2.18', '1.2.17', '1.2.16', '1.2.15', '1.2.14', '1.2.13', '1.2.12', '1.2.11', '1.2.10', '1.2.9', '1.2.8', '1.2.7', '1.2.6', '1.2.5', '1.2.4', '1.2.3', '1.2.2', '1.2.1', '1.2.0', '1.0.8', '1.0.7', '1.0.6', '1.0.5', '1.0.4', '1.0.3', '1.0.2', '1.0.1'];
  var unstableVersions = ['1.3.0-rc.5', '1.3.0-rc.4', '1.3.0-rc.3', '1.3.0-rc.2', '1.3.0-rc.1', '1.3.0-rc.0', '1.3.0-beta.19', '1.3.0-beta.18', '1.3.0-beta.17', '1.3.0-beta.16', '1.3.0-beta.15', '1.3.0-beta.14', '1.3.0-beta.13', '1.3.0-beta.12', '1.3.0-beta.11', '1.3.0-beta.10', '1.3.0-beta.9', '1.3.0-beta.8', '1.3.0-beta.7', '1.3.0-beta.6', '1.3.0-beta.5', '1.3.0-beta.4', '1.3.0-beta.3', '1.3.0-beta.2', '1.3.0-beta.1'];
  data[item] = {
    versions: [].concat(stableVersions).concat(unstableVersions),
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/angularjs/' + version + '/' + item + '.min.js';
    }
  };
});
<|endoftext|>


<commit_before>"use strict";

/*window.requestAnimationFrame = (function () {
 return  window.requestAnimationFrame ||
 window.webkitRequestAnimationFrame ||
 window.mozRequestAnimationFrame ||
 function (callback) {
 window.setTimeout(callback, 1000 / 60);
 };
 })();*/

$(document).ready(function () {
  function BigImage(_cropped) {
    var cropped = _cropped,
      croppedImg = cropped.children("img"),
      lastPageX = 0,
      lastPageY = 0;

    this.initDrag = function (pageX, pageY) {
      lastPageX = pageX;
      lastPageY = pageY;
    }

    this.drag = function (pageX, pageY) {
      var diffX = lastPageX - pageX;
      var diffY = lastPageY - pageY;

      this.moveX(diffX);
      this.moveY(diffY);

      lastPageX = pageX;
      lastPageY = pageY;
    }

    this.moveX = function (delta) {
      var max = this.maxMarginLeft();
      this.move("margin-left", delta, max);
    }

    this.moveY = function (delta) {
      var max = this.maxMarginTop();
      this.move("margin-top", delta, max);
    }

    this.move = function (direction, delta, max) {
      var mt = -parseFloat(croppedImg.css(direction));
      var position = mt + delta;
      this.moveTo(direction, position, max);
    }

    this.moveTo = function (direction, position, max) {
      if (position < 0) position = 0;
      if (position > max) position = max;
      croppedImg.css(direction, -position + "px");
    }

    this.maxMarginTop = function () {
      return croppedImg.height() - cropped.height();
    }

    this.maxMarginLeft = function () {
      return this.fullImageWidth() - cropped.width();
    }

    this.widthVisibleRatio = function () {
      return cropped.width() / this.fullImageWidth();
    }

    this.marginLeftRatio = function () {
      return this.marginLeft() / croppedImg.width();
    }

    this.fullImageWidth = function () {
      return croppedImg.width();
    }

    this.marginLeft = function () {
      return parseFloat(croppedImg.css("margin-left"))
    }
  }

  function Thumbnail(_thumbnail) {
    var thumbnail = _thumbnail;
    var thumbnailImg = thumbnail.children("img");
    var rectangle = thumbnail.children(".rectangle");

    this.updateRectangle = function (bigImage) {
      var widthRatio = bigImage.widthVisibleRatio();
      rectangle.css("height", parseFloat(thumbnailImg.height()) + "px");
      rectangle.css("width", (thumbnailImg.width() * widthRatio) + "px");

      var marginLeftRatio = bigImage.marginLeftRatio();
      rectangle.css("margin-left", -marginLeftRatio * thumbnailImg.width() + "px")
    }

    this.calculateMovementToNewCenter = function (newCenter) {
      var w = rectangle.width();
      var l = parseFloat(rectangle.css("margin-left"));
      var currentRectangleCenter = l + w / 2;
      return newCenter - currentRectangleCenter;
    }
  }

  function AutoDrag(_bigImage, _thumbnail) {
    var _this = this;

    var bigImage = _bigImage;
    var thumbnail = _thumbnail;

    var autoDragEnabled = true;
    var autoDragSpeed = 0.1;

    var marginOffset = 0, timeOffset = 0, lastTime = 0, manualDrag = true;

    this.stopAutoDrag = function () {
      autoDragEnabled = false;
    }

    this.setManuallyDragged = function(){
      manualDrag = true;
    }

    this.initAutoDrag = function () {
      this.setStartParameters();
      if(manualDrag){
        manualDrag = false;
        marginOffset = -bigImage.marginLeft();
      }

      var drag = function (time) {
        if (autoDragEnabled) requestAnimationFrame(drag);
        _this.autoDrag(time);
      }

      requestAnimationFrame(drag);
    }

    this.setStartParameters = function () {
      var max = bigImage.maxMarginLeft();
      marginOffset = _this.calcT(lastTime, max);
      timeOffset = lastTime;

      var setParams = function (time) {
        timeOffset = time;
      }
      requestAnimationFrame(setParams);
    }

    this.calcT = function (time, max) {
      lastTime = time;
      return (((time - timeOffset) * autoDragSpeed) + marginOffset) % (max * 2);
    }

    this.calculateMarginLeft = function (time, max) {
      var t = this.calcT(time, max);
      if (t > max) t = 2 * max - t;
      var newPosition = Math.abs(t);
      return newPosition;
    }

    this.autoDrag = function (time) {
      if (!autoDragEnabled) return;
      var max = bigImage.maxMarginLeft();
      var newPosition = this.calculateMarginLeft(time, max);
      bigImage.moveTo("margin-left", newPosition, max);
      thumbnail.updateRectangle(bigImage);
    }

    this.play = function () {
      if (autoDragEnabled) return;
      autoDragEnabled = true;
      this.initAutoDrag();
    }

    this.increaseSpeed = function () {
      this.setStartParameters();
      autoDragSpeed *= 1.5;
    }

    this.decreaseSpeed = function () {
      this.setStartParameters();
      autoDragSpeed /= 1.5;
    }
  }

  function PanoramaWidget() {
    var widget = this;
    var firstDrag = true;

    var body = $("body");

    var slider = $(".image-slider");

    var cropped = slider.children(".cropped");
    var bigImage = new BigImage(cropped);

    var thumbnailOuterDiv = slider.children(".thumbnail");
    var thumbnailDiv = thumbnailOuterDiv.children(".thumbnail-inner");
    var thumbnailImg = thumbnailDiv.children("img");
    var rectangle = thumbnailDiv.children(".rectangle");
    var thumbnail = new Thumbnail(thumbnailDiv);

    var autoDrag = new AutoDrag(bigImage, thumbnail);

    this.convertTouchEvent = function (event) {
      if (event.originalEvent && event.originalEvent.touches && event.originalEvent.touches[0])
        return event.originalEvent.touches[0];
      return event;
    }

    this.registerEvents = function () {
      var manualDragBig = function (_event) {
        var event = widget.convertTouchEvent(_event);

        if (firstDrag) {
          bigImage.initDrag(event.pageX, event.pageY);
          firstDrag = false;
        }
        bigImage.drag(event.pageX, event.pageY);
        thumbnail.updateRectangle(bigImage);

        autoDrag.setManuallyDragged();
      }

      var manualDragThumbnail = function (_event) {
        var event = widget.convertTouchEvent(_event);
        var pageX = event.pageX;
        pageX *= -bigImage.fullImageWidth() / thumbnailImg.width();
        // fullImageWidth
        if (firstDrag) {
          bigImage.initDrag(pageX, 0);
          firstDrag = false;
        }
        bigImage.drag(pageX, 0);
        thumbnail.updateRectangle(bigImage);

        autoDrag.setManuallyDragged();
      }

      slider.on("dragstart", function (e) {
        e.preventDefault();
      });

      cropped.on("mousedown touchstart", function (e) {
        e.preventDefault();
        $("body").on("mousemove touchmove", manualDragBig);
        cropped.addClass("grabbing");
        firstDrag = true;
        autoDrag.stopAutoDrag();
      });

      // could also use mouseout, then we wouldn't need to register the body events
      body.on("mouseup touchend", function (e) {
        e.preventDefault();
        body.off("mousemove touchmove", manualDragBig);
        cropped.removeClass("grabbing");
        firstDrag = false;
      });

      rectangle.on("mousedown touchstart", function (e) {
        e.preventDefault();
        body.on("mousemove touchmove", manualDragThumbnail);
        rectangle.addClass("grabbing");
        firstDrag = true;
        autoDrag.stopAutoDrag();
      });

      // could also use mouseout, then we wouldn't need to register the body events
      body.on("mouseup touchend", function (e) {
        e.preventDefault();
        body.off("mousemove touchmove", manualDragThumbnail);
        rectangle.removeClass("grabbing");
        firstDrag = false;
      });

      thumbnailImg.on("click", function (e) {
        e.preventDefault();

        autoDrag.stopAutoDrag();

        var newCenter = thumbnail.calculateMovementToNewCenter(e.offsetX);
        newCenter *= -bigImage.fullImageWidth() / thumbnailImg.width();

        bigImage.initDrag(0, 0);
        bigImage.drag(newCenter, 0);

        thumbnail.updateRectangle(bigImage);

        autoDrag.setManuallyDragged();
      });

      $(window).on("resize", function () {
        thumbnail.updateRectangle(bigImage);
      });
    }

    this.registerControls = function () {
      $("a[href=#play]").click(function (e) {
        e.preventDefault();
        autoDrag.play();
      });

      $("a[href=#stop]").click(function (e) {
        e.preventDefault();
        autoDrag.stopAutoDrag();
      });

      $("a[href=#faster]").click(function (e) {
        e.preventDefault();
        autoDrag.increaseSpeed();
      });

      $("a[href=#slower]").click(function (e) {
        e.preventDefault();
        autoDrag.decreaseSpeed();
      });
    }

    this.initAutoDrag = function () {
      autoDrag.initAutoDrag();
    }

  }

  var w = new PanoramaWidget();
  w.registerEvents();
  w.registerControls();
  w.initAutoDrag();

});
<commit_msg>touch<commit_after>"use strict";

/*window.requestAnimationFrame = (function () {
 return  window.requestAnimationFrame ||
 window.webkitRequestAnimationFrame ||
 window.mozRequestAnimationFrame ||
 function (callback) {
 window.setTimeout(callback, 1000 / 60);
 };
 })();*/

$(document).ready(function () {
  function BigImage(_cropped) {
    var cropped = _cropped,
      croppedImg = cropped.children("img"),
      lastPageX = 0,
      lastPageY = 0;

    this.initDrag = function (pageX, pageY) {
      lastPageX = pageX;
      lastPageY = pageY;
    }

    this.drag = function (pageX, pageY) {
      var diffX = lastPageX - pageX;
      var diffY = lastPageY - pageY;

      this.moveX(diffX);
      this.moveY(diffY);

      lastPageX = pageX;
      lastPageY = pageY;
    }

    this.moveX = function (delta) {
      var max = this.maxMarginLeft();
      this.move("margin-left", delta, max);
    }

    this.moveY = function (delta) {
      var max = this.maxMarginTop();
      this.move("margin-top", delta, max);
    }

    this.move = function (direction, delta, max) {
      var mt = -parseFloat(croppedImg.css(direction));
      var position = mt + delta;
      this.moveTo(direction, position, max);
    }

    this.moveTo = function (direction, position, max) {
      if (position < 0) position = 0;
      if (position > max) position = max;
      croppedImg.css(direction, -position + "px");
    }

    this.maxMarginTop = function () {
      return croppedImg.height() - cropped.height();
    }

    this.maxMarginLeft = function () {
      return this.fullImageWidth() - cropped.width();
    }

    this.widthVisibleRatio = function () {
      return cropped.width() / this.fullImageWidth();
    }

    this.marginLeftRatio = function () {
      return this.marginLeft() / croppedImg.width();
    }

    this.fullImageWidth = function () {
      return croppedImg.width();
    }

    this.marginLeft = function () {
      return parseFloat(croppedImg.css("margin-left"))
    }
  }

  function Thumbnail(_thumbnail) {
    var thumbnail = _thumbnail;
    var thumbnailImg = thumbnail.children("img");
    var rectangle = thumbnail.children(".rectangle");

    this.updateRectangle = function (bigImage) {
      var widthRatio = bigImage.widthVisibleRatio();
      rectangle.css("height", parseFloat(thumbnailImg.height()) + "px");
      rectangle.css("width", (thumbnailImg.width() * widthRatio) + "px");

      var marginLeftRatio = bigImage.marginLeftRatio();
      rectangle.css("margin-left", -marginLeftRatio * thumbnailImg.width() + "px")
    }

    this.calculateMovementToNewCenter = function (newCenter) {
      var w = rectangle.width();
      var l = parseFloat(rectangle.css("margin-left"));
      var currentRectangleCenter = l + w / 2;
      return newCenter - currentRectangleCenter;
    }
  }

  function AutoDrag(_bigImage, _thumbnail) {
    var _this = this;

    var bigImage = _bigImage;
    var thumbnail = _thumbnail;

    var autoDragEnabled = true;
    var autoDragSpeed = 0.1;

    var marginOffset = 0, timeOffset = 0, lastTime = 0, manualDrag = true;

    this.stopAutoDrag = function () {
      autoDragEnabled = false;
    }

    this.setManuallyDragged = function () {
      manualDrag = true;
    }

    this.initAutoDrag = function () {
      this.setStartParameters();
      if (manualDrag) {
        manualDrag = false;
        marginOffset = -bigImage.marginLeft();
      }

      var drag = function (time) {
        if (autoDragEnabled) requestAnimationFrame(drag);
        _this.autoDrag(time);
      }

      requestAnimationFrame(drag);
    }

    this.setStartParameters = function () {
      var max = bigImage.maxMarginLeft();
      marginOffset = _this.calcT(lastTime, max);
      timeOffset = lastTime;

      var setParams = function (time) {
        timeOffset = time;
      }
      requestAnimationFrame(setParams);
    }

    this.calcT = function (time, max) {
      lastTime = time;
      return (((time - timeOffset) * autoDragSpeed) + marginOffset) % (max * 2);
    }

    this.calculateMarginLeft = function (time, max) {
      var t = this.calcT(time, max);
      if (t > max) t = 2 * max - t;
      var newPosition = Math.abs(t);
      return newPosition;
    }

    this.autoDrag = function (time) {
      if (!autoDragEnabled) return;
      var max = bigImage.maxMarginLeft();
      var newPosition = this.calculateMarginLeft(time, max);
      bigImage.moveTo("margin-left", newPosition, max);
      thumbnail.updateRectangle(bigImage);
    }

    this.play = function () {
      if (autoDragEnabled) return;
      autoDragEnabled = true;
      this.initAutoDrag();
    }

    this.increaseSpeed = function () {
      this.setStartParameters();
      autoDragSpeed *= 1.5;
    }

    this.decreaseSpeed = function () {
      this.setStartParameters();
      autoDragSpeed /= 1.5;
    }
  }

  function PanoramaWidget() {
    var widget = this;
    var firstDrag = true;

    var body = $("body");

    var slider = $(".image-slider");

    var cropped = slider.children(".cropped");
    var bigImage = new BigImage(cropped);

    var thumbnailOuterDiv = slider.children(".thumbnail");
    var thumbnailDiv = thumbnailOuterDiv.children(".thumbnail-inner");
    var thumbnailImg = thumbnailDiv.children("img");
    var rectangle = thumbnailDiv.children(".rectangle");
    var thumbnail = new Thumbnail(thumbnailDiv);

    var autoDrag = new AutoDrag(bigImage, thumbnail);

    this.isTouchEvent = function (event) {
      return event.originalEvent && event.originalEvent.touches && event.originalEvent.touches.length > 0;
    }
    this.isSingleTouchEvent = function (event) {
      return event.originalEvent && event.originalEvent.touches && event.originalEvent.touches.length == 1;
    }
    this.isDoubleTouchEvent = function (event) {
      return event.originalEvent && event.originalEvent.touches && event.originalEvent.touches.length == 2;
    }
    this.convertSingleTouchEvent = function (event) {
      return event.originalEvent.touches[0];
      /*if (event.originalEvent && event.originalEvent.touches && event.originalEvent.touches[0]) {
       var touches = event.originalEvent.touches;
       return touches.length == 1 ? touches[0] : null;
       }
       return event;*/
    }

    this.registerEvents = function () {
      var manualDragBig = function (event) {
        var dragFunction = function (e) {
          if (firstDrag) {
            bigImage.initDrag(e.pageX, e.pageY);
            firstDrag = false;
          }
          bigImage.drag(e.pageX, e.pageY);
          thumbnail.updateRectangle(bigImage);

          autoDrag.setManuallyDragged();
        };

        var zoomFunction = function (event) {

        };

        if (!widget.isTouchEvent(event)) dragFunction(event);
        else if (widget.isSingleTouchEvent(event)) {
          dragFunction(widget.convertSingleTouchEvent(event));
        }
        else if (widget.isDoubleTouchEvent(event)) zoomFunction(event);
        else return;

        event.preventDefault();
      };

      var manualDragThumbnail = function (_event) {
        var event = _event;

        if (widget.isSingleTouchEvent(event)) event = widget.convertSingleTouchEvent(event);
        else if (widget.isTouchEvent(event)) return;

        _event.preventDefault();

        var pageX = event.pageX;
        pageX *= -bigImage.fullImageWidth() / thumbnailImg.width();
        // fullImageWidth
        if (firstDrag) {
          bigImage.initDrag(pageX, 0);
          firstDrag = false;
        }
        bigImage.drag(pageX, 0);
        thumbnail.updateRectangle(bigImage);

        autoDrag.setManuallyDragged();
      }

      slider.on("dragstart", function (e) {
        e.preventDefault();
      });

      cropped.on("mousedown touchstart", function (e) {
        $("body").on("mousemove touchmove", manualDragBig);
        cropped.addClass("grabbing");
        firstDrag = true;
        autoDrag.stopAutoDrag();
      });

      // could also use mouseout, then we wouldn't need to register the body events
      body.on("mouseup touchend", function (e) {
        body.off("mousemove touchmove", manualDragBig);
        cropped.removeClass("grabbing");
        firstDrag = false;
      });

      rectangle.on("mousedown touchstart", function (e) {
        body.on("mousemove touchmove", manualDragThumbnail);
        rectangle.addClass("grabbing");
        firstDrag = true;
        autoDrag.stopAutoDrag();
      });

      // could also use mouseout, then we wouldn't need to register the body events
      body.on("mouseup touchend", function (e) {
        body.off("mousemove touchmove", manualDragThumbnail);
        rectangle.removeClass("grabbing");
        firstDrag = false;
      });

      var clickFunction = function(offsetX){
        autoDrag.stopAutoDrag();

        var newCenter = thumbnail.calculateMovementToNewCenter(offsetX);
        newCenter *= -bigImage.fullImageWidth() / thumbnailImg.width();

        bigImage.initDrag(0, 0);
        bigImage.drag(newCenter, 0);

        thumbnail.updateRectangle(bigImage);

        autoDrag.setManuallyDragged();
      }

      thumbnailImg.on("click ", function (event) {
        event.preventDefault();
        clickFunction(event.offsetX);
      });

      thumbnailImg.on("touchstart ", function (_event) {
        var event = _event;

        if (!widget.isSingleTouchEvent(event)) return;

        _event.preventDefault();
        event = widget.convertSingleTouchEvent(event);

        var offsetX = event.pageX - event.target.x;
        clickFunction(offsetX);
      });

      $(window).on("resize", function () {
        thumbnail.updateRectangle(bigImage);
      });
    }

    this.registerControls = function () {
      $("a[href=#play]").on("click touchstart", function (e) {
        e.preventDefault();
        autoDrag.play();
      });

      $("a[href=#stop]").on("click touchstart", function (e) {
        e.preventDefault();
        autoDrag.stopAutoDrag();
      });

      $("a[href=#faster]").on("click touchstart", function (e) {
        e.preventDefault();
        autoDrag.increaseSpeed();
      });

      $("a[href=#slower]").on("click touchstart", function (e) {
        e.preventDefault();
        autoDrag.decreaseSpeed();
      });
    }

    this.initAutoDrag = function () {
      autoDrag.initAutoDrag();
    }

  }

  var w = new PanoramaWidget();
  w.registerEvents();
  w.registerControls();
  w.initAutoDrag();

})
;
<|endoftext|>


<commit_before>const app = require('../../app');

const User = require('../../models/user'),
	should = require('should');
	Bluebird = require('bluebird'),
	request = require('supertest');

const userData = {
  email: 'contact@postcardsforchange.net'
}

describe('Route: Users', function(){

	it('creates new users', function(){
		return request(app)
		.post('/api/users')
        .send(userData)
		.expect(201)
		.then(function () {
			return User.find({})
		})
        .then(function (res) {
            res.length.should.eql(1);
            res[0].email.should.eql(userData.email)
        });
	});

	it('does not create users without an email', function(){
        return request(app)
		.post('/api/users')
        .send({name: 'Kamilla'})
		.expect(400)
		.then(function (res) {
			return User.find({})
		})
        .then(function (res) {
            res.length.should.eql(0);
        });
	});

})

<commit_msg>fix users test<commit_after>const app = require('../../app');

const User = require('../../models/user'),
	should = require('should');
	Bluebird = require('bluebird'),
	request = require('supertest');

const userData = {
  email: 'contact@postcardsforchange.net'
}

describe('Route: Users', function(){
	it('does not create users without an email', function(){
        return request(app)
		.post('/api/users')
        .send({name: 'Kamilla'})
		.expect(400)
		.then(function (res) {
			return User.find({})
		})
        .then(function (res) {
            res.length.should.eql(0);
        });
	});

	it('creates new users', function(){
		return request(app)
		.post('/api/users')
        .send(userData)
		.expect(201)
		.then(function () {
			return User.find({})
		})
        .then(function (res) {
            res.length.should.eql(1);
            res[0].email.should.eql(userData.email)
        });
	});
})

<|endoftext|>


<commit_before>/**
 * TkMap is a JS class to make it easy to place a Google Maps API map into a
 * given DOM object.
 * @param array Args
 * @type class
 */
var TkMap = (function($){
	var constructor = function(Args)
	{
		/*
		 * PROPERTIES ***************************************************************
		 */
		/*
		 * PRIVATE properties from Required Arguments
		 */
		/** Latitude in decimal degrees */
		var Lat = typeof Args.lat !== 'undefined' ? Args.lat : null;
		/** Longitude in decimal degrees */
		var Lng = typeof Args.lng !== 'undefined' ? Args.lng : null;
		/** The ID of the DOM object in which to place the map */
		var DomId = typeof Args.domid !== 'undefined' ? Args.domid : null;
		/*
		 * PRIVATE Properties from Optional Arguments
		 */
		/** Google Maps zoom level */
		var Zoom = typeof Args.zoom !== 'undefined' ? Args.zoom : 15;
		/** Show the map as soom as this map object is created */
		var Init = typeof Args.init !== 'undefined' ? Args.init : false;
		/** Set map zoom level according to map DOM size */
		var Responsive = typeof Args.responsive !== 'undefined' ? Args.responsive : false;
		/** Set built-in custom map styles */
		var Styles = typeof Args.styles !== 'undefined' ? Args.styles : null;
		/*
		 * Other PRIVATE Properties
		 */
		/** Google Maps map options */
		var MapOptions = {
				center : new google.maps.LatLng(Lat,Lng),
				draggable : true,
				mapTypeControl : false,
				mapTypeId : google.maps.MapTypeId.ROADMAP,
				panControl : false,
				streetViewControl : false,
				styles : [],
				zoom: Zoom,
				zoomControl : true
		};
		/*
		 * Variables used to control touch events
		 */
		/** Are we currently dragging? */
		var dragFlag = false;
		/** touchstart Y location */
		var touchstart = null;
		/** touchend Y location */
		var touchend = null;
		/*
		 * PUBLIC Properties
		 */
		/** The Google Map object */
		this.Map = null;
		/*
		 * METHODS ****************************************************************
		 */
		/*
		 * PRIVATE methods
		 */
		/** Begin calculation of vertical scroll on touchstart event */
		var touchStart =  function(e)
		{
			dragFlag = true;
			touchstart = e.touches[0].pageY;
		};
		/** End calculation of vertical scroll on touchend event */
		var touchEnd = function()
		{
			dragFlag = false;
		};
		/** Calculate vertical scroll on touchmove event */
		var touchMove = function(e)
		{
			if ( ! dragFlag){return;}
			touchend = e.touches[0].pageY;
			window.scrollBy(0,(touchstart - touchend ));
		};
		/** Choose pre-built map styles. */
		var setCustomStyles = function()
		{
			var StylesArray = Styles.split(' ');
			for (var i in StylesArray)
			{
				if(StylesArray[i] === 'satellite')
				{
					MapOptions.mapTypeId = google.maps.MapTypeId.SATELLITE;
				}
				else
				{
					if (StylesArray[i] === 'hybrid')
					{
						MapOptions.mapTypeId = google.maps.MapTypeId.HYBRID;
					}
					else if (StylesArray[i] === 'road')
					{
						MapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP;
					}
					else if (StylesArray[i] === 'terrain')
					{
						MapOptions.mapTypeId = google.maps.MapTypeId.TERRAIN;
					}
					else if (StylesArray[i] === 'minlabels')
					{
						MapOptions.styles.push
						(
							{
								featureType : "all",
								elementType : "labels",
								stylers: [{ visibility: "off" }]
							},
							{
								featureType : "administrative",
								elementType : "labels",
								stylers: [{ visibility: "on" }]
							},
							{
								featureType : "road",
								elementType : "labels",
								stylers: [{ visibility: "on" }]
							}
						);
					}
					else if (StylesArray[i] === 'grey')
					{
						MapOptions.backgroundColor = '#C5C5C5';
						MapOptions.styles.push
						(
							{
								stylers: [{ saturation: -87 }]
							},
							{
								featureType: "road.arterial",
								elementType: "geometry",
								stylers: [{ lightness: 85 }]
							},
							{
								featureType: "water",
								stylers: [{ lightness: -20 }]
							}
						);
					}
				}
			}
		};
		/** Set map zoom level based on the map's DOM object width */
		var setResponsive = function()
		{
			/** The width of the map DOM object */
			var theWidth = $("#"+DomId).width();
			if(theWidth < 481)
			{
				MapOptions.zoom--;
			}
			else if (theWidth > 959)
			{
				MapOptions.zoom++;
			}
		};
		/*
		 * PUBLIC methods
		 */
		/** Place the map in the DOM object */
		this.initMap = function()
		{
			if (this.Map === null)
			{
				if (Styles !== null)
				{
					setCustomStyles();
				}
				if (Responsive)
				{
					setResponsive();
				}
				this.Map = new google.maps.Map(
					document.getElementById(DomId),
					MapOptions
				);
			}
		};
		/** Set more map options before map initializaton */
		this.setMapOptions = function(options)
		{
			if(this.Map !== null)
			{
				$.extend(MapOptions,options);
			}
		};
		/**
		 * Set the listeners for touch-scrolling the screen on the map.
		 * Generally used in conjunction with this.setPanZoom().
		 */
		this.setTouchScroll = function(TSBoolean)
		{
			var thisElement = document.getElementById(DomId);
			if(TSBoolean)
			{
				thisElement.addEventListener("touchstart", touchStart, true);
				thisElement.addEventListener("touchend", touchEnd, true);
				thisElement.addEventListener("touchmove", touchMove, true);
				this.Map.setOptions({
					zoomControl : false
				});
			}
			else
			{
				thisElement.removeEventListener("touchstart", touchStart, true);
				thisElement.removeEventListener("touchend", touchEnd, true);
				thisElement.removeEventListener("touchmove", touchMove, true);
				this.Map.setOptions({
				zoomControl: true,
				zoomControlOptions: {
					position : google.maps.ControlPosition.LEFT_TOP
				}
				});
			}
		};
		/**
		 * Turn on and off map's pan and zoom capabilities.
		 */
		this.setPanZoom = function(PZBoolean)
		{
			var dblclick;
			if(PZBoolean)
			{
				dblclick = false;
			}
			else
			{
				dblclick = true;
			}
			this.Map.setOptions({
				disableDoubleClickZoom : dblclick,
				draggable : PZBoolean,
				keyboardShortcuts : PZBoolean,
				scrollwheel : PZBoolean,
				zoomControl : PZBoolean
			});
		};
		/**
		 * CODE TO RUN AT INSTANTIATION *********************************************
		 */
		if(Init === true)
		{
			this.initMap();
		}
	};
	return constructor;
})(jQuery);<commit_msg>comented experimetn<commit_after>/**
 * TkMap is a JS class to make it easy to place a Google Maps API map into a
 * given DOM object.
 * @param array Args
 * @type class
 */
var TkMap = (function($){
	var constructor = function(Args)
	{
		/*
		 * PROPERTIES ***************************************************************
		 */
		/*
		 * PRIVATE properties from Required Arguments
		 */
		/** Latitude in decimal degrees */
		var Lat = typeof Args.lat !== 'undefined' ? Args.lat : null;
		/** Longitude in decimal degrees */
		var Lng = typeof Args.lng !== 'undefined' ? Args.lng : null;
		/** The ID of the DOM object in which to place the map */
		var DomId = typeof Args.domid !== 'undefined' ? Args.domid : null;
		/*
		 * PRIVATE Properties from Optional Arguments
		 */
		/** Google Maps zoom level */
		var Zoom = typeof Args.zoom !== 'undefined' ? Args.zoom : 15;
		/** Show the map as soom as this map object is created */
		var Init = typeof Args.init !== 'undefined' ? Args.init : false;
		/** Set map zoom level according to map DOM size */
		var Responsive = typeof Args.responsive !== 'undefined' ? Args.responsive : false;
		/** Set built-in custom map styles */
		var Styles = typeof Args.styles !== 'undefined' ? Args.styles : null;
		/*
		 * Other PRIVATE Properties
		 */
		/** Google Maps map options */
		var MapOptions = {
				center : new google.maps.LatLng(Lat,Lng),
				draggable : true,
				mapTypeControl : false,
				mapTypeId : google.maps.MapTypeId.ROADMAP,
				panControl : false,
				streetViewControl : false,
				styles : [],
				zoom: Zoom,
				zoomControl : true
		};
		/*
		 * Variables used to control touch events
		 */
		/** Are we currently dragging? */
		var dragFlag = false;
		/** touchstart Y location */
		var touchstart = null;
		/** touchend Y location */
		var touchend = null;
		/*
		 * PUBLIC Properties
		 */
		/** The Google Map object */
		this.Map = null;
		/*
		 * METHODS ****************************************************************
		 */
		/*
		 * PRIVATE methods
		 */
		/** Begin calculation of vertical scroll on touchstart event */
		var touchStart =  function(e)
		{
			dragFlag = true;
			touchstart = e.touches[0].pageY;
		};
		/** End calculation of vertical scroll on touchend event */
		var touchEnd = function()
		{
			dragFlag = false;
		};
		/** Calculate vertical scroll on touchmove event */
		var touchMove = function(e)
		{
			if ( ! dragFlag){return;}
			touchend = e.touches[0].pageY;
			window.scrollBy(0,(touchstart - touchend ));
		};
		/** Choose pre-built map styles. */
//		var setCustomStyles = function()
//		{
//			var StylesArray = Styles.split(' ');
//			for (var i in StylesArray)
//			{
//				if(StylesArray[i] === 'satellite')
//				{
//					MapOptions.mapTypeId = google.maps.MapTypeId.SATELLITE;
//				}
//				else
//				{
//					if (StylesArray[i] === 'hybrid')
//					{
//						MapOptions.mapTypeId = google.maps.MapTypeId.HYBRID;
//					}
//					else if (StylesArray[i] === 'road')
//					{
//						MapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP;
//					}
//					else if (StylesArray[i] === 'terrain')
//					{
//						MapOptions.mapTypeId = google.maps.MapTypeId.TERRAIN;
//					}
//					else if (StylesArray[i] === 'minlabels')
//					{
//						MapOptions.styles.push
//						(
//							{
//								featureType : "all",
//								elementType : "labels",
//								stylers: [{ visibility: "off" }]
//							},
//							{
//								featureType : "administrative",
//								elementType : "labels",
//								stylers: [{ visibility: "on" }]
//							},
//							{
//								featureType : "road",
//								elementType : "labels",
//								stylers: [{ visibility: "on" }]
//							}
//						);
//					}
//					else if (StylesArray[i] === 'grey')
//					{
//						MapOptions.backgroundColor = '#C5C5C5';
//						MapOptions.styles.push
//						(
//							{
//								stylers: [{ saturation: -87 }]
//							},
//							{
//								featureType: "road.arterial",
//								elementType: "geometry",
//								stylers: [{ lightness: 85 }]
//							},
//							{
//								featureType: "water",
//								stylers: [{ lightness: -20 }]
//							}
//						);
//					}
//				}
//			}
//		};
		/** Set map zoom level based on the map's DOM object width */
		var setResponsive = function()
		{
			/** The width of the map DOM object */
			var theWidth = $("#"+DomId).width();
			if(theWidth < 481)
			{
				MapOptions.zoom--;
			}
			else if (theWidth > 959)
			{
				MapOptions.zoom++;
			}
		};
		/*
		 * PUBLIC methods
		 */
		/** Place the map in the DOM object */
		this.initMap = function()
		{
			if (this.Map === null)
			{
				if (Styles !== null)
				{
					setCustomStyles();
				}
				if (Responsive)
				{
					setResponsive();
				}
				this.Map = new google.maps.Map(
					document.getElementById(DomId),
					MapOptions
				);
			}
		};
		/** Set more map options before map initializaton */
		this.setMapOptions = function(options)
		{
			if(this.Map !== null)
			{
				$.extend(MapOptions,options);
			}
		};
		/**
		 * Set the listeners for touch-scrolling the screen on the map.
		 * Generally used in conjunction with this.setPanZoom().
		 */
		this.setTouchScroll = function(TSBoolean)
		{
			var thisElement = document.getElementById(DomId);
			if(TSBoolean)
			{
				thisElement.addEventListener("touchstart", touchStart, true);
				thisElement.addEventListener("touchend", touchEnd, true);
				thisElement.addEventListener("touchmove", touchMove, true);
				this.Map.setOptions({
					zoomControl : false
				});
			}
			else
			{
				thisElement.removeEventListener("touchstart", touchStart, true);
				thisElement.removeEventListener("touchend", touchEnd, true);
				thisElement.removeEventListener("touchmove", touchMove, true);
				this.Map.setOptions({
				zoomControl: true,
				zoomControlOptions: {
					position : google.maps.ControlPosition.LEFT_TOP
				}
				});
			}
		};
		/**
		 * Turn on and off map's pan and zoom capabilities.
		 */
		this.setPanZoom = function(PZBoolean)
		{
			var dblclick;
			if(PZBoolean)
			{
				dblclick = false;
			}
			else
			{
				dblclick = true;
			}
			this.Map.setOptions({
				disableDoubleClickZoom : dblclick,
				draggable : PZBoolean,
				keyboardShortcuts : PZBoolean,
				scrollwheel : PZBoolean,
				zoomControl : PZBoolean
			});
		};
		/**
		 * CODE TO RUN AT INSTANTIATION *********************************************
		 */
		if(Init === true)
		{
			this.initMap();
		}
	};
	return constructor;
})(jQuery);<|endoftext|>