<commit_before>(function (angular) {
    'use strict';

    angular.module('coRangeSlider', ['ngGesture', 'coAnimate'])
        .directive('range', [
            '$animation',

            function ($animation) {
                return {
                    restrict: 'E',
                    replace: true,

                    scope: {
                        options: '=?',
                        model: '=?'
                    },

                    template:   '
' +
                                    '

' +
                                    '

' +
                                    '

' +
                                    '<input ng-model="value" type="number" data-type="range" ng-class="{hide: !options.visible}" max="{{options.max}}" min="{{options.min}}" step="{{options.step}}">' +
                                '
',

                    link: function($scope, $element) {
                        var input = $element.find('input'),
                            handle = $element.find('.handle'),
                            progress = $element.find('.progress'),
                            options = $scope.options;

                        if (options.horizontal) {
                            var handleProperty   = 'left';
                            var progressProperty = 'width';
                        } else {
                            var handleProperty   = 'bottom';
                            var progressProperty = 'height';
                        }

                        // ---------------------
                        // rendering
                        // ---------------------
                        function calculateValue(event) {
                            if (options.horizontal) {
                                var pos = event.center.pageX - $element.offset().left;
                                var percent = pos / $element.width();
                            } else {
                                var pos = event.center.pageY - $element.offset().top;
                                var percent = 1 - (pos / $element.height());
                            }

                            // TODO: handle min, max, steps etc. here
                            var value = Math.round(percent * 100);
                            return Math.min(100, Math.max(0, value));
                        }

                        function slide() {
                            progress.css(progressProperty, $scope.value + '%');
                            handle.css(handleProperty, $scope.value + '%');
                        }

                        function handleEvent(event) {
                            $scope.value = calculateValue(event);
                            $scope.model = $scope.value;
                            slide();
                        }

                        // ---------------------
                        // events
                        // ---------------------
                        $scope.clicked = function(event) {
                            if (options.disabled || event.target === handle[0]) {
                                event.stopPropagation();
                                return event.preventDefault();
                            } else {
                                handleEvent(event);
                            }
                        }

                        $scope.dragStart = function(event) {
                            event.stopPropagation();
                            if (options.disabled)
                                return event.preventDefault();
                            else
                                $scope.dragging = true;
                        };

                        $scope.drag = function(event) {
                            if (options.disabled)
                                return;
                            else
                                handleEvent(event);
                        };

                        $scope.dragEnd = function() {
                            $scope.dragging = false;
                        };

                        // ---------------------
                        // initialisation
                        // ---------------------
                        $scope.value = $scope.model || 0;
                        $scope.dragging = false;
                        slide();
                    }
                }
            }
        ]);

}(this.angular));
<commit_msg>Handle min, max, step, precision values in options<commit_after>(function (angular) {
    'use strict';

    angular.module('coRangeSlider', ['ngGesture', 'coAnimate'])
        .directive('range', [
            '$animation',

            function ($animation) {
                return {
                    restrict: 'E',
                    replace: true,

                    scope: {
                        options: '=?',
                        model: '=?'
                    },

                    template:   '
' +
                                    '

' +
                                    '

' +
                                    '

' +
                                    '<input ng-model="value" type="number" data-type="range" ng-class="{hide: !options.visible}" max="{{options.max}}" min="{{options.min}}" step="{{options.step}}">' +
                                '
',

                    link: function($scope, $element) {
                        var input    = $element.find('input'),
                            handle   = $element.find('.handle'),
                            progress = $element.find('.progress'),
                            options  = $scope.options;

                        var min  = options.min  || 0,
                            max  = options.max  || 100,
                            step = options.step || 1,
                            precision = options.precision || step;

                        if (options.horizontal) {
                            var handleProperty   = 'left';
                            var progressProperty = 'width';
                        } else {
                            var handleProperty   = 'bottom';
                            var progressProperty = 'height';
                        }

                        // ---------------------
                        // rendering
                        // ---------------------
                        function calculateValue(event) {
                            if (options.horizontal) {
                                var pos = event.center.pageX - $element.offset().left;
                                var percent = pos / $element.width();
                            } else {
                                var pos = event.center.pageY - $element.offset().top;
                                var percent = 1 - (pos / $element.height());
                            }

                            // expand the value to an number min...max, and clip
                            // it to a multiple of step
                            var stepped = Math.round((percent * max) / step) * step;

                            // round the stepped value to a precision level
                            var rounded = Math.round(stepped, precision);

                            // constraint min..X..max
                            return Math.min(max, Math.max(min, rounded));
                        }

                        function slide() {
                            progress.css(progressProperty, $scope.value + '%');
                            handle.css(handleProperty, $scope.value + '%');
                        }

                        function handleEvent(event) {
                            $scope.value = calculateValue(event);
                            $scope.model = $scope.value;
                            slide();
                        }

                        // ---------------------
                        // events
                        // ---------------------
                        $scope.clicked = function(event) {
                            if (options.disabled || event.target === handle[0]) {
                                event.stopPropagation();
                                return event.preventDefault();
                            } else {
                                handleEvent(event);
                            }
                        }

                        $scope.dragStart = function(event) {
                            event.stopPropagation();
                            event.preventDefault();
                            if (!options.disabled)
                                $scope.dragging = true;
                        };

                        $scope.drag = function(event) {
                            if (options.disabled)
                                return;
                            else
                                handleEvent(event);
                        };

                        $scope.dragEnd = function() {
                            $scope.dragging = false;
                        };

                        // ---------------------
                        // initialisation
                        // ---------------------
                        $scope.value = $scope.model || 0;
                        $scope.dragging = false;
                        slide();
                    }
                }
            }
        ]);

}(this.angular));
<|endoftext|>


<commit_before>// Copyright 2016, University of Colorado Boulder

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // modules
  var assertInstanceOf = require( 'PHET_IO/assertions/assertInstanceOf' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var TButton = require( 'PHET_IO/types/sun/buttons/TButton' );
  var TNode = require( 'PHET_IO/types/scenery/nodes/TNode' );
  var TMenuItem = require( 'PHET_IO/types/joist/TMenuItem' );

  var TPhetMenu = phetioInherit( TNode, 'TPhetMenu', function( phetMenu, phetioID ) {
    TButton.call( this, phetMenu, phetioID );
    assertInstanceOf( phetMenu, phet.joist.PhetMenu );
  }, {}, {
    api: {
      aboutButton: TMenuItem,
      fullScreenButton: TMenuItem,
      phetWebsiteButton: TMenuItem,
      reportAProblemButton: TMenuItem,
      screenshotMenuItem: TMenuItem,
      optionsButton: TMenuItem
    },
    documentation: 'The PhET Menu in the bottom right of the screen'
  } );

  phetioNamespace.register( 'TPhetMenu', TPhetMenu );

  return TPhetMenu;
} );

<commit_msg>Fixed: When running as phet-io, the PhET Menu "Options" button causes a failure #79<commit_after>// Copyright 2016, University of Colorado Boulder

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // modules
  var assertInstanceOf = require( 'PHET_IO/assertions/assertInstanceOf' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var TButton = require( 'PHET_IO/types/sun/buttons/TButton' );
  var TNode = require( 'PHET_IO/types/scenery/nodes/TNode' );
  var TMenuItem = require( 'PHET_IO/types/joist/TMenuItem' );

  var TPhetMenu = phetioInherit( TNode, 'TPhetMenu', function( phetMenu, phetioID ) {
    TButton.call( this, phetMenu, phetioID );
    assertInstanceOf( phetMenu, phet.joist.PhetMenu );
  }, {}, {
    api: {
      aboutButton: TMenuItem,
      fullScreenButton: TMenuItem,
      phetWebsiteButton: TMenuItem,
      reportAProblemButton: TMenuItem,
      screenshotMenuItem: TMenuItem,
      optionsButton: TMenuItem,
      optionsDialog: TNode.extend( {
        closeButton: TButton
      } ) // TODO: We need TDialog class
    },
    documentation: 'The PhET Menu in the bottom right of the screen'
  } );

  phetioNamespace.register( 'TPhetMenu', TPhetMenu );

  return TPhetMenu;
} );

<|endoftext|>


