<commit_before>require('setimmediate');
  // This shims `setImmediate`

const spec = require('tape-catch');
const repeat = require('repeat-element');
const delay = require('timeout-as-promise');
const sinon = require('sinon');

const register = require('./register');

const waitForNextFrame = () => new Promise((resolve) => {
  requestAnimationFrame(resolve);
});

const recalculateCallback = sinon.spy();
register({ recalculateCallback });
  // This registers the <parametric-svg> thing on the actual `document`.

spec('Registers the <parametric-svg> element', (test) => {
  test.plan(7);

  const HTMLElement = () => {};
  const MutationObserver = () => {
    test.pass(
      'with a custom implementation of `MutationObserver`'
    );

    return {observe: () => {}};
  };

  const registerElement = (
    name, options
  ) => {
    const prototype = options.prototype;
    const extendsArg = options.extends || null;

    test.pass(
      'taking a custom implementation of `document`'
    );

    test.equal(
      name,
      'parametric-svg',
      'under the name <parametric-svg>'
    );

    test.equal(
      extendsArg,
      null,
      'as a standard HTML element – no bells and whistles'
    );

    test.equal(
      prototype.constructor,
      HTMLElement,
      'inheriting from the given `HTMLElement`'
    );

    test.equal(
      typeof prototype.createdCallback,
      'function',
      'attaching stuff to the createdCallback…'
    );

    test.deepEqual(
      [
        prototype.attachedCallback,
        prototype.detachedCallback,
        prototype.atributeChangedCallback,
      ],
      repeat(undefined, 3),
      '…and to no other lifecycle callback'
    );

    options.prototype.createdCallback.apply({
      querySelector: () => {},
    });
  };

  register({document: {registerElement}, HTMLElement, MutationObserver});
});

spec('Works in a DOM structure created in one go', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg>
      <svg>
        <rect parametric:x="50" />
      </svg>
    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');
  test.equal(
    rect.getAttribute('x'),
    '50',
    'synchronously'
  );
});

spec('Allows dynamic changes to attributes', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg l="50">
      <svg>
        <rect parametric:x="l" />
      </svg>
    </parametric-svg>
  `;
  const rect = document.querySelector('rect');

  delay(100).then(() => {
    rect.setAttribute('parametric:x', '2 * l');
  }).then(() => {
    test.equal(
      rect.getAttribute('x'),
      '100',
      'changing attributes'
    );
  });
});

spec('Allows dynamic changes to DOM tree', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg l="50">
      <svg>
        <rect parametric:x="l" />
      </svg>
    </parametric-svg>
  `;
  const svg = document.querySelector('svg');

  delay(100).then(() => {
    const circle =
      document.createElementNS('http://www.w3.org/2000/svg', 'circle');
    circle.setAttribute('parametric:r', 'l');
    svg.appendChild(circle);

    return delay(100, {circle});
  }).then(({circle}) => {
    test.equal(
      circle.getAttribute('r'),
      '50',
      'adding elements'
    );
  });
});

spec('Works in a DOM structure built up programatically', (test) => {
  test.plan(4);

  setTimeout(() => {
    // For reliable, consistent results this spec must fire after the initial
    // render.

    const parametricSvg = document.createElement('parametric-svg');
    const svg = document.createElement('svg');
    const circle = document.createElement('circle');
    svg.appendChild(circle);
    parametricSvg.appendChild(svg);

    circle.setAttribute('r', '5');
    circle.setAttribute('cx', '0');
    circle.setAttribute('parametric:r', '2 * (3 + 5)');
    setImmediate(() => {
      circle.setAttribute('parametric:cx', '3 * 3');
    });

    test.equal(
      circle.getAttribute('r'),
      '5',
      'updates asynchronously'
    );

    waitForNextFrame().then(() => {
      test.equal(
        circle.getAttribute('r'),
        String(2 * (3 + 5)),
        'within a single animation frame'
      );

      test.equal(
        circle.getAttribute('cx'),
        '0',
        'throttles other updates'
      );

      return waitForNextFrame();
    }).then(() => {
      test.equal(
        circle.getAttribute('cx'),
        String(3 * 3),
        'and applies them in the next animation frame'
      );
    });
  });
});

spec('Only affects the first child SVG', (test) => {
  test.plan(2);

  document.body.innerHTML = `
    <parametric-svg>
      <svg>
      </svg>

      <svg>
        <rect parametric:x="50" />
      </svg>

<svg>
        <circle parametric:r="70" r="5" />
      </svg>

    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');

  test.equal(
    rect.getAttribute('x'),
    null,
    'leaves a second child untouched'
  );

  const circle = document.body.querySelector('circle');
  test.equal(
    circle.getAttribute('r'),
    '5',
    'leaves another nested child untouched'
  );
});

spec('Works with a nested SVG', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg>

        <svg>
          <rect parametric:x="5 / 5" />
        </svg>

    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');
  test.equal(
    rect.getAttribute('x'),
    String(5 / 5),
    'nested one level deep'
  );
});

spec('Supports variables', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg
      a="2"
      b="50"
      >
      <svg>
        <rect parametric:x="b / a" />
      </svg>
    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');
  test.equal(
    rect.getAttribute('x'),
    String(50 / 2),
    'passes multiple variables in the right order'
  );
});

spec('Only updates a parameter when all variables are defined', (test) => {
  test.plan(3);

  document.body.innerHTML = `
    <parametric-svg
      a="2"
      >
      <svg>
        <circle parametric:r="a + b" r="5" />
        <ellipse parametric:fill="c" />
        <rect parametric:x="a" />
      </svg>
    </parametric-svg>
  `;

  const circle = document.body.querySelector('circle');
  test.equal(
    circle.getAttribute('r'),
    '5',
    'doesn’t update an attribute when its dependencies aren’t satisfied'
  );

  const ellipse = document.body.querySelector('ellipse');
  test.equal(
    ellipse.getAttribute('fill'),
    null,
    'doesn’t create an attribute when its dependencies aren’t satisfied'
  );

  const rect = document.body.querySelector('rect');
  test.equal(
    rect.getAttribute('x'),
    '2',
    'updates another attribute with satisfied dependencies'
  );
});

spec('Updates variables dynamically', (test) => {
  test.plan(5);

  document.body.innerHTML = `
    <parametric-svg>
      <svg>
        <rect parametric:x="a" parametric:y="b" />
      </svg>
    </parametric-svg>
  `;

  recalculateCallback.reset();

  const rect = document.body.querySelector('rect');
  const parametricSvg = document.body.querySelector('parametric-svg');

  waitForNextFrame().then(() => {
    parametricSvg.setAttribute('a', '5');
    test.equal(
      rect.getAttribute('x'),
      '5',
      'updates parametric attributes synchronously'
    );

    return waitForNextFrame();
  }).then(() => {
    parametricSvg.setAttribute('a', '15');
    test.equal(
      rect.getAttribute('x'),
      '15',
      'does it repeatedly'
    );

    parametricSvg.removeAttribute('a');
    parametricSvg.setAttribute('b', '8');
    test.equal(
      rect.getAttribute('x'),
      '15',
      'leaves an attribute as it when a dependency is removed'
    );

    test.equal(
      rect.getAttribute('y'),
      '8',
      'but updates other attributes even so'
    );

    return waitForNextFrame();
  }).then(() => {
    test.equal(
      recalculateCallback.callCount,
      0,
      'does it efficiently, without reparsing the DOM tree'
    );
  });
});

spec('Supports different types of values', (test) => {
  document.body.innerHTML = `
    <parametric-svg>
      <svg>
        <rect
          parametric:x="left"
          parametric:y="down ? 10 : -10"
          parametric:fill="color"
        />
      </svg>
    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');
  const parametricSvg = document.body.querySelector('parametric-svg');

  parametricSvg.setAttribute('left', '5');
  test.equal(
    rect.getAttribute('x'),
    '5',
    'numbers'
  );

  parametricSvg.setAttribute('down', 'false');
  test.equal(
    rect.getAttribute('y'),
    '-10',
    'booleans'
  );

  parametricSvg.setAttribute('color', '`green`');
  test.equal(
    rect.getAttribute('fill'),
    'green',
    'strings'
  );

  test.end();
});

spec((
  'Doesn’t crash when setting an attribute when no <svg> is inside'
), (test) => {
  const parametricSvg = document.createElement('parametric-svg');
  parametricSvg.setAttribute('class', 'whatever');
  test.pass(
    'doesn’t throw an error'
  );
  test.end();
});
<commit_msg>Loosen test<commit_after>require('setimmediate');
  // This shims `setImmediate`

const spec = require('tape-catch');
const repeat = require('repeat-element');
const delay = require('timeout-as-promise');
const sinon = require('sinon');

const register = require('./register');

const waitForNextFrame = () => new Promise((resolve) => {
  requestAnimationFrame(resolve);
});

const recalculateCallback = sinon.spy();
register({ recalculateCallback });
  // This registers the <parametric-svg> thing on the actual `document`.

spec('Registers the <parametric-svg> element', (test) => {
  test.plan(7);

  const HTMLElement = () => {};
  const MutationObserver = () => {
    test.pass(
      'with a custom implementation of `MutationObserver`'
    );

    return {observe: () => {}};
  };

  const registerElement = (
    name, options
  ) => {
    const prototype = options.prototype;
    const extendsArg = options.extends || null;

    test.pass(
      'taking a custom implementation of `document`'
    );

    test.equal(
      name,
      'parametric-svg',
      'under the name <parametric-svg>'
    );

    test.equal(
      extendsArg,
      null,
      'as a standard HTML element – no bells and whistles'
    );

    test.equal(
      prototype.constructor,
      HTMLElement,
      'inheriting from the given `HTMLElement`'
    );

    test.equal(
      typeof prototype.createdCallback,
      'function',
      'attaching stuff to the createdCallback…'
    );

    test.deepEqual(
      [
        prototype.attachedCallback,
        prototype.detachedCallback,
        prototype.atributeChangedCallback,
      ],
      repeat(undefined, 3),
      '…and to no other lifecycle callback'
    );

    options.prototype.createdCallback.apply({
      querySelector: () => {},
    });
  };

  register({document: {registerElement}, HTMLElement, MutationObserver});
});

spec('Works in a DOM structure created in one go', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg>
      <svg>
        <rect parametric:x="50" />
      </svg>
    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');
  test.equal(
    rect.getAttribute('x'),
    '50',
    'synchronously'
  );
});

spec('Allows dynamic changes to attributes', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg l="50">
      <svg>
        <rect parametric:x="l" />
      </svg>
    </parametric-svg>
  `;
  const rect = document.querySelector('rect');

  delay(100).then(() => {
    rect.setAttribute('parametric:x', '2 * l');
  }).then(() => {
    test.equal(
      rect.getAttribute('x'),
      '100',
      'changing attributes'
    );
  });
});

spec('Allows dynamic changes to DOM tree', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg l="50">
      <svg>
        <rect parametric:x="l" />
      </svg>
    </parametric-svg>
  `;
  const svg = document.querySelector('svg');

  delay(100).then(() => {
    const circle =
      document.createElementNS('http://www.w3.org/2000/svg', 'circle');
    circle.setAttribute('parametric:r', 'l');
    svg.appendChild(circle);

    return delay(100, {circle});
  }).then(({circle}) => {
    test.equal(
      circle.getAttribute('r'),
      '50',
      'adding elements'
    );
  });
});

spec('Works in a DOM structure built up programatically', (test) => {
  test.plan(3);

  setTimeout(() => {
    // For reliable, consistent results this spec must fire after the initial
    // render.

    const parametricSvg = document.createElement('parametric-svg');
    const svg = document.createElement('svg');
    const circle = document.createElement('circle');
    svg.appendChild(circle);
    parametricSvg.appendChild(svg);

    circle.setAttribute('r', '5');
    circle.setAttribute('cx', '0');
    circle.setAttribute('parametric:r', '2 * (3 + 5)');
    setImmediate(() => {
      circle.setAttribute('parametric:cx', '3 * 3');
    });

    test.equal(
      circle.getAttribute('r'),
      '5',
      'updates asynchronously'
    );

    waitForNextFrame().then(() => {
      test.equal(
        circle.getAttribute('r'),
        String(2 * (3 + 5)),
        'within a single animation frame'
      );

      return waitForNextFrame();
    }).then(() => {
      test.equal(
        circle.getAttribute('cx'),
        String(3 * 3),
        'throttles other updates until the next animation frame at the latest'
      );
    });
  });
});

spec('Only affects the first child SVG', (test) => {
  test.plan(2);

  document.body.innerHTML = `
    <parametric-svg>
      <svg>
      </svg>

      <svg>
        <rect parametric:x="50" />
      </svg>

<svg>
        <circle parametric:r="70" r="5" />
      </svg>

    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');

  test.equal(
    rect.getAttribute('x'),
    null,
    'leaves a second child untouched'
  );

  const circle = document.body.querySelector('circle');
  test.equal(
    circle.getAttribute('r'),
    '5',
    'leaves another nested child untouched'
  );
});

spec('Works with a nested SVG', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg>

        <svg>
          <rect parametric:x="5 / 5" />
        </svg>

    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');
  test.equal(
    rect.getAttribute('x'),
    String(5 / 5),
    'nested one level deep'
  );
});

spec('Supports variables', (test) => {
  test.plan(1);

  document.body.innerHTML = `
    <parametric-svg
      a="2"
      b="50"
      >
      <svg>
        <rect parametric:x="b / a" />
      </svg>
    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');
  test.equal(
    rect.getAttribute('x'),
    String(50 / 2),
    'passes multiple variables in the right order'
  );
});

spec('Only updates a parameter when all variables are defined', (test) => {
  test.plan(3);

  document.body.innerHTML = `
    <parametric-svg
      a="2"
      >
      <svg>
        <circle parametric:r="a + b" r="5" />
        <ellipse parametric:fill="c" />
        <rect parametric:x="a" />
      </svg>
    </parametric-svg>
  `;

  const circle = document.body.querySelector('circle');
  test.equal(
    circle.getAttribute('r'),
    '5',
    'doesn’t update an attribute when its dependencies aren’t satisfied'
  );

  const ellipse = document.body.querySelector('ellipse');
  test.equal(
    ellipse.getAttribute('fill'),
    null,
    'doesn’t create an attribute when its dependencies aren’t satisfied'
  );

  const rect = document.body.querySelector('rect');
  test.equal(
    rect.getAttribute('x'),
    '2',
    'updates another attribute with satisfied dependencies'
  );
});

spec('Updates variables dynamically', (test) => {
  test.plan(5);

  document.body.innerHTML = `
    <parametric-svg>
      <svg>
        <rect parametric:x="a" parametric:y="b" />
      </svg>
    </parametric-svg>
  `;

  recalculateCallback.reset();

  const rect = document.body.querySelector('rect');
  const parametricSvg = document.body.querySelector('parametric-svg');

  waitForNextFrame().then(() => {
    parametricSvg.setAttribute('a', '5');
    test.equal(
      rect.getAttribute('x'),
      '5',
      'updates parametric attributes synchronously'
    );

    return waitForNextFrame();
  }).then(() => {
    parametricSvg.setAttribute('a', '15');
    test.equal(
      rect.getAttribute('x'),
      '15',
      'does it repeatedly'
    );

    parametricSvg.removeAttribute('a');
    parametricSvg.setAttribute('b', '8');
    test.equal(
      rect.getAttribute('x'),
      '15',
      'leaves an attribute as it when a dependency is removed'
    );

    test.equal(
      rect.getAttribute('y'),
      '8',
      'but updates other attributes even so'
    );

    return waitForNextFrame();
  }).then(() => {
    test.equal(
      recalculateCallback.callCount,
      0,
      'does it efficiently, without reparsing the DOM tree'
    );
  });
});

spec('Supports different types of values', (test) => {
  document.body.innerHTML = `
    <parametric-svg>
      <svg>
        <rect
          parametric:x="left"
          parametric:y="down ? 10 : -10"
          parametric:fill="color"
        />
      </svg>
    </parametric-svg>
  `;

  const rect = document.body.querySelector('rect');
  const parametricSvg = document.body.querySelector('parametric-svg');

  parametricSvg.setAttribute('left', '5');
  test.equal(
    rect.getAttribute('x'),
    '5',
    'numbers'
  );

  parametricSvg.setAttribute('down', 'false');
  test.equal(
    rect.getAttribute('y'),
    '-10',
    'booleans'
  );

  parametricSvg.setAttribute('color', '`green`');
  test.equal(
    rect.getAttribute('fill'),
    'green',
    'strings'
  );

  test.end();
});

spec((
  'Doesn’t crash when setting an attribute when no <svg> is inside'
), (test) => {
  const parametricSvg = document.createElement('parametric-svg');
  parametricSvg.setAttribute('class', 'whatever');
  test.pass(
    'doesn’t throw an error'
  );
  test.end();
});
<|endoftext|>


<commit_before>/*

            _/    _/_/    _/_/_/_/_/                              _/
               _/    _/      _/      _/_/    _/    _/    _/_/_/  _/_/_/
          _/  _/  _/_/      _/    _/    _/  _/    _/  _/        _/    _/
         _/  _/    _/      _/    _/    _/  _/    _/  _/        _/    _/
        _/    _/_/  _/    _/      _/_/      _/_/_/    _/_/_/  _/    _/
       _/
    _/

    Created by David Kaneda <http://www.davidkaneda.com>
    Maintained by Thomas Yip <http://beedesk.com/>
    Sponsored by Sencha Labs <http://www.sencha.com/>
    Special thanks to Jonathan Stark <http://www.jonathanstark.com/>

    Documentation and issue tracking on GitHub <http://github.com/senchalabs/jQTouch/>

    (c) 2009-2012 Sencha Labs
    jQTouch may be freely distributed under the MIT license.
*/

(function($) {
    var src = $("head script").last().attr("src") || '';
    var scriptpath = src.split('?')[0].split('/').slice(0, -1).join('/')+'/';
    var csspath = scriptpath + 'jqt.menusheet.css';
    var link = $('<link href="' + csspath + '" rel="stylesheet">');
    $('head').append($(link));

    function hide(callback) {
        var $target = $(this);
        var data = $(this).data('menusheet');
        if (data.shown) {
            $(this).data('menusheet', {});
            var $source = data.source;
            $target.trigger('pageAnimationStart', {
                direction: 'out', animation: undefined, back: true
            });
            $source.unbind('touchstart mousedown', data.closehandler);
            $source.one('webkitTransitionEnd', function() {
                $source.removeClass('inmotion transition in');
                $target.removeClass('inmotion out');
                $target.trigger('pageAnimationEnd', {
                    direction: 'out', animation: undefined, back: true
                });
                !callback || callback.apply(this, arguments);
            });

            $source.addClass('inmotion transition in');
            $target.addClass('inmotion out').removeClass('current');
            $('#jqt').removeClass('menuopened');
        }
        return $target;
    }

    function show(callback) {
        var $target = $(this);
        var data = $(this).data('menusheet') || {};
        if (!data.shown) {
            var $source = $('#jqt .current:not(.menusheet)');
            $target.trigger('pageAnimationStart', {
                direction: 'in', animation: undefined, back: false
            });
            var closehandler = function() {
                $target.menusheet('hide');
                return false;
            };

            $source.one('webkitTransitionEnd', function() {
                $source.one('touchstart mousedown', closehandler);
                $source.removeClass('inmotion transition out');
                $target.removeClass('inmotion in');
                $target.trigger('pageAnimationEnd', {
                    direction: 'in', animation: undefined, back: false
                });
                !callback || callback.apply(this, arguments);
            });

            data.shown = true;
            data.closehandler = closehandler;
            data.source = $source;
            $(this).data('menusheet', data);

            $source.addClass('inmotion transition out');
            $target.addClass('current in');
            $('#jqt').addClass('menuopened');
        }
        return $target;
    }

    var methods = {
        init: function(options) {
            $(this).addClass('menusheet');
            $(this).data('menusheet', {shown: false});
        },
        show: show,
        hide: hide
    };

    $.fn.menusheet = function(method) {
      if (methods[method]) {
          if ($(this).is('.menusheet')) {
              return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
          } else {
              var msg = 'Target is not a `menusheet`. Action `' + method + '` is ignored.';
              console.warn(msg);
          }
      } else if ( typeof method === 'object' || ! method ) {
          return methods.init.apply(this, arguments);
      } else {
          $.error('Method "' + method + '" does not exist on jqt.menusheet' );
      }
    };

    if ($.jQT) {
        $.jQT.addTapHandler({
            name: 'open-menusheet',
            isSupported: function(e, params) {
                return params.$el.is('.menu');
            },
            fn: function(e, params) {
                params.$el.removeClass('active');

                var $target = $(params.hash);
                $target.menusheet('show');

                return false;
            }
        });
        $.jQT.addTapHandler({
            name: 'follow-menulink',
            isSupported: function(e, params) {
                if ($('#jqt').hasClass('menuopened')) {
                    return params.$el.is('.menusheet a');
                }
                return false;
            },
            fn: function(e, params) {
                params.$el.removeClass('active');

                var $target = params.$el.closest('.menusheet');
                $target.menusheet('hide', function() {
                    if (!params.$el.is('.dismiss')) {
                      params.$el.trigger('tap');
                    }
                });
                return false;
            }
        });
    } else {
        console.error('Extension `jqt.menusheet` failed to load. jQT not found');
    }
})($);
<commit_msg>Don't do link appending.<commit_after>/*

            _/    _/_/    _/_/_/_/_/                              _/
               _/    _/      _/      _/_/    _/    _/    _/_/_/  _/_/_/
          _/  _/  _/_/      _/    _/    _/  _/    _/  _/        _/    _/
         _/  _/    _/      _/    _/    _/  _/    _/  _/        _/    _/
        _/    _/_/  _/    _/      _/_/      _/_/_/    _/_/_/  _/    _/
       _/
    _/

    Created by David Kaneda <http://www.davidkaneda.com>
    Maintained by Thomas Yip <http://beedesk.com/>
    Sponsored by Sencha Labs <http://www.sencha.com/>
    Special thanks to Jonathan Stark <http://www.jonathanstark.com/>

    Documentation and issue tracking on GitHub <http://github.com/senchalabs/jQTouch/>

    (c) 2009-2012 Sencha Labs
    jQTouch may be freely distributed under the MIT license.