<commit_before>/*
 *  Copyright 2014 TWO SIGMA OPEN SOURCE, LLC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

var BeakerPageObject = require('../../beaker.po.js');
var beakerPO;

describe('Table Display (Groovy API)', function (done) {

    beforeAll(function(done){
        beakerPO = new BeakerPageObject();
        browser.get(beakerPO.baseURL + "beaker/#/open?uri=file:config%2Ftutorials%2Ftable-api.bkr&readOnly=true").then(done);
        beakerPO.waitUntilLoadingCellOutput();
    });

    afterAll(function(done){
        beakerPO.createScreenshot('tableGroovyTutorial');
        done();
    });

    function getArrayTdElements(idCell, indx){
        return beakerPO.getDataTablesTBodyByIdCell(idCell).get(indx).all(by.css('td'));
    }

    describe('Programmatic control of visual formatting', function(){
        it('Built-in formatters', function () {
            var idCell = "codeaWwWKg";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.checkDtContainerByIdCell(idCell);
            beakerPO.checkDataTableHeadByIdCell(idCell, 'm3\ny30\ny1\nm6\ny2\ny10\ny3\ntime\ny5\ny7');
            beakerPO.checkDataTableBodyByIdCell(idCell, 25, '0 8 8.258571 7.920952 7.956190 8.085238 8.206667 :) 1990-01-31 8.119524 8.196190');
        });
        it('Cell renderer', function () {
            var idCell = "codeROe5NG";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.checkDtContainerByIdCell(idCell);

            var arrTd = getArrayTdElements(idCell, 0);
            expect(arrTd.count()).toBe(11);
            beakerPO.checkSubString(arrTd.get(1), '7.8981', 0, 6);
            expect(arrTd.get(1).element(by.css('.dt-bar-data')).isPresent()).toBe(true);
            expect(arrTd.get(1).element(by.css('.dt-cell-text')).isPresent()).toBe(true);
        });
        it('Controlling column display', function () {
            var idCell = "codenPyPvP";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.checkDtContainerByIdCell(idCell);
            beakerPO.checkDataTableHeadByIdCell(idCell, 'm3\ny1\ny5\ntime\ny2');
            var arrTd = getArrayTdElements(idCell, 0);
            expect(arrTd.count()).toBe(6);
            beakerPO.checkSubString(arrTd.get(1), '7.898095', 0, 8);
            beakerPO.checkSubString(arrTd.get(2), '7.92095', 0, 7);
            beakerPO.checkSubString(arrTd.get(3), '8.11952', 0, 7);
            beakerPO.checkSubString(arrTd.get(5), '8.085238', 0, 8);
        });

        describe('Сell highlighters', function() {
            it('Color the entire table like a heatmap based on column value', function () {
                var idCell = "codeWyrMwb";
                beakerPO.scrollToBkCellByIdCell(idCell);
                beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
                beakerPO.checkDtContainerByIdCell(idCell);

                var arrTd = getArrayTdElements(idCell, 0);
                expect(arrTd.count()).toBe(11);
                beakerPO.checkSubString(arrTd.get(1), '7.8981', 0, 6);
                expect(arrTd.get(1).getCssValue('background-color')).toBe('rgba(236, 91, 88, 1)');

                var arrTd20 = getArrayTdElements(idCell, 20);
                expect(arrTd20.count()).toBe(11);
                beakerPO.checkSubString(arrTd20.get(1), '5.3735', 0, 6);
                expect(arrTd20.get(1).getCssValue('background-color')).toBe('rgba(190, 114, 130, 1)');
            });
            it('Use a closure to highlight specific values', function () {
                var idCell = "code7zZ3sT";
                beakerPO.scrollToBkCellByIdCell(idCell);
                beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
                beakerPO.checkDtContainerByIdCell(idCell);

                var arrTd = getArrayTdElements(idCell, 0);
                expect(arrTd.count()).toBe(4);
                beakerPO.checkSubString(arrTd.get(3), '3', 0, 1);
                expect(arrTd.get(3).getCssValue('background-color')).toBe('rgba(255, 0, 0, 1)');

                var arrTd1 = getArrayTdElements(idCell, 1);
                expect(arrTd1.count()).toBe(4);
                beakerPO.checkSubString(arrTd1.get(3), '6', 0, 1);
                expect(arrTd1.get(3).getCssValue('background-color')).toBe('rgba(0, 255, 0, 1)');
            });
            it('Heatmap with custom min/max values and colors', function () {
                var idCell = "codetHTtD2";
                beakerPO.scrollToBkCellByIdCell(idCell);
                beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
                beakerPO.checkDtContainerByIdCell(idCell);

                var arrTd = getArrayTdElements(idCell, 0);
                expect(arrTd.count()).toBe(11);
                beakerPO.checkSubString(arrTd.get(3), '7.9210', 0, 6);
                expect(arrTd.get(3).getCssValue('background-color')).toBe('rgba(105, 190, 120, 1)');
                beakerPO.checkSubString(arrTd.get(4), '7.9562', 0, 6);
                expect(arrTd.get(4).getCssValue('background-color')).toBe('rgba(249, 171, 171, 1)');

                var arrTd20 = getArrayTdElements(idCell, 20);
                expect(arrTd20.count()).toBe(11);
                beakerPO.checkSubString(arrTd20.get(3), '5.5725', 0, 6);
                expect(arrTd20.get(3).getCssValue('background-color')).toBe('rgba(241, 194, 87, 1)');
                beakerPO.checkSubString(arrTd20.get(4), '5.4790', 0, 6);
                expect(arrTd20.get(4).getCssValue('background-color')).toBe('rgba(0, 0, 0, 1)');

            });
            it('UniqueEntriesHighlighter', function () {
                var idCell = "code2KwSKV";
                beakerPO.scrollToBkCellByIdCell(idCell);
                beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
                beakerPO.checkDtContainerByIdCell(idCell);

                var rgb0 = 'rgba(245, 188, 188, 1)'
                var arrTd0 = getArrayTdElements(idCell, 0);
                expect(arrTd0.count()).toBe(4);
                beakerPO.checkSubString(arrTd0.get(1), '1', 0, 1);
                expect(arrTd0.get(1).getCssValue('background-color')).toBe(rgb0);
                beakerPO.checkSubString(arrTd0.get(2), '2', 0, 1);
                expect(arrTd0.get(2).getCssValue('background-color')).toBe(rgb0);

                var rgb1 = 'rgba(188, 245, 188, 1)';
                var arrTd1 = getArrayTdElements(idCell, 1);
                expect(arrTd1.count()).toBe(4);
                beakerPO.checkSubString(arrTd1.get(1), '3', 0, 1);
                expect(arrTd1.get(1).getCssValue('background-color')).toBe(rgb1);
                beakerPO.checkSubString(arrTd1.get(2), '4', 0, 1);
                expect(arrTd1.get(2).getCssValue('background-color')).toBe(rgb1);
            });
       });

        it('Adding custom actions', function () {
            var idCell = "codex9hziv";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.scrollHeaderElement();
            beakerPO.checkDtContainerByIdCell(idCell);

            var arrTd0 = getArrayTdElements(idCell, 0);
            expect(arrTd0.count()).toBe(4);
            beakerPO.checkSubString(arrTd0.get(1), '1', 0, 1);
            browser.actions().doubleClick(arrTd0.get(1)).perform();
            beakerPO.checkSubString(arrTd0.get(1), '6', 0, 1);

            browser.actions().mouseMove(arrTd0.get(1)).perform();
            browser.actions().click(protractor.Button.RIGHT).perform();
            var contextMenu =  element(by.css('ul.context-menu-list[style*="z-index: 1"]'));
            var negate = contextMenu.element(by.cssContainingText('span', 'negate'));
            browser.actions().mouseMove(negate).perform();
            negate.click();
            beakerPO.checkSubString(arrTd0.get(1), '-6', 0, 2);

            browser.actions().mouseMove(arrTd0.get(1)).perform();
            browser.actions().click(protractor.Button.RIGHT).perform();
            var run_misc_formatting = contextMenu.element(by.cssContainingText('span', 'run misc_formatting'));
            browser.actions().mouseMove(run_misc_formatting).perform();
            run_misc_formatting.click().then(function(){
                beakerPO.waitUntilLoadingFinished();
            });
        });

    });
});<commit_msg>add test<commit_after>/*
 *  Copyright 2014 TWO SIGMA OPEN SOURCE, LLC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

var BeakerPageObject = require('../../beaker.po.js');
var beakerPO;

describe('Table Display (Groovy API)', function (done) {

    beforeAll(function(done){
        beakerPO = new BeakerPageObject();
        browser.get(beakerPO.baseURL + "beaker/#/open?uri=file:config%2Ftutorials%2Ftable-api.bkr&readOnly=true").then(done);
        beakerPO.waitUntilLoadingCellOutput();
    });

    afterAll(function(done){
        beakerPO.createScreenshot('tableGroovyTutorial');
        done();
    });

    function getArrayTdElements(idCell, indx){
        return beakerPO.getDataTablesTBodyByIdCell(idCell).get(indx).all(by.css('td'));
    }

    describe('Programmatic control of visual formatting', function(){
        it('Built-in formatters', function () {
            var idCell = "codeaWwWKg";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.checkDtContainerByIdCell(idCell);
            beakerPO.checkDataTableHeadByIdCell(idCell, 'm3\ny30\ny1\nm6\ny2\ny10\ny3\ntime\ny5\ny7');
            beakerPO.checkDataTableBodyByIdCell(idCell, 25, '0 8 8.258571 7.920952 7.956190 8.085238 8.206667 :) 1990-01-31 8.119524 8.196190');
        });
        it('Cell renderer', function () {
            var idCell = "codeROe5NG";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.checkDtContainerByIdCell(idCell);

            var arrTd = getArrayTdElements(idCell, 0);
            expect(arrTd.count()).toBe(11);
            beakerPO.checkSubString(arrTd.get(1), '7.8981', 0, 6);
            expect(arrTd.get(1).element(by.css('.dt-bar-data')).isPresent()).toBe(true);
            expect(arrTd.get(1).element(by.css('.dt-cell-text')).isPresent()).toBe(true);
        });
        it('Controlling column display', function () {
            var idCell = "codenPyPvP";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.checkDtContainerByIdCell(idCell);
            beakerPO.checkDataTableHeadByIdCell(idCell, 'm3\ny1\ny5\ntime\ny2');
            var arrTd = getArrayTdElements(idCell, 0);
            expect(arrTd.count()).toBe(6);
            beakerPO.checkSubString(arrTd.get(1), '7.898095', 0, 8);
            beakerPO.checkSubString(arrTd.get(2), '7.92095', 0, 7);
            beakerPO.checkSubString(arrTd.get(3), '8.11952', 0, 7);
            beakerPO.checkSubString(arrTd.get(5), '8.085238', 0, 8);
        });
        describe('Сell highlighters', function() {
            it('Color the entire table like a heatmap based on column value', function () {
                var idCell = "codeWyrMwb";
                beakerPO.scrollToBkCellByIdCell(idCell);
                beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
                beakerPO.checkDtContainerByIdCell(idCell);

                var arrTd = getArrayTdElements(idCell, 0);
                expect(arrTd.count()).toBe(11);
                beakerPO.checkSubString(arrTd.get(1), '7.8981', 0, 6);
                expect(arrTd.get(1).getCssValue('background-color')).toBe('rgba(236, 91, 88, 1)');

                var arrTd20 = getArrayTdElements(idCell, 20);
                expect(arrTd20.count()).toBe(11);
                beakerPO.checkSubString(arrTd20.get(1), '5.3735', 0, 6);
                expect(arrTd20.get(1).getCssValue('background-color')).toBe('rgba(190, 114, 130, 1)');
            });
            it('Use a closure to highlight specific values', function () {
                var idCell = "code7zZ3sT";
                beakerPO.scrollToBkCellByIdCell(idCell);
                beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
                beakerPO.checkDtContainerByIdCell(idCell);

                var arrTd = getArrayTdElements(idCell, 0);
                expect(arrTd.count()).toBe(4);
                beakerPO.checkSubString(arrTd.get(3), '3', 0, 1);
                expect(arrTd.get(3).getCssValue('background-color')).toBe('rgba(255, 0, 0, 1)');

                var arrTd1 = getArrayTdElements(idCell, 1);
                expect(arrTd1.count()).toBe(4);
                beakerPO.checkSubString(arrTd1.get(3), '6', 0, 1);
                expect(arrTd1.get(3).getCssValue('background-color')).toBe('rgba(0, 255, 0, 1)');
            });
            it('Heatmap with custom min/max values and colors', function () {
                var idCell = "codetHTtD2";
                beakerPO.scrollToBkCellByIdCell(idCell);
                beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
                beakerPO.checkDtContainerByIdCell(idCell);

                var arrTd = getArrayTdElements(idCell, 0);
                expect(arrTd.count()).toBe(11);
                beakerPO.checkSubString(arrTd.get(3), '7.9210', 0, 6);
                expect(arrTd.get(3).getCssValue('background-color')).toBe('rgba(105, 190, 120, 1)');
                beakerPO.checkSubString(arrTd.get(4), '7.9562', 0, 6);
                expect(arrTd.get(4).getCssValue('background-color')).toBe('rgba(249, 171, 171, 1)');

                var arrTd20 = getArrayTdElements(idCell, 20);
                expect(arrTd20.count()).toBe(11);
                beakerPO.checkSubString(arrTd20.get(3), '5.5725', 0, 6);
                expect(arrTd20.get(3).getCssValue('background-color')).toBe('rgba(241, 194, 87, 1)');
                beakerPO.checkSubString(arrTd20.get(4), '5.4790', 0, 6);
                expect(arrTd20.get(4).getCssValue('background-color')).toBe('rgba(0, 0, 0, 1)');
            });
            it('UniqueEntriesHighlighter', function () {
                var idCell = "code2KwSKV";
                beakerPO.scrollToBkCellByIdCell(idCell);
                beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
                beakerPO.checkDtContainerByIdCell(idCell);

                var rgb0 = 'rgba(245, 188, 188, 1)'
                var arrTd0 = getArrayTdElements(idCell, 0);
                expect(arrTd0.count()).toBe(4);
                beakerPO.checkSubString(arrTd0.get(1), '1', 0, 1);
                expect(arrTd0.get(1).getCssValue('background-color')).toBe(rgb0);
                beakerPO.checkSubString(arrTd0.get(2), '2', 0, 1);
                expect(arrTd0.get(2).getCssValue('background-color')).toBe(rgb0);

                var rgb1 = 'rgba(188, 245, 188, 1)';
                var arrTd1 = getArrayTdElements(idCell, 1);
                expect(arrTd1.count()).toBe(4);
                beakerPO.checkSubString(arrTd1.get(1), '3', 0, 1);
                expect(arrTd1.get(1).getCssValue('background-color')).toBe(rgb1);
                beakerPO.checkSubString(arrTd1.get(2), '4', 0, 1);
                expect(arrTd1.get(2).getCssValue('background-color')).toBe(rgb1);
            });
        });
        it('Adding custom actions', function () {
            var idCell = "codex9hziv";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.scrollHeaderElement();
            beakerPO.checkDtContainerByIdCell(idCell);

            var arrTd0 = getArrayTdElements(idCell, 0);
            expect(arrTd0.count()).toBe(4);
            beakerPO.checkSubString(arrTd0.get(1), '1', 0, 1);
            browser.actions().doubleClick(arrTd0.get(1)).perform();
            beakerPO.checkSubString(arrTd0.get(1), '6', 0, 1);

            browser.actions().mouseMove(arrTd0.get(1)).perform();
            browser.actions().click(protractor.Button.RIGHT).perform();
            var contextMenu =  element(by.css('ul.context-menu-list[style*="z-index: 1"]'));
            var negate = contextMenu.element(by.cssContainingText('span', 'negate'));
            browser.actions().mouseMove(negate).perform();
            negate.click();
            beakerPO.checkSubString(arrTd0.get(1), '-6', 0, 2);

            browser.actions().mouseMove(arrTd0.get(1)).perform();
            browser.actions().click(protractor.Button.RIGHT).perform();
            var run_misc_formatting = contextMenu.element(by.cssContainingText('span', 'run misc_formatting'));
            browser.actions().mouseMove(run_misc_formatting).perform();
            run_misc_formatting.click().then(function(){
                beakerPO.waitUntilLoadingFinished();
            });
        });
        it('Misc formatting', function () {
            var idCell = "code0Xkn1E";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.checkDtContainerByIdCell(idCell);
            var arrTd = getArrayTdElements(idCell, 0);
            expect(arrTd.count()).toBe(4);
            beakerPO.checkSubString(arrTd.get(1), '1', 0, 1);
            expect(arrTd.get(1).getCssValue('color')).toBe('rgba(192, 192, 192, 1)');
            expect(arrTd.get(1).getCssValue('font-size')).toBe('15px');
            expect(arrTd.get(1).getAttribute('title')).toBe('The value is: 1');

            var thHeader = beakerPO.getDataTablesTHeadByIdCell(idCell).get(0).all(by.css('th'));
            expect(thHeader.get(1).getCssValue('vertical-align')).toBe('bottom');
            expect(thHeader.get(1).getCssValue('font-size')).toBe('30px');
        });
        it('Run tags', function () {
            var idCell = "codeYEb1OS";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Table');
            beakerPO.checkDtContainerByIdCell(idCell);
            var arrTd0 = getArrayTdElements(idCell, 0);
            expect(arrTd0.count()).toBe(4);
            beakerPO.checkSubString(arrTd0.get(2), '2', 0, 1);
            browser.actions().doubleClick(arrTd0.get(2)).perform().then(function(){
                beakerPO.waitUntilLoadingFinished();
            });

            idCell = "codeC8S3M3";
            beakerPO.scrollToBkCellByIdCell(idCell);
            beakerPO.clickCodeCellInputButtonByIdCell(idCell, 'Results');
            beakerPO.scrollToCodeCellOutputByIdCell(idCell);
            beakerPO.checkCellOutputTextByIdCell(idCell, 'You clicked on the cell [0, 1]');
        });
    });
});<|endoftext|>


<commit_before>'use strict'

/* @flow */