*/

(function($) {
    function hide(callback) {
        var $target = $(this);
        var data = $(this).data('menusheet');
        if (data.shown) {
            $(this).data('menusheet', {});
            var $source = data.source;
            $target.trigger('pageAnimationStart', {
                direction: 'out', animation: undefined, back: true
            });
            $source.unbind('touchstart mousedown', data.closehandler);
            $source.one('webkitTransitionEnd', function() {
                $source.removeClass('inmotion transition in');
                $target.removeClass('inmotion out');
                $target.trigger('pageAnimationEnd', {
                    direction: 'out', animation: undefined, back: true
                });
                !callback || callback.apply(this, arguments);
            });

            $source.addClass('inmotion transition in');
            $target.addClass('inmotion out').removeClass('current');
            $('#jqt').removeClass('menuopened');
        }
        return $target;
    }

    function show(callback) {
        var $target = $(this);
        var data = $(this).data('menusheet') || {};
        if (!data.shown) {
            var $source = $('#jqt .current:not(.menusheet)');
            $target.trigger('pageAnimationStart', {
                direction: 'in', animation: undefined, back: false
            });
            var closehandler = function() {
                $target.menusheet('hide');
                return false;
            };

            $source.one('webkitTransitionEnd', function() {
                $source.one('touchstart mousedown', closehandler);
                $source.removeClass('inmotion transition out');
                $target.removeClass('inmotion in');
                $target.trigger('pageAnimationEnd', {
                    direction: 'in', animation: undefined, back: false
                });
                !callback || callback.apply(this, arguments);
            });

            data.shown = true;
            data.closehandler = closehandler;
            data.source = $source;
            $(this).data('menusheet', data);

            $source.addClass('inmotion transition out');
            $target.addClass('current in');
            $('#jqt').addClass('menuopened');
        }
        return $target;
    }

    var methods = {
        init: function(options) {
            $(this).addClass('menusheet');
            $(this).data('menusheet', {shown: false});
        },
        show: show,
        hide: hide
    };

    $.fn.menusheet = function(method) {
      if (methods[method]) {
          if ($(this).is('.menusheet')) {
              return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
          } else {
              var msg = 'Target is not a `menusheet`. Action `' + method + '` is ignored.';
              console.warn(msg);
          }
      } else if ( typeof method === 'object' || ! method ) {
          return methods.init.apply(this, arguments);
      } else {
          $.error('Method "' + method + '" does not exist on jqt.menusheet' );
      }
    };

    if ($.jQT) {
        $.jQT.addTapHandler({
            name: 'open-menusheet',
            isSupported: function(e, params) {
                return params.$el.is('.menu');
            },
            fn: function(e, params) {
                params.$el.removeClass('active');

                var $target = $(params.hash);
                $target.menusheet('show');

                return false;
            }
        });
        $.jQT.addTapHandler({
            name: 'follow-menulink',
            isSupported: function(e, params) {
                if ($('#jqt').hasClass('menuopened')) {
                    return params.$el.is('.menusheet a');
                }
                return false;
            },
            fn: function(e, params) {
                params.$el.removeClass('active');

                var $target = params.$el.closest('.menusheet');
                $target.menusheet('hide', function() {
                    if (!params.$el.is('.dismiss')) {
                      params.$el.trigger('tap');
                    }
                });
                return false;
            }
        });
    } else {
        console.error('Extension `jqt.menusheet` failed to load. jQT not found');
    }
})($);
<|endoftext|>


<commit_before>
/**
 * Prevent circular dependencies.
 */

import './block'
import './inline'

/**
 * Dependencies.
 */

import Block from './block'
import Node from './node'
import generateKey from '../utils/generate-key'
import { OrderedMap, Record } from 'immutable'

/**
 * Default properties.
 *
 * @type {Object}
 */

const DEFAULTS = {
  key: null,
  nodes: new OrderedMap(),
}

/**
 * Document.
 *
 * @type {Document}
 */

class Document extends new Record(DEFAULTS) {

  /**
   * Create a new `Document` with `properties`.
   *
   * @param {Object|Document} properties
   * @return {Document}
   */

  static create(properties = {}) {
    if (properties instanceof Document) return properties

    properties.key = properties.key || generateKey()
    properties.nodes = Block.createList(properties.nodes)

    return new Document(properties)
  }

  /**
   * Get the node's kind.
   *
   * @return {String}
   */

  get kind() {
    return 'document'
  }

  /**
   * Is the document empty?
   *
   * @return {Boolean}
   */

  get isEmpty() {
    return this.text == ''
  }

  /**
   * Get the length of the concatenated text of the document.
   *
   * @return {Number}
   */

  get length() {
    return this.text.length
  }

  /**
   * Get the concatenated text `string` of all child nodes.
   *
   * @return {String}
   */

  get text() {
    return this.getText()
  }

}

/**
 * Mix in `Node` methods.
 */

for (const method in Node) {
  Document.prototype[method] = Node[method]
}

/**
 * Export.
 *
 * @type {Document}
 */

export default Document
<commit_msg>fix to default document.nodes to an immutable list, closes #460<commit_after>
/**
 * Prevent circular dependencies.
 */

import './block'
import './inline'

/**
 * Dependencies.
 */

import Block from './block'
import Node from './node'
import generateKey from '../utils/generate-key'
import { List, Record } from 'immutable'

/**
 * Default properties.
 *
 * @type {Object}
 */

const DEFAULTS = {
  key: null,
  nodes: new List(),
}

/**
 * Document.
 *
 * @type {Document}
 */

class Document extends new Record(DEFAULTS) {

  /**
   * Create a new `Document` with `properties`.
   *
   * @param {Object|Document} properties
   * @return {Document}
   */

  static create(properties = {}) {
    if (properties instanceof Document) return properties

    properties.key = properties.key || generateKey()
    properties.nodes = Block.createList(properties.nodes)

    return new Document(properties)
  }

  /**
   * Get the node's kind.
   *
   * @return {String}
   */

  get kind() {
    return 'document'
  }

  /**
   * Is the document empty?
   *
   * @return {Boolean}
   */

  get isEmpty() {
    return this.text == ''
  }

  /**
   * Get the length of the concatenated text of the document.
   *
   * @return {Number}
   */

  get length() {
    return this.text.length
  }

  /**
   * Get the concatenated text `string` of all child nodes.
   *
   * @return {String}
   */

  get text() {
    return this.getText()
  }

}

/**
 * Mix in `Node` methods.
 */

for (const method in Node) {
  Document.prototype[method] = Node[method]
}

/**
 * Export.
 *
 * @type {Document}
 */

export default Document
<|endoftext|>


<commit_before>import getCenter from '../../../shared/services/geo-json/geo-json'
import { rdToWgs84 } from '../../../shared/services/coordinate-reference-system/crs-converter'

import { getByUrl } from '../../../shared/services/api/api'

export default function fetchByUri(uri, normalization = params => params) {
  return getByUrl(uri).then(async result => {
    const normalizedData = await normalization(result)

    const geometry = result.geometry || normalizedData.geometry

    const geometryCenter = geometry && getCenter(geometry)
    const wgs84Center = geometryCenter ? rdToWgs84(geometryCenter) : null

    return {
      label: result._display,
      ...(normalizedData || result),
      location: result.location || wgs84Center,
      geometrie: geometry,
    }
  })
}
<commit_msg>Inluded some more tests<commit_after>import getCenter from '../../../shared/services/geo-json/geo-json'
import { rdToWgs84 } from '../../../shared/services/coordinate-reference-system/crs-converter'

import { getByUrl } from '../../../shared/services/api/api'

export default async function fetchByUri(uri, normalization = false) {
  const result = await getByUrl(uri)

  // as some APIs return data in a different format than the frontend wants to display
  // some API results are normalized or even enhanced with results from additional API calls
  let normalizedData = false
  if (normalization) {
    normalizedData = await normalization(result)
  }

  // "geometrie" is often returned from the instance API, "gemoetry" is created by the normalizers
  const geometry = result.geometrie || result.geometry || normalizedData.geometry

  const geometryCenter = geometry && getCenter(geometry)
  const wgs84Center = geometryCenter ? rdToWgs84(geometryCenter) : null

  return {
    label: result._display,
    ...(normalizedData || result),
    // "label" may be overwritten by the result or normalizedData, but the location and geometry are constructed above
    location: result.location || wgs84Center,
    geometrie: geometry,
  }
}
<|endoftext|>


<commit_before>'use strict';

var Fs = require('fs');
var Path = require('path');

var EsprimaHelpers = require('./helpers/esprima');
var Config = require('./config/config');

var FSLASH = '/';
var NEWLINE = '\n';
var NEWLINE_REGEXP = /\n/g;
var TAB = '    '; // 4 spaces!
var SAFE_NAMESPACE_DELIMITER = '~';

function indent(str) {
    return (TAB + str).replace(NEWLINE_REGEXP, NEWLINE + TAB);
}

function copyright() {
    var startYear = '2015';
    var currYear = new Date().getFullYear().toString();
    var yearStr = startYear;

    if (currYear !== startYear) {
        yearStr += ('-' + currYear);
    }

    return '// Copyright ' + yearStr + ' (c) Famous Industries, Inc.';
}

function iterateDependenciesIn(data, iterator) {
    for (var i = 0; i < data.builtDependencyTuples.length; i++) {
        var tuple = data.builtDependencyTuples[i];

        iterator(tuple[0], tuple[1], tuple[2], tuple[3]);
    }
}

function componentRelativeURL(name, version) {
    return name.split(Config.get('componentDelimiter')).join(FSLASH);
}

function componentNameSafeDelimited(name, version) {
    return name.split(Config.get('componentDelimiter')).join(SAFE_NAMESPACE_DELIMITER);
}

function expandBaseURLTokens(name, version, string) {
    var baseURLToken = Config.get('baseURLToken');
    var fixedString = string.split(baseURLToken).join(componentRelativeURL(name, version) + FSLASH);
    return fixedString;
}

function expandBaseURLSyntax(name, version, entrypointAST) {
    EsprimaHelpers.eachStringLiteral(entrypointAST, function(value, node, parent) {
        node.value = expandBaseURLTokens(name, version, value);
    });
}