import type {Disposable} from './disposable'

export class CompositeDisposable {
  disposed: boolean;
  disposables: Set<Disposable>;

  constructor(){
    this.disposed = false
    this.disposables = new Set(arguments)
  }
  add(){
    if (!this.disposed) {
      let length = arguments.length
      for (let i = 0; i < length; ++i) {
        this.disposables.add(arguments[i])
      }
    }
  }
  remove(){
    if (!this.disposed) {
      let length = arguments.length
      for (let i = 0; i < length; ++i) {
        this.disposables.delete(arguments[i])
      }
    }
  }
  clear(){
    if (!this.disposed) {
      this.disposables.clear()
    }
  }
  isDisposed(): boolean {
    return this.disposed
  }
  dispose(){
    if (!this.disposed) {
      this.disposed = true
      this.disposables.forEach(function(item) {
        item.dispose()
      })
      this.disposables.clear()
    }
  }
}
<commit_msg>:new: Use iterator instead of forEach<commit_after>'use strict'

/* @flow */

import type {Disposable} from './disposable'

export class CompositeDisposable {
  disposed: boolean;
  disposables: Set<Disposable>;

  constructor(){
    this.disposed = false
    this.disposables = new Set(arguments)
  }
  add(){
    if (!this.disposed) {
      let length = arguments.length
      for (let i = 0; i < length; ++i) {
        this.disposables.add(arguments[i])
      }
    }
  }
  remove(){
    if (!this.disposed) {
      let length = arguments.length
      for (let i = 0; i < length; ++i) {
        this.disposables.delete(arguments[i])
      }
    }
  }
  clear(){
    if (!this.disposed) {
      this.disposables.clear()
    }
  }
  isDisposed(): boolean {
    return this.disposed
  }
  dispose(){
    if (!this.disposed) {
      for (const item of this.disposables) {
        item.dispose()
      }
      this.disposed = true
      this.disposables.clear()
    }
  }
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Load this file and make your Angular module depend on the 'foam' module to
// get foam-view and foam-repeat directives in your code.
//
// Correct load order is Angular 1.5 and FOAM 2 (either order), this library,
// then your application module that uses Angular and this library.

/* globals angular: false */
angular.module('foam', [ 'ngMaterial' ]).directive('foamView', function() {
  return {
    restrict: 'A',
    scope: {
      // TODO: Make these one-way reactive bindings, probably.
      // Except for "as", that should just be a string.
      key: '=foamView',
      dao: '<foamDao',
      as: '@foamAs',
      delay: '@foamDelay'
    },
    priority: 2000,
    transclude: 'element',
    link: function($scope, element, attrs, controllers, transcludeFn) {
      var obj;
      var innerScope;

      var delay = typeof $scope.delay === 'undefined' ? 100 : $scope.delay;
      var as = $scope.as || 'object';

      // Subscription to changes inside the DAO.
      var daoSub;
      // Subscription to changes on the cloned object.
      var objSub;

      // Look up our FOAM object on the DAO.
      function initialStart() {
        if ( ! $scope.dao ) return;
        $scope.dao.find($scope.key).then(hookUpObject);
        daoSub && daoSub.destroy();
        daoSub = $scope.dao.on.sub(function(sub, _, operation, obj) {
          if ( operation === 'reset' ) {
            initialStart();
          } else if ( obj.id === $scope.key ) {
            hookUpObject(obj);
          }
        });

        innerScope.$watch(as, function(nu, old) {
          if ( nu && nu.id !== (old && old.id) ) {
            $scope.key = nu.id;
          }
        });
      }

      $scope.$watch('key', initialStart);
      $scope.$watch('dao', initialStart);

      function hookUpObject(o) {
        innerScope[as] = obj = o.clone();

        objSub && objSub.destroy();
        objSub = obj.propertyChange.sub(foam.X.merged(function(sub) {
          sub.destroy();
          $scope.dao.put(obj).then(hookUpObject);
        }, delay));
      }

      transcludeFn(function(clone, scope) {
        innerScope = scope;
        initialStart();
        element.after(clone);
      });
      // TODO: Do I need to add something extra to destroy that scope?
    }
  };
});

angular.module('foam').directive('foamRepeat', [ '$timeout',
    function($timeout) {
  return {
    restrict: 'A',
    scope: {
      // TODO: Make these one-way reactive bindings, probably.
      // Except for "as", that should just be a string.
      dao: '<foamRepeat',
      as: '@foamAs'
    },
    priority: 20000,
    transclude: 'element',
    link: function($scope, element, attrs, controllers, transcludeFn) {
      var cache = {};
      var as = $scope.as || 'object';
      var delay = 200;

      var listener = {
        put: onPut,
        remove: onRemove,
        reset: onReset,
        eof: function() { }
      };

      $scope.dao.pipe(listener);

      $scope.$watch('dao', function() {
        doReset();
        $scope.dao.pipe(listener);
      });

      function attachObject(obj) {
        obj.propertyChange.sub(foam.X.merged(function(sub) {
          sub.destroy();
          $scope.dao.put(obj);
        }, delay));
      }

      function onPut(obj) {
        var c = cache[obj.id];
        if ( c ) {
          var o = c.scope[as] = obj.clone();
          $timeout(function() { c.scope.$apply(); }, 0, false);
          attachObject(o);
          return;
        }

        // Otherwise we need to create a new clone, bind its scope, and save the
        // scope.
        c = { object: obj.clone() };
        attachObject(c.object);
        transcludeFn(function(clone, scope) {
          var end = element.clone(false);
          element.replaceWith(clone);
          clone.after(end);
          element = end;

          c.element = clone;
          c.scope = scope;
          scope[as] = c.object;
          cache[obj.id] = c;
        });
      }

      function remove(c) {
        c.element.remove();
        c.scope.$destroy();
      }
      // TODO: Optimization: Hide DOM nodes and reuse their scopes?

      function onRemove(obj) {
        var c = cache[obj.id];
        c && remove(c);
        delete cache[obj.id];
      }

      function doReset() {
        for ( var id in cache ) {
          remove(cache[id]);
        }
        cache = {};
        $scope.dao.select(listener);
      }

      function onReset() {
        doReset();
        $scope.dao.select(listener);
      }
    }
  };
} ]);

angular.module('foam').directive('foamInternalInject', function() {
  return {
    link: function(scope, element, attrs, controller, transcludeFn) {
      // TODO: Include error message generation here, for production.
      var innerScope = scope.$new();
      transcludeFn(innerScope, function(clone) {
        element.empty();
        element.append(clone);
        element.on('$destroy', function() {
          innerScope.$destroy();
        });
      });
    }
  };
});

angular.module('foam').directive('foamDaoController', [ '$timeout',
    function($timeout) {
  return {
    restrict: 'E',
    scope: {
      dao: '<',
      selection: '=',
      controllerMode: '=',
      header: '<',
      fab: '<',
      label: '<'
    },
    transclude: true,
    template: foam.String.multiline(function() {/*

      {{label}}
      <button class="foam-dao-controller-create" ng-click="doCreate()">
      New
      </button>

      <md-button ng-if="fab" class="md-fab md-fab-bottom-right"
          ng-click="doCreate()">
      <md-icon>add</md-icon>
      </md-button>

    */}),

    link: function(scope) {
      scope.doCreate = function doCreate() {
        var obj = foam.lookup(scope.dao.of).create();
        scope.selection = obj;
        scope.controllerMode = 'create';
      };

      scope.doSave = function doSave() {
        scope.dao.put(scope.selection);
        scope.selection = null;
        scope.controllerMode = 'none';
      };

      scope.controllerMode = 'none';

      scope.doEdit = function doEdit(item) {
        scope.controllerMode = 'edit';
        var clone = item.clone();
        scope.selection = clone;

        var timeout;
        clone.propertyChange.sub(function(sub) {
          if ( timeout ) {
            $timeout.cancel(timeout);
          }
          timeout = $timeout(function() {
            timeout = null;
            scope.dao.put(clone);
          }, 500, false);
        });
      };
    }
  };
} ]);

angular.module('foam').directive('foamDetails', [ '$compile',
    function($compile) {
  return {
    restrict: 'A',
    scope: {
      object: '<foamDetails'
    },
    transclude: true,
    link: function(scope, element, attrs, _, $transclude) {
      var lastClass;
      var maybeRebuild = function maybeRebuild(obj) {
        // We only need to rebuild the view if the model has changed.
        if ( ! obj || (lastClass && obj.cls_ === lastClass) ) return;

        lastClass = obj.cls_;
        var props = obj.cls_.getAxiomsByClass(foam.core.Property);
        var html = '';
        for ( var i = 0; i < props.length; i++ ) {
          var prop = props[i];
          if ( prop.hidden ) continue;

          if ( prop.ngTemplate ) {
            html += prop.ngTemplate;
            continue;
          }

          // Otherwise we dispatch on the type of the property.
          if ( foam.core.Boolean.isInstance(prop) ) {
            html += '<md-checkbox ng-model="object.' + prop.name + '">' +
                prop.label + '</md-checkbox>';
          } else {
            var type = 'text';
            if ( foam.core.Int.isInstance(prop) ||
                foam.core.Float.isInstance(prop) ) {
              type = 'number';
            }

            var inputHTML = '<input type="' + type + '" ' +
                'ng-model="object.' + prop.name + '" ' +
                (prop.required ? ' required' : '') + ' />';
            html += '<md-input-container>' +
                '' + prop.label + '' +
                inputHTML +
                '</md-input-container>';
          }
        }

        var subscope;
        $transclude(function(_, innerScope) {
          if ( subscope ) subscope.$destroy();
          subscope = innerScope.$new();
          subscope.object = scope.object;
          element.empty();
          element.append(html);
          $compile(element.contents())(subscope);
        });
      };

      scope.$watch('object', function(nu) {
        maybeRebuild(nu);
      });
    }
  };
} ]);

<commit_msg>Angular: Handle the object (but not the model) changing in <foam-details><commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Load this file and make your Angular module depend on the 'foam' module to
// get foam-view and foam-repeat directives in your code.
//
// Correct load order is Angular 1.5 and FOAM 2 (either order), this library,
// then your application module that uses Angular and this library.

/* globals angular: false */
angular.module('foam', [ 'ngMaterial' ]).directive('foamView', function() {
  return {
    restrict: 'A',
    scope: {
      // TODO: Make these one-way reactive bindings, probably.
      // Except for "as", that should just be a string.
      key: '=foamView',
      dao: '<foamDao',
      as: '@foamAs',
      delay: '@foamDelay'
    },
    priority: 2000,
    transclude: 'element',
    link: function($scope, element, attrs, controllers, transcludeFn) {
      var obj;
      var innerScope;

      var delay = typeof $scope.delay === 'undefined' ? 100 : $scope.delay;
      var as = $scope.as || 'object';

      // Subscription to changes inside the DAO.
      var daoSub;
      // Subscription to changes on the cloned object.
      var objSub;

      // Look up our FOAM object on the DAO.
      function initialStart() {
        if ( ! $scope.dao ) return;
        $scope.dao.find($scope.key).then(hookUpObject);
        daoSub && daoSub.destroy();
        daoSub = $scope.dao.on.sub(function(sub, _, operation, obj) {
          if ( operation === 'reset' ) {
            initialStart();
          } else if ( obj.id === $scope.key ) {
            hookUpObject(obj);
          }
        });

        innerScope.$watch(as, function(nu, old) {
          if ( nu && nu.id !== (old && old.id) ) {
            $scope.key = nu.id;
          }
        });
      }

      $scope.$watch('key', initialStart);
      $scope.$watch('dao', initialStart);

      function hookUpObject(o) {
        innerScope[as] = obj = o.clone();

        objSub && objSub.destroy();
        objSub = obj.propertyChange.sub(foam.X.merged(function(sub) {
          sub.destroy();
          $scope.dao.put(obj).then(hookUpObject);
        }, delay));
      }

      transcludeFn(function(clone, scope) {
        innerScope = scope;
        initialStart();
        element.after(clone);
      });
      // TODO: Do I need to add something extra to destroy that scope?
    }
  };
});

angular.module('foam').directive('foamRepeat', [ '$timeout',
    function($timeout) {
  return {
    restrict: 'A',
    scope: {
      // TODO: Make these one-way reactive bindings, probably.
      // Except for "as", that should just be a string.
      dao: '<foamRepeat',
      as: '@foamAs'
    },
    priority: 20000,
    transclude: 'element',
    link: function($scope, element, attrs, controllers, transcludeFn) {
      var cache = {};
      var as = $scope.as || 'object';
      var delay = 200;

      var listener = {
        put: onPut,
        remove: onRemove,
        reset: onReset,
        eof: function() { }
      };

      $scope.dao.pipe(listener);

      $scope.$watch('dao', function() {
        doReset();
        $scope.dao.pipe(listener);
      });

      function attachObject(obj) {
        obj.propertyChange.sub(foam.X.merged(function(sub) {
          sub.destroy();
          $scope.dao.put(obj);
        }, delay));
      }

      function onPut(obj) {
        var c = cache[obj.id];
        if ( c ) {
          var o = c.scope[as] = obj.clone();
          $timeout(function() { c.scope.$apply(); }, 0, false);
          attachObject(o);
          return;
        }

        // Otherwise we need to create a new clone, bind its scope, and save the
        // scope.
        c = { object: obj.clone() };
        attachObject(c.object);
        transcludeFn(function(clone, scope) {
          var end = element.clone(false);
          element.replaceWith(clone);
          clone.after(end);
          element = end;

          c.element = clone;
          c.scope = scope;
          scope[as] = c.object;
          cache[obj.id] = c;
        });
      }

      function remove(c) {
        c.element.remove();
        c.scope.$destroy();
      }
      // TODO: Optimization: Hide DOM nodes and reuse their scopes?

      function onRemove(obj) {
        var c = cache[obj.id];
        c && remove(c);
        delete cache[obj.id];
      }

      function doReset() {
        for ( var id in cache ) {
          remove(cache[id]);
        }
        cache = {};
        $scope.dao.select(listener);
      }

      function onReset() {
        doReset();
        $scope.dao.select(listener);
      }
    }
  };
} ]);

angular.module('foam').directive('foamInternalInject', function() {
  return {
    link: function(scope, element, attrs, controller, transcludeFn) {
      // TODO: Include error message generation here, for production.
      var innerScope = scope.$new();
      transcludeFn(innerScope, function(clone) {
        element.empty();
        element.append(clone);
        element.on('$destroy', function() {
          innerScope.$destroy();
        });
      });
    }
  };
});

angular.module('foam').directive('foamDaoController', [ '$timeout',
    function($timeout) {
  return {
    restrict: 'E',
    scope: {
      dao: '<',
      selection: '=',
      controllerMode: '=',
      header: '<',
      fab: '<',
      label: '<'
    },
    transclude: true,
    template: foam.String.multiline(function() {/*

      {{label}}
      <button class="foam-dao-controller-create" ng-click="doCreate()">
      New
      </button>

      <md-button ng-if="fab" class="md-fab md-fab-bottom-right"
          ng-click="doCreate()">
      <md-icon>add</md-icon>
      </md-button>

    */}),

    link: function(scope) {
      scope.doCreate = function doCreate() {
        var obj = foam.lookup(scope.dao.of).create();
        scope.selection = obj;
        scope.controllerMode = 'create';
      };

      scope.doSave = function doSave() {
        scope.dao.put(scope.selection);
        scope.selection = null;
        scope.controllerMode = 'none';
      };

      scope.controllerMode = 'none';

      scope.doEdit = function doEdit(item) {
        scope.controllerMode = 'edit';
        var clone = item.clone();
        scope.selection = clone;

        var timeout;
        clone.propertyChange.sub(function(sub) {
          if ( timeout ) {
            $timeout.cancel(timeout);
          }
          timeout = $timeout(function() {
            timeout = null;
            scope.dao.put(clone);
          }, 500, false);
        });
      };
    }
  };
} ]);

angular.module('foam').directive('foamDetails', [ '$compile',
    function($compile) {
  return {
    restrict: 'A',
    scope: {
      object: '<foamDetails'
    },
    transclude: true,
    link: function(scope, element, attrs, _, $transclude) {
      var lastClass;
      var subscope;
      var maybeRebuild = function maybeRebuild(obj) {
        // We only need to rebuild the view if the model has changed.
        if ( ! obj ) return;

        if ( lastClass && obj.cls_ === lastClass ) {
          subscope.object = obj;
          return;
        }

        lastClass = obj.cls_;
        var props = obj.cls_.getAxiomsByClass(foam.core.Property);
        var html = '';
        for ( var i = 0; i < props.length; i++ ) {
          var prop = props[i];
          if ( prop.hidden ) continue;

          if ( prop.ngTemplate ) {
            html += prop.ngTemplate;
            continue;
          }

          // Otherwise we dispatch on the type of the property.
          if ( foam.core.Boolean.isInstance(prop) ) {
            html += '<md-checkbox ng-model="object.' + prop.name + '">' +
                prop.label + '</md-checkbox>';
          } else {
            var type = 'text';
            if ( foam.core.Int.isInstance(prop) ||
                foam.core.Float.isInstance(prop) ) {
              type = 'number';
            }

            var inputHTML = '<input type="' + type + '" ' +
                'ng-model="object.' + prop.name + '" ' +
                (prop.required ? ' required' : '') + ' />';
            html += '<md-input-container>' +
                '' + prop.label + '' +
                inputHTML +
                '</md-input-container>';
          }
        }

        $transclude(function(_, innerScope) {
          if ( subscope ) subscope.$destroy();
          subscope = innerScope.$new();
          subscope.object = scope.object;
          element.empty();
          element.append(html);
          $compile(element.contents())(subscope);
        });
      };

      scope.$watch('object', function(nu) {
        maybeRebuild(nu);
      });
    }
  };
} ]);

<|endoftext|>


<commit_before>var __ = require('underscore'),
    Backbone = require('backbone'),
    $ = require('jquery'),
    app = require('../App').getApp();

/*eslint no-use-before-define:0*/
module.exports = function (currency, callback) {
    //some APIs require currency to be upper case
    currency = currency.toUpperCase();

    var showStatus,
        btPrices = [],
        btcAverages = {rates: {}};

    //if this is the first check, show status
    if(!window.btcAverages){
        showStatus = app.statusBar.pushMessage({
            msg: polyglot.t('LoadingBitcoinPrices'),
            duration: false
        });
    }

    window.btcAverages = window.btcAverages || {};

    var getBTCPrices = function(){
      $.ajax({
        url: app.serverConfig.getServerBaseUrl() + '/btc_price',
        dataType: 'json',
        cache: false //just in case
      })
      .done(function(data, textStatus, jqXHR){
        if(!__.isEmpty(data.currencyCodes)){
          btPrices.push(data.currencyCodes);
        }
      })
      .fail(function (jqXHR, textStatus, errorThrown) {
        logAPIErrorInfo("Call to btc_price", jqXHR, textStatus, errorThrown);
      })
      .always(function () {
        makeAveragePrice();
      });

    };

   if (window.btcAverages.timeStamp
        && Math.floor((new Date() - window.btcAverages.timeStamp) / 60000) < 15
        && window.currencyKeys
        && window.btcAverages.rates[currency]) {
        typeof callback === 'function' && callback(window.btcAverages.rates[currency], window.currencyKeys);
    } else {
        getBTCPrices();
    }

    var makeAveragePrice = function () {
        var sum,
            currencyPrices,
            currency_code,
            currencyKeys,
            averagePrice,
            keys = {},
            btAve;
        btcAverages.timeStamp = new Date();
        for (var i in btPrices) {
            if (btPrices.hasOwnProperty(i)) {
                keys = $.extend(keys, btPrices[i]);
            }
        }
        if (btPrices.length === 0) {
            console.log("Bitcoin exchange rates are not available.");
        }
        currencyKeys = Object.keys(keys);
        for (var index in currencyKeys) {
            if (currencyKeys.hasOwnProperty(index)) {
                currency_code = currencyKeys[index];
                currencyPrices = [];
                for (var j in btPrices) {
                    if (btPrices[j][currency_code]) {
                        currencyPrices.push(btPrices[j][currency_code]);
                    }
                }
                sum = 0;
                for (var jIndex in currencyPrices) {
                    if (currencyPrices.hasOwnProperty(jIndex)) {
                        sum += Number(currencyPrices[jIndex]);
                    }
                }
                averagePrice = sum / currencyPrices.length;  //TODO: Eliminate division due to floating point math
                btcAverages.rates[currency_code] = averagePrice;
            }
        }
        window.btcAverages = btcAverages;
        window.currencyKeys = currencyKeys;
        if(currency != "BTC"){
            btAve = btcAverages.rates[currency];
        } else {
            btAve = 1;
        }

        showStatus && showStatus.remove();

        typeof callback === 'function' && callback(btAve, currencyKeys);
    };

    function logAPIErrorInfo(APIname, jqXHR, textStatus, errorThrown)
    {
        console.log(APIname + " request failed: ");
        console.log(jqXHR);
        console.log(textStatus);
        console.log(errorThrown);
    }
};
<commit_msg>fix btc price<commit_after>var __ = require('underscore'),
    Backbone = require('backbone'),
    $ = require('jquery'),
    app = require('../App').getApp();

/*eslint no-use-before-define:0*/
module.exports = function (currency, callback) {
    //some APIs require currency to be upper case
    currency = currency.toUpperCase();

    var showStatus,
        btPrices = [],
        btcAverages = {rates: {}};

    //if this is the first check, show status
    if(!window.btcAverages){
        showStatus = app.statusBar.pushMessage({
            msg: polyglot.t('LoadingBitcoinPrices'),
            duration: false
        });
    }

    window.btcAverages = window.btcAverages || {};

    var getBTCPrices = function(){
      $.ajax({
        url: app.serverConfig.getServerBaseUrl() + '/btc_price',
        dataType: 'json',
        cache: false //just in case
      })
      .done(function(data, textStatus, jqXHR){
        if(!__.isEmpty(data.currencyCodes)){
          btPrices.push(data.currencyCodes);
        }
      })
      .fail(function (jqXHR, textStatus, errorThrown) {
        logAPIErrorInfo("Call to btc_price", jqXHR, textStatus, errorThrown);
      })
      .always(function () {
        makeAveragePrice();
      });

    };

  if(currency == "BTC" && window.currencyKeys) {
    typeof callback === 'function' && callback(1, window.currencyKeys);
  } else if(window.btcAverages.timeStamp
        && Math.floor((new Date() - window.btcAverages.timeStamp) / 60000) < 15
        && window.currencyKeys
        && window.btcAverages.rates[currency]) {
        typeof callback === 'function' && callback(window.btcAverages.rates[currency], window.currencyKeys);
    } else {
        getBTCPrices();
    }

    var makeAveragePrice = function () {
        var sum,
            currencyPrices,
            currency_code,
            currencyKeys,
            averagePrice,
            keys = {},
            btAve;
        btcAverages.timeStamp = new Date();
        for (var i in btPrices) {
            if (btPrices.hasOwnProperty(i)) {
                keys = $.extend(keys, btPrices[i]);
            }
        }
        if (btPrices.length === 0) {
            console.log("Bitcoin exchange rates are not available.");
        }
        currencyKeys = Object.keys(keys);
        for (var index in currencyKeys) {
            if (currencyKeys.hasOwnProperty(index)) {
                currency_code = currencyKeys[index];
                currencyPrices = [];
                for (var j in btPrices) {
                    if (btPrices[j][currency_code]) {
                        currencyPrices.push(btPrices[j][currency_code]);
                    }
                }
                sum = 0;
                for (var jIndex in currencyPrices) {
                    if (currencyPrices.hasOwnProperty(jIndex)) {
                        sum += Number(currencyPrices[jIndex]);
                    }
                }
                averagePrice = sum / currencyPrices.length;  //TODO: Eliminate division due to floating point math
                btcAverages.rates[currency_code] = averagePrice;
            }
        }
        window.btcAverages = btcAverages;
        window.currencyKeys = currencyKeys;
        if(currency != "BTC"){
            btAve = btcAverages.rates[currency];
        } else {
            btAve = 1;
        }

        showStatus && showStatus.remove();

        typeof callback === 'function' && callback(btAve, currencyKeys);
    };

    function logAPIErrorInfo(APIname, jqXHR, textStatus, errorThrown)
    {
        console.log(APIname + " request failed: ");
        console.log(jqXHR);
        console.log(textStatus);
        console.log(errorThrown);
    }
};
<|endoftext|>


<commit_before>(function(){
  // http://stackoverflow.com/questions/10906734/how-to-upload-image-into-html5-canvas
  var original;
  var imageLoader = document.querySelector('#imageLoader');
  imageLoader.addEventListener('change', handleImage, false);
  var canvas = document.querySelector('#image');
  var ctx = canvas.getContext('2d');

  function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
      var img = new Image();
      img.onload = function(){
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img,0,0);
        original = ctx.getImageData(0, 0, canvas.width, canvas.height);
      }
      img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);
  }

  // greys out the buttons while manipulation is happening
  // un-greys out the buttons when the manipulation is done
  function toggleButtonsAbledness() {
    var buttons = document.querySelectorAll('button');
    for (var i = 0; i < buttons.length; i++) {
      if (buttons[i].hasAttribute('disabled')) {
        buttons[i].removeAttribute('disabled')
      } else {
        buttons[i].setAttribute('disabled', null);
      }
    };
  }

  function manipulateImage(type) {
    var a, b, g, i, imageData, j, length, pixel, r, ref;
    imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

    toggleButtonsAbledness();

    var myWorker = new Worker("scripts/worker.js");
    onchange = function() {
      myWorker.postMessage(imageData);
    }
    myWorker.onmessage = function(e) {
      imageData = e.data.imageData;
    }

    toggleButtonsAbledness();
    return ctx.putImageData(imageData, 0, 0);
  };

  function revertImage() {
    return ctx.putImageData(original, 0, 0);
  }

  document.querySelector('#invert').onclick = function() {
    manipulateImage("invert");
  };
  document.querySelector('#chroma').onclick = function() {
    manipulateImage("chroma");
  };
  document.querySelector('#greyscale').onclick = function() {
    manipulateImage("greyscale");
  };
  document.querySelector('#vibrant').onclick = function() {
    manipulateImage("vibrant");
  };
  document.querySelector('#revert').onclick = function() {
    revertImage();
  };
})();<commit_msg>troubleshooting<commit_after>(function(){
  // http://stackoverflow.com/questions/10906734/how-to-upload-image-into-html5-canvas
  var original;
  var imageLoader = document.querySelector('#imageLoader');
  imageLoader.addEventListener('change', handleImage, false);
  var canvas = document.querySelector('#image');
  var ctx = canvas.getContext('2d');

  function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
      var img = new Image();
      img.onload = function(){
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img,0,0);
        original = ctx.getImageData(0, 0, canvas.width, canvas.height);
      }
      img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);
  }

  // greys out the buttons while manipulation is happening
  // un-greys out the buttons when the manipulation is done
  function toggleButtonsAbledness() {
    var buttons = document.querySelectorAll('button');
    for (var i = 0; i < buttons.length; i++) {
      if (buttons[i].hasAttribute('disabled')) {
        buttons[i].removeAttribute('disabled')
      } else {
        buttons[i].setAttribute('disabled', null);
      }
    };
  }

  function manipulateImage(type) {
    var a, b, g, i, imageData, j, length, pixel, r, ref;
    imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

    toggleButtonsAbledness();

    var myWorker = new Worker("scripts/worker.js");
    onchange = function() {
      myWorker.postMessage(imageData);
    }
    myWorker.onmessage = function(e) {
      imageData = imageData;
    }

    toggleButtonsAbledness();
    return ctx.putImageData(imageData, 0, 0);
  };

  function revertImage() {
    return ctx.putImageData(original, 0, 0);
  }

  document.querySelector('#invert').onclick = function() {
    manipulateImage("invert");
  };
  document.querySelector('#chroma').onclick = function() {
    manipulateImage("chroma");
  };
  document.querySelector('#greyscale').onclick = function() {
    manipulateImage("greyscale");
  };
  document.querySelector('#vibrant').onclick = function() {
    manipulateImage("vibrant");
  };
  document.querySelector('#revert').onclick = function() {
    revertImage();
  };
})();<|endoftext|>


<commit_before>// use strict mode to avoid problems, should apply only to this script
"use strict";

// run this on all window size change events
$(window).bind("load resize orientationchange", function() {
  resizer($(".ps-grid"));
});

function resizer(el) {
  // this approach is inspired by https://www.html5rocks.com/en/tutorials/casestudies/gopherwoord-studios-resizing-html5-games/#disqus_thread
  // to be safe, this SHOULD be recalculated every time, b/c el MIGHT have stuff which does not resize dynamically, therefore altering aspect ratio
  var reqAspRatio = findAspectRatio(el);
  // this should respect parent width
  var availWidth = el.parent().innerWidth();
  // but for height, we only care about viewport limitations; users will have to scroll accordingly
  var availHeight = $(window).innerHeight();
  var availAspRat = availWidth / availHeight;

  // remember that we ONLY write out width, rest is dealt with via css padding hack
  if (availAspRat > reqAspRatio) {
    // this is e.g. 4/3 in 16/9, needs boxes on the side, aka width based on height
    el.css("width", Math.floor(availHeight * reqAspRatio));
  } else if (availAspRat < reqAspRatio) {
    // this is e.g. 16/9 in 4/3, needs boxes on the top, aka, width can be max
    el.css("width", Math.floor(availWidth));
  }
}