function buildEntrypointString(name, version, data) {
    try {
        expandBaseURLSyntax(name, version, data.entrypointAST);
        return EsprimaHelpers.generate(data.entrypointAST);
    }
    catch (entrypointBuildErr) {
        console.error('Esprima says:', entrypointBuildErr);
        console.error('Failed to build `' + name + '` (' + version + ') entrypoint; this is most likely a problem with the framework build tool');
        // Inline an error message so that the developer sees this in the browser too
        return 'console.error("The build of `' + name + '` (' + version + ') failed; this is most likely a problem with the framework build tool");';
    }
}

function buildCodeBlock(name, version, data) {
    var codeBlock = [];
    codeBlock.push('(function(){');
    codeBlock.push(indent(buildEntrypointString(name, version, data)));
    codeBlock.push('}());');
    return codeBlock.join(NEWLINE);
}

function buildCodeBlocks(outArray, name, version, data) {
    iterateDependenciesIn(data, function(depName, depVersion, depFiles, depData) {
        buildCodeBlocks(outArray, depName, depVersion, depData);
    });
    outArray.push(buildCodeBlock(name, version, data));
    return outArray.join(NEWLINE);
}

function getIncludeURLs(outArray, name, version, data) {
    for (var i = 0; i < data.moduleConfigObjects.length; i++) {
        var configObject = data.moduleConfigObjects[i];
        var includesArray = configObject[Config.get('includesKeyName')];

        if (includesArray) {
            for (var j = 0; j < includesArray.length; j++) {
                outArray.push(componentRelativeURL(name, version) + FSLASH + includesArray[j]);
            }
        }
    }

    iterateDependenciesIn(data, function(depName, depVersion, depFiles, depData) {
        getIncludeURLs(outArray, depName, depVersion, depData);
    });
}

function buildIncludesPrefix(name, version, data) {
    var includeURLs = [];
    getIncludeURLs(includeURLs, name, version, data);
    return 'FamousFramework.includes("' + name + '", "' + version + '", ' + JSON.stringify(includeURLs) + ', function() {';
}

function buildBundleString(name, files, data) {
    var version = Config.get('defaultDependencyVersion');
    return [
        copyright(),
        '"use strict";',
        buildIncludesPrefix(name, version, data),
        indent(buildCodeBlocks([], name, version, data)),
        indent('FamousFramework.markComponentAsReady("' + name + '", "' + version + '");'),
        '});'
    ].join(NEWLINE);
}

function buildIndexString(name, file, data) {
    // Important: This line needs to remain statically analyzable so it can be
    // substituted by brfs
    var rawString = Fs.readFileSync(Path.join(__dirname, 'templates', 'index.html'), 'utf8');

    var outString = rawString.split('{{componentNameSafeDelimited}}').join(componentNameSafeDelimited(name));
    outString = outString.split('{{componentName}}').join(name);
    outString = outString.split('{{componentVersion}}').join(Config.get('defaultDependencyVersion'));
    outString = outString.split('{{frameworkBundleURL}}').join(Config.get('frameworkBundleURL'));
    return outString;
}

function buildFlatProjectFiles(outArray, name, version, files, data) {
    for (var i = 0; i < files.length; i++) {
        var file = files[i];

        outArray.push({
            path: componentRelativeURL(name, version) + Path.sep + file.path,
            content: file.content
        });
    }

    iterateDependenciesIn(data, function(depName, depVersion, depFiles, depData) {
        buildFlatProjectFiles(outArray, depName, depVersion, depFiles, depData);
    });

    return outArray;
}

function buildBundle(name, files, data, finish) {
    var flatProjectFiles = buildFlatProjectFiles([], name, Config.get('defaultDependencyVersion'), files, data);

    flatProjectFiles.push({
        path: componentNameSafeDelimited(name) + '.bundle.js',
        content: buildBundleString(name, files, data)
    });

    flatProjectFiles.push({
        path: 'index.html',
        content: buildIndexString(name, files, data)
    });

    data.flatProjectFiles = flatProjectFiles;

    return finish(null, name, files, data);
}

module.exports = buildBundle;
<commit_msg>chore: Unshift dependencies to the beginning of the bundle<commit_after>'use strict';

var Fs = require('fs');
var Path = require('path');

var EsprimaHelpers = require('./helpers/esprima');
var Config = require('./config/config');

var FSLASH = '/';
var NEWLINE = '\n';
var NEWLINE_REGEXP = /\n/g;
var TAB = '    '; // 4 spaces!
var SAFE_NAMESPACE_DELIMITER = '~';

function indent(str) {
    return (TAB + str).replace(NEWLINE_REGEXP, NEWLINE + TAB);
}

function copyright() {
    var startYear = '2015';
    var currYear = new Date().getFullYear().toString();
    var yearStr = startYear;

    if (currYear !== startYear) {
        yearStr += ('-' + currYear);
    }

    return '// Copyright ' + yearStr + ' (c) Famous Industries, Inc.';
}

function iterateDependenciesIn(data, iterator) {
    for (var i = 0; i < data.builtDependencyTuples.length; i++) {
        var tuple = data.builtDependencyTuples[i];

        iterator(tuple[0], tuple[1], tuple[2], tuple[3]);
    }
}

function componentRelativeURL(name, version) {
    return name.split(Config.get('componentDelimiter')).join(FSLASH);
}

function componentNameSafeDelimited(name, version) {
    return name.split(Config.get('componentDelimiter')).join(SAFE_NAMESPACE_DELIMITER);
}

function expandBaseURLTokens(name, version, string) {
    var baseURLToken = Config.get('baseURLToken');
    var fixedString = string.split(baseURLToken).join(componentRelativeURL(name, version) + FSLASH);
    return fixedString;
}

function expandBaseURLSyntax(name, version, entrypointAST) {
    EsprimaHelpers.eachStringLiteral(entrypointAST, function(value, node, parent) {
        node.value = expandBaseURLTokens(name, version, value);
    });
}

function buildEntrypointString(name, version, data) {
    try {
        expandBaseURLSyntax(name, version, data.entrypointAST);
        return EsprimaHelpers.generate(data.entrypointAST);
    }
    catch (entrypointBuildErr) {
        console.error('Esprima says:', entrypointBuildErr);
        console.error('Failed to build `' + name + '` (' + version + ') entrypoint; this is most likely a problem with the framework build tool');
        // Inline an error message so that the developer sees this in the browser too
        return 'console.error("The build of `' + name + '` (' + version + ') failed; this is most likely a problem with the framework build tool");';
    }
}

function buildCodeBlock(name, version, data) {
    var codeBlock = [];
    codeBlock.push('(function(){');
    codeBlock.push(indent(buildEntrypointString(name, version, data)));
    codeBlock.push('}());');
    return codeBlock.join(NEWLINE);
}

function nameVersionKey(name, version) {
    return name + '~' + version;
}

function buildCodeBlocks(outArray, depsAdded, name, version, data) {
    var depKeys = Object.keys(data.dependencyTable);
    if (depKeys.length > 0) {
        iterateDependenciesIn(data, function(depName, depVersion, depFiles, depData) {
            buildCodeBlocks(outArray, depsAdded, depName, depVersion, depData);
        });
        outArray.push(buildCodeBlock(name, version, data));
        depsAdded.push([name, version]);
    }
    else {
        outArray.unshift(buildCodeBlock(name, version, data));
        depsAdded.unshift([name, version]);
    }
    return outArray.join(NEWLINE);
}

function getIncludeURLs(outArray, name, version, data) {
    for (var i = 0; i < data.moduleConfigObjects.length; i++) {
        var configObject = data.moduleConfigObjects[i];
        var includesArray = configObject[Config.get('includesKeyName')];

        if (includesArray) {
            for (var j = 0; j < includesArray.length; j++) {
                outArray.push(componentRelativeURL(name, version) + FSLASH + includesArray[j]);
            }
        }
    }

    iterateDependenciesIn(data, function(depName, depVersion, depFiles, depData) {
        getIncludeURLs(outArray, depName, depVersion, depData);
    });
}

function buildIncludesPrefix(name, version, data) {
    var includeURLs = [];
    getIncludeURLs(includeURLs, name, version, data);
    return 'FamousFramework.includes("' + name + '", "' + version + '", ' + JSON.stringify(includeURLs) + ', function() {';
}

function buildBundleString(name, files, data) {
    var version = Config.get('defaultDependencyVersion');
    var depsAdded = [];
    var output = [
        copyright(),
        '"use strict";',
        buildIncludesPrefix(name, version, data),
        indent(buildCodeBlocks([], depsAdded, name, version, data)),
        indent('FamousFramework.markComponentAsReady("' + name + '", "' + version + '");'),
        '});'
    ].join(NEWLINE);
    return output;
}

function buildIndexString(name, file, data) {
    // Important: This line needs to remain statically analyzable so it can be
    // substituted by brfs
    var rawString = Fs.readFileSync(Path.join(__dirname, 'templates', 'index.html'), 'utf8');

    var outString = rawString.split('{{componentNameSafeDelimited}}').join(componentNameSafeDelimited(name));
    outString = outString.split('{{componentName}}').join(name);
    outString = outString.split('{{componentVersion}}').join(Config.get('defaultDependencyVersion'));
    outString = outString.split('{{frameworkBundleURL}}').join(Config.get('frameworkBundleURL'));
    return outString;
}

function buildFlatProjectFiles(outArray, name, version, files, data) {
    for (var i = 0; i < files.length; i++) {
        var file = files[i];

        outArray.push({
            path: componentRelativeURL(name, version) + Path.sep + file.path,
            content: file.content
        });
    }

    iterateDependenciesIn(data, function(depName, depVersion, depFiles, depData) {
        buildFlatProjectFiles(outArray, depName, depVersion, depFiles, depData);
    });

    return outArray;
}

function buildBundle(name, files, data, finish) {
    var flatProjectFiles = buildFlatProjectFiles([], name, Config.get('defaultDependencyVersion'), files, data);

    flatProjectFiles.push({
        path: componentNameSafeDelimited(name) + '.bundle.js',
        content: buildBundleString(name, files, data)
    });

    flatProjectFiles.push({
        path: 'index.html',
        content: buildIndexString(name, files, data)
    });

    data.flatProjectFiles = flatProjectFiles;

    return finish(null, name, files, data);
}

module.exports = buildBundle;
<|endoftext|>


<commit_before>/*
* Google Docs Interface
* 2014 Jake Whiteley <twentyzerotwo.co.uk>
*/
(function ( $ ) {
	$.extend({
		getGoogleDoc: function (urlKey, callback) {
			var self = this,
				// results holder
				results = [];

			// converts the return data from Google into a usable array
			this.parseEntry = function (a) {
				var keys = [];
				// get keys
				for (k in a[0])
					if (k.match(/gsx/) !== null)
						keys.push(k.replace('gsx$', ''))
				// create results array
				for (var i = 0, t = {}; i < a.length; t = {}, i++) {
					for (k in keys)
						if (keys.hasOwnProperty(k)) {
							var result = (a[i]['gsx$' + keys[k]]['$t'].length > 0 ? a[i]['gsx$' + keys[k]]['$t'] : null);
							// push result to results holder, type cast numbers if needed
							t[ keys[k] ] = ( !isNaN( parseInt(result) ) ? parseInt(result) : result )
						}
					// add result to holder
					results.push(t)
				}
			};

			// make GET request, and return promise for chaining
			return $.getJSON(
				"https://spreadsheets.google.com/feeds/list/"+urlKey+"/od6/public/values?alt=json",
				function (a, b, c) {
					// if the sheet was empty
					if (typeof a.feed.entry === 'undefined') {
						console.error('$.getGoogleDoc: The sheet was empty')
					}
					else {
						// parse the results
						self.parseEntry(a.feed.entry)
						// callback
						if (typeof callback == 'function')
							callback(results)
						else if (typeof callback != 'undefined')
							console.error('$.getGoogleDoc: Please use a function as a callback. You provided a ' + typeof callback)
					}
				}
			).fail(function () {
				console.error('$.getGoogleDoc: Invalid key provided')
				return false;
			});
		}
	});
}( jQuery ));
<commit_msg>Changed getJSON request to JSONP for IE8/9 support<commit_after>/*
* Google Docs Interface
* 2014 Jake Whiteley <twentyzerotwo.co.uk>
*/
(function ( $ ) {
	$.extend({
		getGoogleDoc: function (urlKey, callback) {
			var self = this,
				// results holder
				results = [];

			// converts the return data from Google into a usable array
			this.parseEntry = function (a) {
				var keys = [];
				// get keys
				for (k in a[0])
					if (k.match(/gsx/) !== null)
						keys.push(k.replace('gsx$', ''))
				// create results array
				for (var i = 0, t = {}; i < a.length; t = {}, i++) {
					for (k in keys)
						if (keys.hasOwnProperty(k)) {
							var result = (a[i]['gsx$' + keys[k]]['$t'].length > 0 ? a[i]['gsx$' + keys[k]]['$t'] : null);
							// push result to results holder, type cast numbers if needed
							t[ keys[k] ] = ( !isNaN( parseInt(result) ) ? parseInt(result) : result )
						}
					// add result to holder
					results.push(t)
				}
			};

			// make GET request, and return promise for chaining
			return $.getJSON(
				"https://spreadsheets.google.com/feeds/list/"+urlKey+"/od6/public/values?alt=json&callback=?",
				function (a, b, c) {
					// if the sheet was empty
					if (typeof a.feed.entry === 'undefined') {
						console.error('$.getGoogleDoc: The sheet was empty')
					}
					else {
						// parse the results
						self.parseEntry(a.feed.entry)
						// callback
						if (typeof callback == 'function')
							callback(results)
						else if (typeof callback != 'undefined')
							console.error('$.getGoogleDoc: Please use a function as a callback. You provided a ' + typeof callback)
					}
				}
			).fail(function () {
				console.error('$.getGoogleDoc: Invalid key provided')
				return false;
			});
		}
	});
}( jQuery ));
<|endoftext|>


<commit_before>setTimeout(function() {
$("#canvas").remove();
$("#adsBottom").remove();
$("#rightPanel").remove();
$(".agario-panel.agario-side-panel.agario-profile-panel").remove();
$("#dailyquests-panel").remove();
$("#v-ex-menu").remove();
$(".radio-module").remove();
$(".tosBox.right").remove();
$(".tosBox.left").remove();
$(".form-group.clearfix").remove();
$("#skinCustomButton").remove();
$("#settings").remove();
$("#vanilla-home-link").remove();
$("#settingsButton").remove();
$("#instructions").remove();
$(".btn.btn-play.btn-primary").remove();
$(".btn.btn-play-guest.btn-success").remove();
$(".btn.btn-warning.btn-login-play").text("Login");
$(".btn.btn-warning.btn-login-play").css("margin-left", "80px");
$("#helloContainer").css("margin-left", "-150px");
$('.agario-panel.agario-side-panel.agario-shop-panel').append('<button id="logoutbtn" onclick="logout(); return false;" class="btn btn-danger btn-logout" data-itr="page_logout">Logout</button>');
$("#imagebig").remove();

}, 7000);
<commit_msg>Delete oldskins.js<commit_after><|endoftext|>


<commit_before>import {
  checkResolved,
  getComponents,
  getRouteMatches,
  getRouteValues,
  isResolved,
} from 'found/lib/ResolverUtils';
import isPromise from 'is-promise';
import isEqual from 'lodash/isEqual';
import React from 'react';

import QuerySubscription from './QuerySubscription';
import ReadyStateRenderer from './ReadyStateRenderer';
import renderElement from './renderElement';

export default class Resolver {
  constructor(environment) {
    this.environment = environment;

    this.lastQueries = [];
    this.lastRouteVariables = [];
    this.lastQuerySubscriptions = [];
  }

  async *resolveElements(match) {
    const routeMatches = getRouteMatches(match);

    const Components = getComponents(routeMatches);
    const queries = getRouteValues(
      routeMatches,
      route => route.getQuery,
      route => route.query,
    );
    const cacheConfigs = getRouteValues(
      routeMatches,
      route => route.getCacheConfig,
      route => route.cacheConfig,
    );

    const routeVariables = this.getRouteVariables(routeMatches);
    const querySubscriptions = this.updateQuerySubscriptions(
      queries,
      routeVariables,
      cacheConfigs,
    );

    const fetches = querySubscriptions.map(
      querySubscription => querySubscription && querySubscription.fetch(),
    );

    const earlyComponents = Components.some(isPromise)
      ? await Promise.all(Components.map(checkResolved))
      : Components;
    const earlyData = await Promise.all(fetches.map(checkResolved));

    let fetchedComponents;

    if (!earlyComponents.every(isResolved) || !earlyData.every(isResolved)) {
      const pendingElements = this.createElements(
        routeMatches,
        earlyComponents,
        querySubscriptions,
        false,
      );

      yield pendingElements.every(element => element !== undefined)
        ? pendingElements
        : undefined;

      fetchedComponents = await Promise.all(Components);
      await Promise.all(fetches);
    } else {
      fetchedComponents = earlyComponents;
    }

    yield this.createElements(
      routeMatches,
      fetchedComponents,
      querySubscriptions,
      true,
    );
  }

  getRouteVariables(routeMatches) {
    let variables = null;

    return routeMatches.map(routeMatch => {
      const { route } = routeMatch;

      // We need to always run this to make sure we don't miss route params.
      variables = { ...variables, ...routeMatch.routeParams };
      if (route.prepareVariables) {
        variables = route.prepareVariables(variables, routeMatch);
      }

      return variables;
    });
  }

  updateQuerySubscriptions(queries, routeVariables, cacheConfigs) {
    const {
      createOperationSelector,
      getOperation,
    } = this.environment.unstable_internal;

    const querySubscriptions = queries.map((query, i) => {
      if (!query) {
        return null;
      }

      const variables = routeVariables[i];

      if (
        this.lastQueries[i] === query &&
        isEqual(this.lastRouteVariables[i], variables)
      ) {
        // Match the logic in <QueryRenderer> for not refetching.
        const lastQuerySubscription = this.lastQuerySubscriptions[i];
        this.lastQuerySubscriptions[i] = null;
        return lastQuerySubscription;
      }

      return new QuerySubscription(
        this.environment,
        createOperationSelector(getOperation(query), variables),
        cacheConfigs[i],
      );
    });

    this.lastQuerySubscriptions.forEach(querySubscription => {
      if (querySubscription) {
        querySubscription.dispose();
      }
    });

    this.lastQueries = queries;
    this.lastRouteVariables = routeVariables;
    this.lastQuerySubscriptions = querySubscriptions;

    return querySubscriptions;
  }

  createElements(routeMatches, Components, querySubscriptions, fetched) {
    return routeMatches.map((match, i) => {
      const { route } = match;

      const Component = Components[i];
      const querySubscription = querySubscriptions[i];

      const isComponentResolved = isResolved(Component);

      // Handle non-Relay routes.
      if (!querySubscription) {
        if (route.render) {
          return route.render({
            match,
            Component: isComponentResolved ? Component : null,
            props: match,
          });
        }

        if (!isComponentResolved) {
          return undefined;
        }

        return Component ? <Component {...match} /> : null;
      }

      const resolvedComponent = isComponentResolved ? Component : null;
      const hasComponent = Component != null;

      const element = renderElement({
        match,
        Component: resolvedComponent,
        isComponentResolved,
        hasComponent,
        readyState: querySubscription.readyState,
        resolving: true,
      });

      if (element === undefined) {
        return element;
      }

      return (
        <ReadyStateRenderer
          match={match}
          Component={resolvedComponent}
          isComponentResolved={isComponentResolved}
          hasComponent={hasComponent}
          element={element}
          querySubscription={querySubscription}
          fetched={fetched}
        />
      );
    });
  }
}
<commit_msg>Support getRequest instead of getOperation from relay<commit_after>import {
  checkResolved,
  getComponents,
  getRouteMatches,
  getRouteValues,
  isResolved,
} from 'found/lib/ResolverUtils';
import isPromise from 'is-promise';
import isEqual from 'lodash/isEqual';
import React from 'react';

import QuerySubscription from './QuerySubscription';
import ReadyStateRenderer from './ReadyStateRenderer';
import renderElement from './renderElement';

export default class Resolver {
  constructor(environment) {
    this.environment = environment;

    this.lastQueries = [];
    this.lastRouteVariables = [];
    this.lastQuerySubscriptions = [];
  }

  async *resolveElements(match) {
    const routeMatches = getRouteMatches(match);

    const Components = getComponents(routeMatches);
    const queries = getRouteValues(
      routeMatches,
      route => route.getQuery,
      route => route.query,
    );
    const cacheConfigs = getRouteValues(
      routeMatches,
      route => route.getCacheConfig,
      route => route.cacheConfig,
    );

    const routeVariables = this.getRouteVariables(routeMatches);
    const querySubscriptions = this.updateQuerySubscriptions(
      queries,
      routeVariables,
      cacheConfigs,
    );

    const fetches = querySubscriptions.map(
      querySubscription => querySubscription && querySubscription.fetch(),
    );

    const earlyComponents = Components.some(isPromise)
      ? await Promise.all(Components.map(checkResolved))
      : Components;
    const earlyData = await Promise.all(fetches.map(checkResolved));

    let fetchedComponents;

    if (!earlyComponents.every(isResolved) || !earlyData.every(isResolved)) {
      const pendingElements = this.createElements(
        routeMatches,
        earlyComponents,
        querySubscriptions,
        false,
      );

      yield pendingElements.every(element => element !== undefined)
        ? pendingElements
        : undefined;

      fetchedComponents = await Promise.all(Components);
      await Promise.all(fetches);
    } else {
      fetchedComponents = earlyComponents;
    }

    yield this.createElements(
      routeMatches,
      fetchedComponents,
      querySubscriptions,
      true,
    );
  }