function findAspectRatio(el) {
  // we're letting the browser figure out the correct aspect ratio of the *overall* grid, based on the padding-hack in the css
  var aspRatio = el.outerWidth() / el.outerHeight();
  return aspRatio;
}

// create table from json
function createTable(tableData, colNames, rowNames, header, footer, aspectRatioCards, rowheight) {
  var table = document.createElement('table');
  var tableBody = document.createElement('tbody');

  tableData.forEach(function(rowData) {
    var row = createTableRow(rowData, false);

    tableBody.appendChild(row);
  });

  // make header and footer
  if (header) {
    var tableHeader = document.createElement('thead');
    tableHeader.appendChild(createTableRow(colNames, true))
    table.appendChild(tableHeader);
  }
  if (footer) {
    var tableFooter = document.createElement('tfoot');
    tableFooter.appendChild(createTableRow(colNames, false))
    table.appendChild(tableFooter);
  }

  table.appendChild(tableBody);
  return table
}

function createTableRow(rowData, header) {
  var row = document.createElement('tr');

  rowData.forEach(function(cellData) {
    if (header) {
      var cell = document.createElement('th');
    } else {
      var cell = document.createElement('td');
    }
    cell.appendChild(document.createTextNode(cellData));
    row.appendChild(cell);
  });

  return row;
}
<commit_msg>add conditional cell formatting in js #393<commit_after>// use strict mode to avoid problems, should apply only to this script
"use strict";