  getRouteVariables(routeMatches) {
    let variables = null;

    return routeMatches.map(routeMatch => {
      const { route } = routeMatch;

      // We need to always run this to make sure we don't miss route params.
      variables = { ...variables, ...routeMatch.routeParams };
      if (route.prepareVariables) {
        variables = route.prepareVariables(variables, routeMatch);
      }

      return variables;
    });
  }

  updateQuerySubscriptions(queries, routeVariables, cacheConfigs) {
    const {
      createOperationSelector,
      getOperation,
      getRequest,
    } = this.environment.unstable_internal;

    // FIXME: Use getRequest directly when only supporting relay >=1.5.0.
    const getOperationOrRequest = getOperation || getRequest;

    const querySubscriptions = queries.map((query, i) => {
      if (!query) {
        return null;
      }

      const variables = routeVariables[i];

      if (
        this.lastQueries[i] === query &&
        isEqual(this.lastRouteVariables[i], variables)
      ) {
        // Match the logic in <QueryRenderer> for not refetching.
        const lastQuerySubscription = this.lastQuerySubscriptions[i];
        this.lastQuerySubscriptions[i] = null;
        return lastQuerySubscription;
      }

      return new QuerySubscription(
        this.environment,
        createOperationSelector(getOperationOrRequest(query), variables),
        cacheConfigs[i],
      );
    });

    this.lastQuerySubscriptions.forEach(querySubscription => {
      if (querySubscription) {
        querySubscription.dispose();
      }
    });

    this.lastQueries = queries;
    this.lastRouteVariables = routeVariables;
    this.lastQuerySubscriptions = querySubscriptions;

    return querySubscriptions;
  }

  createElements(routeMatches, Components, querySubscriptions, fetched) {
    return routeMatches.map((match, i) => {
      const { route } = match;

      const Component = Components[i];
      const querySubscription = querySubscriptions[i];

      const isComponentResolved = isResolved(Component);

      // Handle non-Relay routes.
      if (!querySubscription) {
        if (route.render) {
          return route.render({
            match,
            Component: isComponentResolved ? Component : null,
            props: match,
          });
        }

        if (!isComponentResolved) {
          return undefined;
        }

        return Component ? <Component {...match} /> : null;
      }

      const resolvedComponent = isComponentResolved ? Component : null;
      const hasComponent = Component != null;

      const element = renderElement({
        match,
        Component: resolvedComponent,
        isComponentResolved,
        hasComponent,
        readyState: querySubscription.readyState,
        resolving: true,
      });

      if (element === undefined) {
        return element;
      }

      return (
        <ReadyStateRenderer
          match={match}
          Component={resolvedComponent}
          isComponentResolved={isComponentResolved}
          hasComponent={hasComponent}
          element={element}
          querySubscription={querySubscription}
          fetched={fetched}
        />
      );
    });
  }
}
<|endoftext|>


<commit_before>/*eslint-disable*/
/* global players, baseW, baseH, Phaser, setScreenFixed, colorHex, bmd:true,
  w2:true, h2:true, powerText:true, localStorage, PowerUp, nextBallHigh:true,
  scale, gameover:true, ButtonList, getAlbumMusic, Vertical, Horizontal, Rotator
*/
/*eslint-enable*/
var Adventure = function (game, testing, items, index) {
  this.sp = true
  this.game = game
  this.spawnPowers = true
  this.countPoints = true
  this.map = null
  this.layer = null
  this.powerText = null
  this.name = 'adventure'
  this.items = items
  this.index = index
  this.margin = 400

  this.image = null
  this.albumText = null
  this.albumDeleted = false
  this.albumBg = null

  this.scale = 1
  this.defaults = {
    mapW: 60,
    mapH: 34,
    length: 60 * 34
  }
  this.mapW = 60
  this.mapH = 34
  this.tileSize = 32

  this.file = null
  this.title = 'adventure'

  this.testing = testing

  this.values = {
    start: 35,
    rotator: 34,
    horizontal: 33,
    vertical: 32,
    wall: 1,
    empty: 0
  }
}

Adventure.prototype = {
  create: function () {
    // varialbes that need to be reset on startup
    this.score = 0
    this.pointPositions = []
    this.player = players[0]
    this.obstacles = []

    this.albumDeleted = false

    w2 = this.game.width / 2
    h2 = this.game.height / 2

    players[0].x = w2
    players[0].y = h2

    this.powerText = this.game.add.text(0, 0, '1', {
      font: '20px dosis',
      fill: colorHex,
      align: 'center'
    })
    this.powerText.anchor.setTo(0.5, 0.5)

    this.score = 0

    var levelArray = this.game.cache.getText('level').split('')

    this.scale = Math.sqrt(levelArray.length / this.defaults.length)
    this.mapW = this.defaults.mapW * this.scale
    this.mapH = this.defaults.mapH * this.scale

    this.map = this.game.add.tilemap()
    this.map.addTilesetImage('block')
    this.layer = this.map.create('obstacles', this.mapW, this.mapH, this.tileSize, this.tileSize)
    this.layer.resizeWorld()

    for (var x = 0; x < this.mapW; x++) {
      for (var y = 0; y < this.mapH; y++) {
        var worldX = x * this.tileSize + this.tileSize / 2
        var worldY = y * this.tileSize + this.tileSize / 2
        var val = parseInt(levelArray[x * this.mapH + y], 36)

        if (val === this.values.wall) this.map.putTile(0, x, y)
        else if (val === this.values.start) {
          players[0].x = worldX
          players[0].y = worldY + 5
        } else if (val === this.values.vertical) {
          var vert = new Vertical(this.game, worldX, worldY)
          vert.create()
          this.obstacles.push(vert)
        } else if (val === this.values.horizontal) {
          var hor = new Horizontal(this.game, worldX, worldY)
          hor.create()
          this.obstacles.push(hor)
        } else if (val === this.values.rotator) {
          var rot = new Rotator(this.game, worldX, worldY)
          rot.create()
          this.obstacles.push(rot)
        } else if (val > 1) {
          this.pointPositions[val - 2] = {}
          var point = this.pointPositions[val - 2]
          point.x = x * this.tileSize + this.tileSize / 2
          point.y = y * this.tileSize + this.tileSize / 2
        }
      }
    }

    this.map.setCollisionByIndex(0)

    this.point = new PowerUp(this.game, 'point', this, 0, 0)
    this.createPower()

    this.finishButtons = new ButtonList(this, this.game)
    this.finishButtons.add('restart_button', 'restart', this.backPressed)
    this.finishButtons.add('steam_button', 'workshop page', this.showWorkshop)
    this.finishButtons.create()
    this.finishButtons.hide()

    var albumElements = getAlbumMusic(this.index)
    if (!this.testing) this.createAlbumElements(albumElements.image, albumElements.author, albumElements.music, albumElements.site)
  },

  setScreen: function () {
    var game = this.game
    var w = baseW
    var h = baseH
    game.width = w
    game.height = h
    game.canvas.width = w
    game.canvas.height = h
    game.renderer.resize(w, h)
    game.scale.width = w
    game.scale.height = h
    game.camera.setSize(w, h)
    game.scale.refresh()
  },

  update: function () {
    if (players[0].ready && !this.albumDeleted && !this.testing) {
      this.deleteAlbumElements()
    }
    if (this.game.physics.arcade.collide(players[0].sprite, this.layer)) {
      players[0].kill()
    }
    var obs = this.obstacles
    for (var i = 0; i < obs.length; i++) obs[i].update()
  },

  setCamera: function () {
    this.game.world.setBounds(0, 4, this.mapW * this.tileSize, this.mapH * this.tileSize - 8)
    this.game.camera.follow(players[0].sprite)
    var m = this.margin
    var w = 2 * w2
    var h = 2 * h2
    this.game.camera.deadzone = new Phaser.Rectangle(m, m, w - 2 * m, h - 2 * m)
  },

  erasesTrail: function () {
    return true
  },

  getScore: function () {
    return this.score
  },

  setScore: function (score) {
    this.score = score
  },

  collect: function (player, power) {
    this.score++

    if (this.score >= this.pointPositions.length) {
      this.nextLevel()
    } else {
      this.createPower()
    }

    if (this.score >= this.pointPositions.length - 2) {
      nextBallHigh = 1
    }

    this.player.size += this.player.growth

    var ballsScore = parseInt(localStorage.getItem('ballsScore'), 10)
    if (isNaN(ballsScore)) {
      ballsScore = 0
    }
    localStorage.setItem('ballsScore', ballsScore + 1)
  },

  createPower: function () {
    if (this.pointPositions[this.score]) {
      var pointName
      if (this.score >= this.pointPositions.length - 1) pointName = 'pointSuper'
      else pointName = 'point'
      var powerup = new PowerUp(this.game, pointName, this, this.pointPositions[this.score].x, this.pointPositions[this.score].y)
      powerup.create()

      var number
      if (this.testing) number = this.score + 1
      else number = this.pointPositions.length - this.score - 1

      if (number > 0 || this.testing) {
        this.powerText.setText(number)
        this.powerText.x = powerup.sprite.x
        this.powerText.y = powerup.sprite.y + 2 * scale
      } else {
        this.powerText.visible = false
      }
    }
  },

  getPointText: function () {
    if (this.testing) return this.score + 1
    else {
      var number = this.pointPositions.length - this.score - 1
      if (number > 0) return number
      else return ''
    }
  },

  nextLevel: function () {
    if (this.testing) this.game.state.start('Editor', true, false, true, this.scale)
    else {
      var manager = this.game.state.states['GameMananger']
      manager.shareText.setText('level completed')
      manager.shareText.visible = true
      manager.endGame()
      manager.twitterButton.enable()
      if (!this.file) {
        var unlocks = localStorage.getItem('unlocks')
        if (unlocks === null) unlocks = 0
        else unlocks = parseInt(unlocks, 10)
        if (unlocks < this.index + 1) localStorage.setItem('unlocks', this.index + 1)
        if (localStorage.getItem('unlocks') > this.index) manager.nextButton.enable()
      }
    }
  },

  playNextLevel: function () {
    this.index++
    this.game.state.start('PreloadGame', true, false, this, 'assets/levels/' + this.items[this.index])
  },

  createAlbumElements: function (image, name, author, site) {
    this.albumBg = this.game.add.sprite(0, 0, 'overlay')
    this.albumBg.anchor.setTo(0, 0.5)
    this.albumBg.fixedToCamera = true
    this.albumBg.cameraOffset.setTo(80, h2 * 4)
    this.albumBg.width = w2 * 1.5
    this.albumBg.height = 2 * h2
    this.albumBg.alpha = 0.4

    var text = name + '\n' + author + '\n' + site
    this.image = this.game.add.sprite(0, 0, image) // [hard-coded] probably we need to change the coordinates
    this.image.anchor.setTo(0, 0.5)
    this.image.fixedToCamera = true
    this.image.cameraOffset.setTo(100, h2 * 2.5)

    this.albumText = this.game.add.text(0, 0, text, {
      font: '60px dosis',
      fill: '#ffffff'})
    this.albumText.scale.set(scale)
    this.albumText.anchor.setTo(0, 0.5)
    this.albumText.fixedToCamera = true
    this.albumText.cameraOffset.setTo(130 + this.image.width, h2 * 2.5)

    this.game.add.tween(this.image.cameraOffset).to({ y: h2 * 1.75 }, 1000, Phaser.Easing.Sinusoidal.In, true)
    this.game.add.tween(this.albumText.cameraOffset).to({ y: h2 * 1.75 }, 1000, Phaser.Easing.Sinusoidal.In, true)
    this.game.add.tween(this.albumBg.cameraOffset).to({ y: h2 * 2.48 }, 1100, Phaser.Easing.Sinusoidal.In, true)
  },

  deleteAlbumElements: function () {
    this.albumDeleted = true
    this.game.time.events.add(Phaser.Timer.SECOND * 1, function () {
      this.game.add.tween(this.image.cameraOffset).to({ y: h2 * 2.5 }, 1000, Phaser.Easing.Sinusoidal.In, true)
      this.game.add.tween(this.albumBg.cameraOffset).to({ y: h2 * 4 }, 1000, Phaser.Easing.Sinusoidal.In, true)
      var aux = this.game.add.tween(this.albumText.cameraOffset).to({ y: h2 * 2.5 }, 1000, Phaser.Easing.Sinusoidal.In, true)
      aux.onComplete.add(function () {
        this.image.kill
        this.albumText.kill
      }, this)
    }, this)
  }

}
<commit_msg>fixed crash when level has no music<commit_after>/*eslint-disable*/
/* global players, baseW, baseH, Phaser, setScreenFixed, colorHex, bmd:true,
  w2:true, h2:true, powerText:true, localStorage, PowerUp, nextBallHigh:true,
  scale, gameover:true, ButtonList, getAlbumMusic, Vertical, Horizontal, Rotator
*/
/*eslint-enable*/
var Adventure = function (game, testing, items, index) {
  this.sp = true
  this.game = game
  this.spawnPowers = true
  this.countPoints = true
  this.map = null
  this.layer = null
  this.powerText = null
  this.name = 'adventure'
  this.items = items
  this.index = index
  this.margin = 400

  this.image = null
  this.albumText = null
  this.albumDeleted = false
  this.albumBg = null

  this.scale = 1
  this.defaults = {
    mapW: 60,
    mapH: 34,
    length: 60 * 34
  }
  this.mapW = 60
  this.mapH = 34
  this.tileSize = 32

  this.file = null
  this.title = 'adventure'

  this.testing = testing

  this.values = {
    start: 35,
    rotator: 34,
    horizontal: 33,
    vertical: 32,
    wall: 1,
    empty: 0
  }
}

Adventure.prototype = {
  create: function () {
    // varialbes that need to be reset on startup
    this.score = 0
    this.pointPositions = []
    this.player = players[0]
    this.obstacles = []

    this.albumDeleted = false

    w2 = this.game.width / 2
    h2 = this.game.height / 2

    players[0].x = w2
    players[0].y = h2

    this.powerText = this.game.add.text(0, 0, '1', {
      font: '20px dosis',
      fill: colorHex,
      align: 'center'
    })
    this.powerText.anchor.setTo(0.5, 0.5)

    this.score = 0

    var levelArray = this.game.cache.getText('level').split('')

    this.scale = Math.sqrt(levelArray.length / this.defaults.length)
    this.mapW = this.defaults.mapW * this.scale
    this.mapH = this.defaults.mapH * this.scale

    this.map = this.game.add.tilemap()
    this.map.addTilesetImage('block')
    this.layer = this.map.create('obstacles', this.mapW, this.mapH, this.tileSize, this.tileSize)
    this.layer.resizeWorld()

    for (var x = 0; x < this.mapW; x++) {
      for (var y = 0; y < this.mapH; y++) {
        var worldX = x * this.tileSize + this.tileSize / 2
        var worldY = y * this.tileSize + this.tileSize / 2
        var val = parseInt(levelArray[x * this.mapH + y], 36)

        if (val === this.values.wall) this.map.putTile(0, x, y)
        else if (val === this.values.start) {
          players[0].x = worldX
          players[0].y = worldY + 5
        } else if (val === this.values.vertical) {
          var vert = new Vertical(this.game, worldX, worldY)
          vert.create()
          this.obstacles.push(vert)
        } else if (val === this.values.horizontal) {
          var hor = new Horizontal(this.game, worldX, worldY)
          hor.create()
          this.obstacles.push(hor)
        } else if (val === this.values.rotator) {
          var rot = new Rotator(this.game, worldX, worldY)
          rot.create()
          this.obstacles.push(rot)
        } else if (val > 1) {
          this.pointPositions[val - 2] = {}
          var point = this.pointPositions[val - 2]
          point.x = x * this.tileSize + this.tileSize / 2
          point.y = y * this.tileSize + this.tileSize / 2
        }
      }
    }

    this.map.setCollisionByIndex(0)

    this.point = new PowerUp(this.game, 'point', this, 0, 0)
    this.createPower()

    this.finishButtons = new ButtonList(this, this.game)
    this.finishButtons.add('restart_button', 'restart', this.backPressed)
    this.finishButtons.add('steam_button', 'workshop page', this.showWorkshop)
    this.finishButtons.create()
    this.finishButtons.hide()

    var albumElements = getAlbumMusic(this.index)
    if (!this.testing && albumElements) this.createAlbumElements(albumElements.image, albumElements.author, albumElements.music, albumElements.site)
  },

  setScreen: function () {
    var game = this.game
    var w = baseW
    var h = baseH
    game.width = w
    game.height = h
    game.canvas.width = w
    game.canvas.height = h
    game.renderer.resize(w, h)
    game.scale.width = w
    game.scale.height = h
    game.camera.setSize(w, h)
    game.scale.refresh()
  },

  update: function () {
    if (players[0].ready && !this.albumDeleted && !this.testing) {
      this.deleteAlbumElements()
    }
    if (this.game.physics.arcade.collide(players[0].sprite, this.layer)) {
      players[0].kill()
    }
    var obs = this.obstacles
    for (var i = 0; i < obs.length; i++) obs[i].update()
  },

  setCamera: function () {
    this.game.world.setBounds(0, 4, this.mapW * this.tileSize, this.mapH * this.tileSize - 8)
    this.game.camera.follow(players[0].sprite)
    var m = this.margin
    var w = 2 * w2
    var h = 2 * h2
    this.game.camera.deadzone = new Phaser.Rectangle(m, m, w - 2 * m, h - 2 * m)
  },

  erasesTrail: function () {
    return true
  },

  getScore: function () {
    return this.score
  },

  setScore: function (score) {
    this.score = score
  },

  collect: function (player, power) {
    this.score++

    if (this.score >= this.pointPositions.length) {
      this.nextLevel()
    } else {
      this.createPower()
    }

    if (this.score >= this.pointPositions.length - 2) {
      nextBallHigh = 1
    }

    this.player.size += this.player.growth

    var ballsScore = parseInt(localStorage.getItem('ballsScore'), 10)
    if (isNaN(ballsScore)) {
      ballsScore = 0
    }
    localStorage.setItem('ballsScore', ballsScore + 1)
  },

  createPower: function () {
    if (this.pointPositions[this.score]) {
      var pointName
      if (this.score >= this.pointPositions.length - 1) pointName = 'pointSuper'
      else pointName = 'point'
      var powerup = new PowerUp(this.game, pointName, this, this.pointPositions[this.score].x, this.pointPositions[this.score].y)
      powerup.create()

      var number
      if (this.testing) number = this.score + 1
      else number = this.pointPositions.length - this.score - 1

      if (number > 0 || this.testing) {
        this.powerText.setText(number)
        this.powerText.x = powerup.sprite.x
        this.powerText.y = powerup.sprite.y + 2 * scale
      } else {
        this.powerText.visible = false
      }
    }
  },

  getPointText: function () {
    if (this.testing) return this.score + 1
    else {
      var number = this.pointPositions.length - this.score - 1
      if (number > 0) return number
      else return ''
    }
  },

  nextLevel: function () {
    if (this.testing) this.game.state.start('Editor', true, false, true, this.scale)
    else {
      var manager = this.game.state.states['GameMananger']
      manager.shareText.setText('level completed')
      manager.shareText.visible = true
      manager.endGame()
      manager.twitterButton.enable()
      if (!this.file) {
        var unlocks = localStorage.getItem('unlocks')
        if (unlocks === null) unlocks = 0
        else unlocks = parseInt(unlocks, 10)
        if (unlocks < this.index + 1) localStorage.setItem('unlocks', this.index + 1)
        if (localStorage.getItem('unlocks') > this.index) manager.nextButton.enable()
      }
    }
  },

  playNextLevel: function () {
    this.index++
    this.game.state.start('PreloadGame', true, false, this, 'assets/levels/' + this.items[this.index])
  },

  createAlbumElements: function (image, name, author, site) {
    this.albumBg = this.game.add.sprite(0, 0, 'overlay')
    this.albumBg.anchor.setTo(0, 0.5)
    this.albumBg.fixedToCamera = true
    this.albumBg.cameraOffset.setTo(80, h2 * 4)
    this.albumBg.width = w2 * 1.5
    this.albumBg.height = 2 * h2
    this.albumBg.alpha = 0.4

    var text = name + '\n' + author + '\n' + site
    this.image = this.game.add.sprite(0, 0, image) // [hard-coded] probably we need to change the coordinates
    this.image.anchor.setTo(0, 0.5)
    this.image.fixedToCamera = true
    this.image.cameraOffset.setTo(100, h2 * 2.5)

    this.albumText = this.game.add.text(0, 0, text, {
      font: '60px dosis',
      fill: '#ffffff'})
    this.albumText.scale.set(scale)
    this.albumText.anchor.setTo(0, 0.5)
    this.albumText.fixedToCamera = true
    this.albumText.cameraOffset.setTo(130 + this.image.width, h2 * 2.5)

    this.game.add.tween(this.image.cameraOffset).to({ y: h2 * 1.75 }, 1000, Phaser.Easing.Sinusoidal.In, true)
    this.game.add.tween(this.albumText.cameraOffset).to({ y: h2 * 1.75 }, 1000, Phaser.Easing.Sinusoidal.In, true)
    this.game.add.tween(this.albumBg.cameraOffset).to({ y: h2 * 2.48 }, 1100, Phaser.Easing.Sinusoidal.In, true)
  },

  deleteAlbumElements: function () {
    this.albumDeleted = true
    this.game.time.events.add(Phaser.Timer.SECOND * 1, function () {
      this.game.add.tween(this.image.cameraOffset).to({ y: h2 * 2.5 }, 1000, Phaser.Easing.Sinusoidal.In, true)
      this.game.add.tween(this.albumBg.cameraOffset).to({ y: h2 * 4 }, 1000, Phaser.Easing.Sinusoidal.In, true)
      var aux = this.game.add.tween(this.albumText.cameraOffset).to({ y: h2 * 2.5 }, 1000, Phaser.Easing.Sinusoidal.In, true)
      aux.onComplete.add(function () {
        this.image.kill
        this.albumText.kill
      }, this)
    }, this)
  }

}
<|endoftext|>