// run this on all window size change events
$(window).bind("load resize orientationchange", function() {
  resizer($(".ps-grid"));
});

function resizer(el) {
  // this approach is inspired by https://www.html5rocks.com/en/tutorials/casestudies/gopherwoord-studios-resizing-html5-games/#disqus_thread
  // to be safe, this SHOULD be recalculated every time, b/c el MIGHT have stuff which does not resize dynamically, therefore altering aspect ratio
  var reqAspRatio = findAspectRatio(el);
  // this should respect parent width
  var availWidth = el.parent().innerWidth();
  // but for height, we only care about viewport limitations; users will have to scroll accordingly
  var availHeight = $(window).innerHeight();
  var availAspRat = availWidth / availHeight;

  // remember that we ONLY write out width, rest is dealt with via css padding hack
  if (availAspRat > reqAspRatio) {
    // this is e.g. 4/3 in 16/9, needs boxes on the side, aka width based on height
    el.css("width", Math.floor(availHeight * reqAspRatio));
  } else if (availAspRat < reqAspRatio) {
    // this is e.g. 16/9 in 4/3, needs boxes on the top, aka, width can be max
    el.css("width", Math.floor(availWidth));
  }
}

function findAspectRatio(el) {
  // we're letting the browser figure out the correct aspect ratio of the *overall* grid, based on the padding-hack in the css
  var aspRatio = el.outerWidth() / el.outerHeight();
  return aspRatio;
}