<commit_before>/**
 *
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you 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.
 *
 */

define(["jquery", "/dev/configuration/config.js", "/dev/lib/misc/parseuri.js"],function($, sakai_conf) {
    return {
        /**
         * Set the permissions for an array of uploaded files or links
         * @param {String} permissionValue either 'public', 'everyone', 'group' or 'private'
         * @param {Array} filesArray Array of files containing the 'hashpath' property per file. This hashpath is the resourceID of the file
         * @param {Function} callback Function to call when the permissions have been saved or failed to save.
         *                   The callback function is provided with a Boolean. True = permissions successfully set, False = permissions not set (error)
         */
        setFilePermissions : function(permissionValue, filesArray, callback, groupID){
            // Check which value was selected and fill in the data object accordingly
            var data = [];
            var file;
            for (file in filesArray) {
                if (filesArray.hasOwnProperty(file)) {
                    var contentPath = "/p/" + filesArray[file].hashpath;
                    var item;
                    switch (permissionValue) {
                    // Logged in only
                    case "everyone":
                        item = {
                            "url": contentPath + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer": "everyone",
                                ":viewer@Delete": "anonymous"
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": "everyone",
                                "privilege@jcr:read": "granted"
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": "anonymous",
                                "privilege@jcr:read": "denied"
                            }
                        };
                        data[data.length] = item;
                        break;
                    // Public
                    case "public":
                        item = {
                            "url": contentPath + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer": ["everyone", "anonymous"]
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": ["everyone", "anonymous"],
                                "privilege@jcr:read": "granted"
                            }
                        };
                        data[data.length] = item;
                        break;
                    // Managers and viewers only
                    case "private":
                        item = {
                            "url": contentPath + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer@Delete": ["anonymous", "everyone"]
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": ["everyone", "anonymous"],
                                "privilege@jcr:read": "denied"
                            }
                        };
                        data[data.length] = item;
                        break;
                    case "group":
                        item = {
                            "url": contentPath + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer": groupID
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": ["everyone", "anonymous"],
                                "privilege@jcr:read": "denied"
                            }
                        };
                        data[data.length] = item;
                        break;
                    }
                }
            }
            $.ajax({
                url: sakai_conf.URL.BATCH,
                traditional: true,
                type: "POST",
                cache: false,
                data: {
                    requests: $.toJSON(data)
                },
                success: function(data){
                    callback(true);
                },
                error: function(xhr, textStatus, thrownError){
                    callback(false);
                }
            });
        },

        /**
         * Returns true if the user is a viewer for the given content item,
         * false otherwise.
         *
         * @param content  content profile data as defined in loadContentProfile()
         *   of /dev/javascript/content_profile.js
         * @param userid   the id of the user to search for
         */
        isUserAViewer: function (content, userid) {
            if (content && userid && content.hasOwnProperty("members") &&
                content.members.hasOwnProperty("viewers")) {
                for (var i in content.members.viewers) {
                    if (content.members.viewers.hasOwnProperty(i)) {
                        if (userid === content.members.viewers[i].userid) {
                            return true;
                        }
                    }
                }
            }
            return false;
        },

        /**
         * Returns true if the user is a manager for the given content item,
         * false otherwise.
         *
         * @param content  content profile data as defined in loadContentProfile()
         *   of /dev/javascript/content_profile.js
         * @param userid  the id of the user to search for
         */
        isUserAManager: function (content, userid) {
            if (content && userid && content.hasOwnProperty("members") &&
                content.members.hasOwnProperty("managers")) {
                for (var i in content.members.managers) {
                    if (content.members.managers.hasOwnProperty(i)) {
                        if (userid === content.members.managers[i].userid) {
                            return true;
                        }
                    }
                }
            }
            return false;
        },

        /**
         * Returns a preview URL for known services, empty string otherwise
         *
         * @param url The url of the content in an external service that you'd like a preview of
         */
        getPreviewUrl : function(url) {
            var uri = parseUri(url);
            var result = "";
            if (/vimeo\.com$/.test(uri.host)) {
                if (uri.path !== "") {
                  result = "http://player.vimeo.com/video" + uri.path;
                }
            } else if (/picasaweb\.google\.com$/.test(uri.host)) {
                var userId = uri.path.split('/')[1];
                var albumName = uri.path.split('/')[2];
                var photoId = uri.anchor;
                result = "https://picasaweb.google.com/data/feed/base/user/" + userId + "/album/" + albumName + "/photoid/" + photoId + "?alt=json";
            } else if (/youtube\.com$/.test(uri.host)) {
                if (uri.path !== ""){
                    result = url;
                }
            } else if (/amazon\.com$/.test(uri.host)) {
                var asin = uri.path.split("/");
                asin = bookId[bookId.indexOf('dp')+1];
                result = "http://kindleweb.s3.amazonaws.com/app/1.0.11.053.093655/KindleReaderApp.html?asin=" + asin + "&containerID=kindleReaderDiv59&tophostname=localhost&iframeName=kindleReaderIFrame1300121366106&dp=0";
            }
            return result;
        }
    };
});
<commit_msg>SAKIII-2648 get picasa preview url from nakamura proxy<commit_after>/**
 *
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you 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.
 *
 */

define(["jquery", "/dev/configuration/config.js", "/dev/lib/misc/parseuri.js"],function($, sakai_conf) {
    return {
        /**
         * Set the permissions for an array of uploaded files or links
         * @param {String} permissionValue either 'public', 'everyone', 'group' or 'private'
         * @param {Array} filesArray Array of files containing the 'hashpath' property per file. This hashpath is the resourceID of the file
         * @param {Function} callback Function to call when the permissions have been saved or failed to save.
         *                   The callback function is provided with a Boolean. True = permissions successfully set, False = permissions not set (error)
         */
        setFilePermissions : function(permissionValue, filesArray, callback, groupID){
            // Check which value was selected and fill in the data object accordingly
            var data = [];
            var file;
            for (file in filesArray) {
                if (filesArray.hasOwnProperty(file)) {
                    var contentPath = "/p/" + filesArray[file].hashpath;
                    var item;
                    switch (permissionValue) {
                    // Logged in only
                    case "everyone":
                        item = {
                            "url": contentPath + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer": "everyone",
                                ":viewer@Delete": "anonymous"
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": "everyone",
                                "privilege@jcr:read": "granted"
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": "anonymous",
                                "privilege@jcr:read": "denied"
                            }
                        };
                        data[data.length] = item;
                        break;
                    // Public
                    case "public":
                        item = {
                            "url": contentPath + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer": ["everyone", "anonymous"]
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": ["everyone", "anonymous"],
                                "privilege@jcr:read": "granted"
                            }
                        };
                        data[data.length] = item;
                        break;
                    // Managers and viewers only
                    case "private":
                        item = {
                            "url": contentPath + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer@Delete": ["anonymous", "everyone"]
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": ["everyone", "anonymous"],
                                "privilege@jcr:read": "denied"
                            }
                        };
                        data[data.length] = item;
                        break;
                    case "group":
                        item = {
                            "url": contentPath + ".members.html",
                            "method": "POST",
                            "parameters": {
                                ":viewer": groupID
                            }
                        };
                        data[data.length] = item;
                        item = {
                            "url": contentPath + ".modifyAce.html",
                            "method": "POST",
                            "parameters": {
                                "principalId": ["everyone", "anonymous"],
                                "privilege@jcr:read": "denied"
                            }
                        };
                        data[data.length] = item;
                        break;
                    }
                }
            }
            $.ajax({
                url: sakai_conf.URL.BATCH,
                traditional: true,
                type: "POST",
                cache: false,
                data: {
                    requests: $.toJSON(data)
                },
                success: function(data){
                    callback(true);
                },
                error: function(xhr, textStatus, thrownError){
                    callback(false);
                }
            });
        },

        /**
         * Returns true if the user is a viewer for the given content item,
         * false otherwise.
         *
         * @param content  content profile data as defined in loadContentProfile()
         *   of /dev/javascript/content_profile.js
         * @param userid   the id of the user to search for
         */
        isUserAViewer: function (content, userid) {
            if (content && userid && content.hasOwnProperty("members") &&
                content.members.hasOwnProperty("viewers")) {
                for (var i in content.members.viewers) {
                    if (content.members.viewers.hasOwnProperty(i)) {
                        if (userid === content.members.viewers[i].userid) {
                            return true;
                        }
                    }
                }
            }
            return false;
        },

        /**
         * Returns true if the user is a manager for the given content item,
         * false otherwise.
         *
         * @param content  content profile data as defined in loadContentProfile()
         *   of /dev/javascript/content_profile.js
         * @param userid  the id of the user to search for
         */
        isUserAManager: function (content, userid) {
            if (content && userid && content.hasOwnProperty("members") &&
                content.members.hasOwnProperty("managers")) {
                for (var i in content.members.managers) {
                    if (content.members.managers.hasOwnProperty(i)) {
                        if (userid === content.members.managers[i].userid) {
                            return true;
                        }
                    }
                }
            }
            return false;
        },

        /**
         * Returns a preview URL for known services, empty string otherwise
         *
         * @param url The url of the content in an external service that you'd like a preview of
         */
        getPreviewUrl : function(url) {
            var uri = parseUri(url);
            var result = "";
            if (/vimeo\.com$/.test(uri.host)) {
                if (uri.path !== "") {
                  result = "http://player.vimeo.com/video" + uri.path;
                }
            } else if (/picasaweb\.google\.com$/.test(uri.host)) {
                var userId = uri.path.split('/')[1];
                var albumName = uri.path.split('/')[2];
                var photoId = uri.anchor;
                $.ajax({
                    url: "/var/proxy/google/picasaGetPhoto.json",
                    type: "GET",
                    async: false,
                    cache: false,
                    data: {
                        "userId" : userId,
                        "albumName" : albumName,
                        "photoId" : photoId
                    },
                    success: function(data){
                        result = data.feed.icon["$t"];
                    }
                });
            } else if (/youtube\.com$/.test(uri.host)) {
                if (uri.path !== ""){
                    result = url;
                }
            } else if (/amazon\.com$/.test(uri.host)) {
                var asin = uri.path.split("/");
                asin = bookId[bookId.indexOf('dp')+1];
                result = "http://kindleweb.s3.amazonaws.com/app/1.0.11.053.093655/KindleReaderApp.html?asin=" + asin + "&containerID=kindleReaderDiv59&tophostname=localhost&iframeName=kindleReaderIFrame1300121366106&dp=0";
            }
            return result;
        }
    };
});
<|endoftext|>