// create table from json
function createTable(tableData, colNames, rowNames, header, footer, aspectRatioCards, rowheight) {
  var table = document.createElement('table');
  table.className = "ps-grid";
  var tableBody = document.createElement('tbody');

  tableData.forEach(function(rowData) {
    var row = createTableRow(rowData, false, false);

    tableBody.appendChild(row);
  });

  // make header and footer
  if (header) {
    var tableHeader = document.createElement('thead');
    tableHeader.appendChild(createTableRow(colNames, true, false))
    table.appendChild(tableHeader);
  }
  if (footer) {
    var tableFooter = document.createElement('tfoot');
    tableFooter.appendChild(createTableRow(colNames, false, true))
    table.appendChild(tableFooter);
  }

  table.appendChild(tableBody);
  return table
}

function createTableRow(rowData, header, footer) {
  var row = document.createElement('tr');

  rowData.forEach(function(cellData) {
    if (header) {
      var cell = document.createElement('th');
    } else if (footer) {
      var cell = document.createElement('td');
    } else {
      var cell = document.createElement('td');
      cell.className = "cell";
      if (cellData) {
        cell.className = "allowed";
      }
    }
    cell.appendChild(document.createTextNode(cellData));
    row.appendChild(cell);
  });

  return row;
}
<|endoftext|>


<commit_before>(function(app) {
  'use strict';
  var m = require('mithril');

  var sidePanelView = function(ctrl) {
    var state = ctrl.state();
    var searchKeyword = ctrl.searchKeyword();
    var pieceList = ctrl.searchPieceList(searchKeyword);

    return m('#side_panel', {
      className: state
    }, [
      m('input#search_input', {
        type: 'search',
        autocapitalize: 'off',
        autocorrect: 'off',
        value: searchKeyword,
        config: function(element, isInitialized) {
          if (isInitialized)
            return;

          var isFocus = false;
          if (dom.supportsTouch()) {
            document.addEventListener('touchstart', function(event) {
              if (event.target !== element)
                element.blur();
            });
          } else {
            element.addEventListener('blur', function() {
              isFocus = false;
            });
            element.addEventListener('click', function() {
              if (isFocus)
                return;
              isFocus = true;
              if (element.selectionStart === element.selectionEnd)
                element.select();
            });
          }

          var changeListener = function(event) {
            var cache = ctrl.searchKeyword();
            var value = event.target.value;

            if (value === cache)
              return;

            ctrl.dispatchEvent({
              type: 'searchkeywordchange',
              value: value
            });
          };
          element.addEventListener('change', changeListener);
          element.addEventListener('input', changeListener);
        }
      }),
      m('#piece_list', {
        config: function(element, isInitialized) {
          if (isInitialized)
            return;

          var isHeld;
          var draggingNode;
          var cloneOffset;
          var isFirstDrag;
          var isAutoClose;
          var cloneNode;

          var start = function() {
            var pieceListContent = element.children[0];

            cloneOffset = {
              left: draggingNode.offsetLeft - pieceListContent.scrollLeft,
              top: draggingNode.offsetTop - pieceListContent.scrollTop
            };

            isFirstDrag = true;
            isAutoClose = false;

            draggingNode.style.opacity = 0.6;

            dom.removeKeyboardFocus();

            cloneNode = draggingNode.cloneNode(true);
            dom.addClass(cloneNode, 'drag');
            document.body.appendChild(cloneNode);
          };

          dom.pointerEvent('.piece-list-item-container', {
            onstart: function(event) {
              isHeld = !dom.supportsTouch();
              draggingNode = event.target;
              if (!dom.supportsTouch())
                start();
            },
            onhold: function() {
              isHeld = true;
              if (dom.supportsTouch())
                start();
            },
            ondrag: function(event, dx, dy) {
              if (!isHeld)
                return;

              event.preventDefault();
              event.stopPropagation();

              if (isFirstDrag) {
                isFirstDrag = false;

                if (window.innerWidth < 358) {
                  isAutoClose = true;
                  ctrl.dispatchEvent({type: 'close'});
                }

                cloneNode.style.left = cloneOffset.left + 'px';
                cloneNode.style.top = cloneOffset.top + 'px';
              }

              dom.translate(cloneNode, dx, dy);
            },
            ondragend: function(event, dx, dy) {
              if (!isHeld)
                return;

              var pageX = cloneOffset.left + dx;
              var pageY = cloneOffset.top + dy;
              var dragEndEvent = {
                type: 'dragend',
                pageX: pageX,
                pageY: pageY,
                pieceSrc: cloneNode.getAttribute('data-piece-src'),
                pieceLabel: cloneNode.children[0].textContent
              };
              ctrl.dispatchEvent(dragEndEvent);
            },
            onend: function() {
              if (!isHeld)
                return;

              draggingNode.style.cssText = '';
              document.body.removeChild(cloneNode);

              if (isAutoClose)
                ctrl.dispatchEvent({type: 'open'});
            }
          });
        }
      }, [
        m('#piece_list_content', pieceList.map(function(item) {
          return m('.piece-list-item', [
            m('.piece-list-item-container', {
              className: dom.supportsTouch() ? '' : 'hoverable',
              'data-piece-src': item.src
            }, [
              m('.piece-list-item-header', item.label),
              m('.piece-list-item-content', item.description)
            ])
          ]);
        }))
      ]),
      m('#divider', [
        m('#divider_icon', {
          config: function(element, isInitialized) {
            if (isInitialized)
              return;

            dom.pointerEvent('#divider_icon', {
              ontap: function() {
                ctrl.dispatchEvent({type: 'toggle'});
                dom.setCursor('default');
                dom.removeClass(element, 'tap');
              },
              onstart: function(event) {
                event.preventDefault();
                dom.addClass(element, 'tap');
                dom.removeKeyboardFocus();
                dom.setCursor('pointer');
              },
              onout: function() {
                dom.removeClass(element, 'tap');
                dom.setCursor('default');
              },
              onover: function() {
                dom.addClass(element, 'tap');
                dom.setCursor('pointer');
              }
            });
          }
        })
      ])
    ]);
  };

  if (typeof module !== 'undefined' && module.exports)
    module.exports = sidePanelView;
  else
    app.sidePanelView = sidePanelView;
})(this.app || (this.app = {}));<commit_msg>Refactor side-panel-view<commit_after>(function(app) {
  'use strict';
  var m = require('mithril');

  var sidePanelView = function(ctrl) {
    var state = ctrl.state();
    var searchKeyword = ctrl.searchKeyword();
    var pieceList = ctrl.searchPieceList(searchKeyword);

    return m('#side_panel', {
      className: state
    }, [
      m('input#search_input', {
        type: 'search',
        autocapitalize: 'off',
        autocorrect: 'off',
        value: searchKeyword,
        config: searchInputConfig.bind(ctrl)
      }),
      m('#piece_list', {
        config: pieceListConfig.bind(ctrl)
      }, [
        m('#piece_list_content', pieceList.map(function(item) {
          return m('.piece-list-item', [
            m('.piece-list-item-container', {
              className: dom.supportsTouch() ? '' : 'hoverable',
              'data-piece-src': item.src
            }, [
              m('.piece-list-item-header', item.label),
              m('.piece-list-item-content', item.description)
            ])
          ]);
        }))
      ]),
      m('#divider', [
        m('#divider_icon', {
          config: dividerIconConfig.bind(ctrl)
        })
      ])
    ]);
  };

  var searchInputConfig = function(element, isInitialized) {
    if (isInitialized)
      return;

    var ctrl = this;

    var isFocus = false;
    if (dom.supportsTouch()) {
      document.addEventListener('touchstart', function(event) {
        if (event.target !== element)
          element.blur();
      });
    } else {
      element.addEventListener('blur', function() {
        isFocus = false;
      });
      element.addEventListener('click', function() {
        if (isFocus)
          return;
        isFocus = true;
        if (element.selectionStart === element.selectionEnd)
          element.select();
      });
    }

    var changeListener = function(event) {
      var cache = ctrl.searchKeyword();
      var value = event.target.value;

      if (value === cache)
        return;

      ctrl.dispatchEvent({
        type: 'searchkeywordchange',
        value: value
      });
    };
    element.addEventListener('change', changeListener);
    element.addEventListener('input', changeListener);
  };

  var pieceListConfig = function(element, isInitialized) {
    if (isInitialized)
      return;

    var ctrl = this;

    var isHeld;
    var draggingNode;
    var cloneOffset;
    var isFirstDrag;
    var isAutoClose;
    var cloneNode;

    var start = function() {
      var pieceListContent = element.children[0];

      cloneOffset = {
        left: draggingNode.offsetLeft - pieceListContent.scrollLeft,
        top: draggingNode.offsetTop - pieceListContent.scrollTop
      };

      isFirstDrag = true;
      isAutoClose = false;

      draggingNode.style.opacity = 0.6;

      dom.removeKeyboardFocus();

      cloneNode = draggingNode.cloneNode(true);
      dom.addClass(cloneNode, 'drag');
      document.body.appendChild(cloneNode);
    };

    dom.pointerEvent('.piece-list-item-container', {
      onstart: function(event) {
        isHeld = !dom.supportsTouch();
        draggingNode = event.target;
        if (!dom.supportsTouch())
          start();
      },
      onhold: function() {
        isHeld = true;
        if (dom.supportsTouch())
          start();
      },
      ondrag: function(event, dx, dy) {
        if (!isHeld)
          return;

        event.preventDefault();
        event.stopPropagation();

        if (isFirstDrag) {
          isFirstDrag = false;

          if (window.innerWidth < 358) {
            isAutoClose = true;
            ctrl.dispatchEvent({type: 'close'});
          }

          cloneNode.style.left = cloneOffset.left + 'px';
          cloneNode.style.top = cloneOffset.top + 'px';
        }

        dom.translate(cloneNode, dx, dy);
      },
      ondragend: function(event, dx, dy) {
        if (!isHeld)
          return;

        var pageX = cloneOffset.left + dx;
        var pageY = cloneOffset.top + dy;
        var dragEndEvent = {
          type: 'dragend',
          pageX: pageX,
          pageY: pageY,
          pieceSrc: cloneNode.getAttribute('data-piece-src'),
          pieceLabel: cloneNode.children[0].textContent
        };
        ctrl.dispatchEvent(dragEndEvent);
      },
      onend: function() {
        if (!isHeld)
          return;

        draggingNode.style.cssText = '';
        document.body.removeChild(cloneNode);

        if (isAutoClose)
          ctrl.dispatchEvent({type: 'open'});
      }
    });
  };

  var dividerIconConfig = function(element, isInitialized) {
    if (isInitialized)
      return;

    var ctrl = this;

    dom.pointerEvent('#divider_icon', {
      ontap: function() {
        ctrl.dispatchEvent({type: 'toggle'});
        dom.setCursor('default');
        dom.removeClass(element, 'tap');
      },
      onstart: function(event) {
        event.preventDefault();
        dom.addClass(element, 'tap');
        dom.removeKeyboardFocus();
        dom.setCursor('pointer');
      },
      onout: function() {
        dom.removeClass(element, 'tap');
        dom.setCursor('default');
      },
      onover: function() {
        dom.addClass(element, 'tap');
        dom.setCursor('pointer');
      }
    });
  };

  if (typeof module !== 'undefined' && module.exports)
    module.exports = sidePanelView;
  else
    app.sidePanelView = sidePanelView;
})(this.app || (this.app = {}));<|endoftext|>