<commit_before>import React from 'react';
import {storiesOf} from '@storybook/react';

import {Entry, RootProviders} from 'pageflow-scrolled/frontend';
import {MotifAreaVisibilityProvider} from '../MotifAreaVisibilityProvider';

import {
  normalizeAndMergeFixture,
  filePermaId,
  exampleHeading,
  exampleTextBlock
} from 'pageflow-scrolled/spec/support/stories';

let transitions = ['fade', 'fadeBg', 'scroll', 'scrollOver', 'reveal', 'beforeAfter'];

const enterTransitions = {
  fade: 'fadeIn',
  fadeBg: 'fadeInBg',
  scroll: 'scrollIn',
  scrollOver: 'scrollIn',
  reveal: 'reveal',
  beforeAfter: 'reveal'
};

const exitTransitions = {
  fade: 'fadeOut',
  fadeBg: 'fadeOutBg',
  scroll: 'ScrollOut',
  scrollOver: 'Conceal',
  reveal: 'ScrollOut',
  beforeAfter: 'Conceal'
};

const motifAreas = {
  'top-left': {
    left: 5,
    top: 5,
    width: 50,
    height: 25
  },
  'bottom-left': {
    left: 5,
    top: 70,
    width: 50,
    height: 25
  },
  'top-right': {
    left: 60,
    top: 5,
    width: 25,
    height: 25
  },
  'bottom-right': {
    left: 60,
    top: 70,
    width: 25,
    height: 25
  }
};

[true, false].forEach(fullHeight =>
  [true, false].forEach(withContent => {
    const prefix = [
      'Frontend/Motif Area',
      fullHeight ? 'Full Height' : 'Dynamic Height',
      withContent ? 'With Content' : 'No Content'
    ].join('/');

    const stories = {}

    transitions.forEach(transition1 =>
      transitions.forEach(transition2 => {
        if (fullHeight || (!transition1.startsWith('fade') && !transition2.startsWith('fade'))) {
          ['top-left', 'bottom-left', 'top-right', 'bottom-right'].forEach(motifAreaPosition => {
            const key = `${enterTransitions[transition1]}${exitTransitions[transition2]}`;

            stories[key] = stories[key] || storiesOf(
              `${prefix}/${enterTransitions[transition1]} - ${exitTransitions[transition2]}`,
              module
            )

            const seed = exampleSeed({
              transition1,
              transition2,
              fullHeight,
              textBlocks: withContent ? 1 : 0,
              motifArea: motifAreas[motifAreaPosition],
              title: `${transition1}/${transition2}/${motifAreaPosition}`
            });

            stories[key].add(
              `${transition1}/${transition2}/${motifAreaPosition}`,
              () =>
                <RootProviders seed={seed}>
                  <MotifAreaVisibilityProvider visible={true}>
                    <Entry />
                  </MotifAreaVisibilityProvider>
                </RootProviders>,
              {
                percy: {skip: true}
              }
            );
          });
        }
      })
    );
  })
);

function exampleSeed({transition1, transition2, motifArea, fullHeight, title, textBlocks}) {
  return normalizeAndMergeFixture({
    sections: [
      {
        id: 1,
        configuration: {
          transition: 'scroll',
          backdrop: {
            image: filePermaId('imageFiles', 'turtle')
          },
          fullHeight: true
        }
      },
      {
        id: 2,
        configuration: {
          transition: transition1,
          backdrop: {
            image: filePermaId('imageFiles', 'churchBefore'),
            imageMotifArea: motifArea
          },
          fullHeight
        }
      },
      {
        id: 3,
        configuration: {
          transition: transition2,
          backdrop: {
            image: filePermaId('imageFiles', 'churchAfter')
          },
          fullHeight: true
        }
      },
    ],
    contentElements: [
      exampleHeading({sectionId: 1, text: title}),
      exampleTextBlock({
        sectionId: 1,
        text: 'See docs/internal/understanding_motif_area_handling.md for details'
      }),
      ...(Array(textBlocks).fill().map(() => exampleTextBlock({sectionId: 2}))),
      exampleTextBlock({sectionId: 3}),
    ]
  })
}
<commit_msg>Expose motif area in motif area stories<commit_after>import React from 'react';
import {storiesOf} from '@storybook/react';

import {Entry, RootProviders} from 'pageflow-scrolled/frontend';
import {MotifAreaVisibilityProvider} from '../MotifAreaVisibilityProvider';

import {
  normalizeAndMergeFixture,
  filePermaId,
  exampleHeading,
  exampleTextBlock
} from 'pageflow-scrolled/spec/support/stories';

let transitions = ['fade', 'fadeBg', 'scroll', 'scrollOver', 'reveal', 'beforeAfter'];

const enterTransitions = {
  fade: 'fadeIn',
  fadeBg: 'fadeInBg',
  scroll: 'scrollIn',
  scrollOver: 'scrollIn',
  reveal: 'reveal',
  beforeAfter: 'reveal'
};

const exitTransitions = {
  fade: 'fadeOut',
  fadeBg: 'fadeOutBg',
  scroll: 'ScrollOut',
  scrollOver: 'Conceal',
  reveal: 'ScrollOut',
  beforeAfter: 'Conceal'
};

const motifAreas = {
  'top-left': {
    left: 5,
    top: 5,
    width: 50,
    height: 25
  },
  'bottom-left': {
    left: 5,
    top: 70,
    width: 50,
    height: 25
  },
  'top-right': {
    left: 60,
    top: 5,
    width: 25,
    height: 25
  },
  'bottom-right': {
    left: 60,
    top: 70,
    width: 25,
    height: 25
  }
};

[true, false].forEach(fullHeight =>
  [true, false].forEach(withContent => {
    const prefix = [
      'Frontend/Motif Area',
      fullHeight ? 'Full Height' : 'Dynamic Height',
      withContent ? 'With Content' : 'No Content'
    ].join('/');

    const stories = {}

    transitions.forEach(transition1 =>
      transitions.forEach(transition2 => {
        if (fullHeight || (!transition1.startsWith('fade') && !transition2.startsWith('fade'))) {
          ['top-left', 'bottom-left', 'top-right', 'bottom-right'].forEach(motifAreaPosition => {
            const key = `${enterTransitions[transition1]}${exitTransitions[transition2]}`;

            stories[key] = stories[key] || storiesOf(
              `${prefix}/${enterTransitions[transition1]} - ${exitTransitions[transition2]}`,
              module
            )

            const seed = exampleSeed({
              transition1,
              transition2,
              fullHeight,
              textBlocks: withContent ? 1 : 0,
              motifArea: motifAreas[motifAreaPosition],
              title: `${transition1}/${transition2}/${motifAreaPosition}`
            });

            stories[key].add(
              `${transition1}/${transition2}/${motifAreaPosition}`,
              () =>
                <RootProviders seed={seed}>
                  <MotifAreaVisibilityProvider visible={true}>
                    <Entry />
                  </MotifAreaVisibilityProvider>
                </RootProviders>,
              {
                percy: {skip: true}
              }
            );
          });
        }
      })
    );
  })
);

function exampleSeed({transition1, transition2, motifArea, fullHeight, title, textBlocks}) {
  return normalizeAndMergeFixture({
    sections: [
      {
        id: 1,
        configuration: {
          transition: 'scroll',
          backdrop: {
            image: filePermaId('imageFiles', 'turtle')
          },
          fullHeight: true
        }
      },
      {
        id: 2,
        configuration: {
          transition: transition1,
          backdrop: {
            image: filePermaId('imageFiles', 'churchBefore'),
            imageMotifArea: motifArea
          },
          fullHeight,
          exposeMotifArea: true
        }
      },
      {
        id: 3,
        configuration: {
          transition: transition2,
          backdrop: {
            image: filePermaId('imageFiles', 'churchAfter')
          },
          fullHeight: true
        }
      },
    ],
    contentElements: [
      exampleHeading({sectionId: 1, text: title}),
      exampleTextBlock({
        sectionId: 1,
        text: 'See docs/internal/understanding_motif_area_handling.md for details'
      }),
      ...(Array(textBlocks).fill().map(() => exampleTextBlock({sectionId: 2}))),
      exampleTextBlock({sectionId: 3}),
    ]
  })
}
<|endoftext|>


<commit_before>// Load in modules
var assert = require('assert'),
    fs = require('fs'),
    path = require('path'),
    _ = require('underscore'),
    spritesmith = require('../src/smith.js');

// Set up paths
var spriteDir = path.join(__dirname, 'test_sprites'),
    expectedDir = __dirname + '/expected_files';

// DEV: These were unsorted for testing `sort: false` but these work for all tests as is =D
var multipleSprites = [
  path.join(spriteDir, 'sprite1.png'),
  path.join(spriteDir, 'sprite3.png'),
  path.join(spriteDir, 'sprite2.jpg')
];

// Define common utilities
var spritesmithUtils = {
  process: function (params) {
    before(function processViaSpritesmithFn (done) {
      // Require and save namespace for later
      this.namespace = params.namespace;
      assert(this.namespace, '`params.namespace` was not defined for `spritesmithUtils.process`, please define it');

      // Load in params and add on to src
      var options = params.options || {},
          spritesmithParams = _.extend({'src': params.sprites}, options);

      // Attempt to spritesmith out the sprites
      var that = this;
      spritesmith(spritesmithParams, function saveResult (err, result) {
        // Save the result and callback
        that.result = result;
        done(err);
      });
    });
    after(function cleanupResult () {
      delete this.namespace;
      delete this.result;
    });
  },

  assertCoordinates: function () {
    // Load in the coordinates
    var result = this.result,
        expectedCoords = require(expectedDir + '/' + this.namespace + '.coordinates.json');

    // Normalize the actual coordinates
    var actualCoords = result.coordinates,
        normCoords = {};
    assert(actualCoords, "Result does not have a coordinates property");

    Object.getOwnPropertyNames(actualCoords).forEach(function (filepath) {
      var file = path.relative(spriteDir, filepath);
      normCoords[file] = actualCoords[filepath];
    });

    // Assert that the returned coordinates deep equal those in the coordinates.json
    assert.deepEqual(expectedCoords, normCoords, "Actual coordinates do not match expected coordinates");
  },

  assertProps: function() {
    // Load in the properties
    var actualProps = this.result.properties,
        expectedProps = require(expectedDir + '/' + this.namespace + '.properties.json');

    // Assert that the returned properties equals the expected properties
    assert.deepEqual(expectedProps, actualProps, "Actual properties do not match expected properties");
  },

  assertSpritesheet: function () {
    var result = this.result,
        namespace = this.namespace;

    // DEV: Write out to actual_files
    if (process.env.TEST_DEBUG) {
      try { fs.mkdirSync(__dirname + '/actual_files'); } catch (e) {}
      fs.writeFileSync(__dirname + '/actual_files/' + namespace + '.sprite.png', result.image, 'binary');
      fs.writeFileSync(__dirname + '/actual_files/' + namespace + '.sprite.jpg', result.image, 'binary');
      fs.writeFileSync(__dirname + '/actual_files/' + namespace + '.coordinates.json', JSON.stringify(result.coordinates, null, 4));
      fs.writeFileSync(__dirname + '/actual_files/' + namespace + '.properties.json', JSON.stringify(result.properties, null, 4));
    }

    // Assert the actual image is the same expected
    var actualImage = result.image,
        expectedFilenames = ['canvas.png', 'gm.png', 'gm2.png', 'phantomjs.png', 'phantomjs2.png'],
        matchesAnImage = false;

    // ANTI-PATTERN: Looping over set without identifiable lines for stack traces
    expectedFilenames.forEach(function testAgainstExpected (filename) {
      if (!matchesAnImage) {
        var filepath = path.join(expectedDir, namespace + '.' + filename);
        if (fs.existsSync(filepath)) {
          var expectedImage = fs.readFileSync(filepath, 'binary');
          matchesAnImage = actualImage === expectedImage;
        }
      }
    });

    assert(matchesAnImage, "Actual image does not match expected image");
  }
};

describe('An array of sprites', function () {
  describe('when processed via spritesmith', function () {
    spritesmithUtils.process({
      namespace: 'topDown',
      sprites: multipleSprites
    });

    it('renders a top-down spritesheet', spritesmithUtils.assertSpritesheet);
    it('has the proper coordinates', spritesmithUtils.assertCoordinates);
    it('has the proper properties', spritesmithUtils.assertProps);
  });

  describe('when converted from left to right', function () {
    spritesmithUtils.process({
      'namespace': 'leftRight',
      'sprites': multipleSprites,
      'options': {
        'algorithm': 'left-right'
      }
    });

    it('renders a left-right spritesheet', spritesmithUtils.assertSpritesheet);
    it('has the proper coordinates', spritesmithUtils.assertCoordinates);
    it('has the proper properties', spritesmithUtils.assertProps);
  });

  describe('when provided with a padding parameter', function () {
    spritesmithUtils.process({
      'namespace': 'padding',
      'sprites': multipleSprites,
      'options': {
        'algorithm': 'binary-tree',
        'padding': 2
      }
    });

    it('renders a padded spritesheet', spritesmithUtils.assertSpritesheet);
    it('has the proper coordinates', spritesmithUtils.assertCoordinates);
    it('has the proper properties', spritesmithUtils.assertProps);
  });

  describe('when told not to sort', function () {
    spritesmithUtils.process({
      'namespace': 'unsorted',
      'sprites': multipleSprites,
      'options': {
        'algorithm': 'top-down',
        'algorithmOpts': {'sort': false}
      }
    });

    it('renders an unsorted spritesheet', spritesmithUtils.assertSpritesheet);
    it('has the proper coordinates', spritesmithUtils.assertCoordinates);
    it('has the proper properties', spritesmithUtils.assertProps);
  });
});

describe('An empty array', function () {
  var emptySprites = [];

  describe('when processed via spritesmith', function () {
    spritesmithUtils.process({
      'namespace': 'empty',
      'sprites': emptySprites
    });

    it('renders an empty spritesheet', function () {
      assert.strictEqual(this.result.image, '');
    });
    it('returns an empty coordinate mapping', function () {
      assert.deepEqual(this.result.coordinates, {});
    });
    it('has the proper properties', spritesmithUtils.assertProps);
  });
});

function addEngineTest(params) {
  // Attempt to load the engine
  try {
    require(params.module);
  } catch (e) {}

  // Create an engine-specific test
  describe(params.engineName , function () {
    describe('when processed via spritesmith', function () {
      spritesmithUtils.process({
        // Use engine as namespace (e.g. `phantomjs`)
        'namespace': params.engineName,
        'sprites': multipleSprites,
        'options': {
          'engine': params.engineName
        }
      });

      it('returns an image', function () {
        // DEV: Write out to actual_files
        if (process.env.TEST_DEBUG) {
          try { fs.mkdirSync(__dirname + '/actual_files'); } catch (e) {}
          fs.writeFileSync(__dirname + '/actual_files/' + this.namespace + '.sprite.png', this.result.image, 'binary');
        }

        assert.notEqual(this.result.image, '');
      });
    });
  });
}

// Test specific engines
addEngineTest({
  engineName: 'phantomjs',
  module: 'phantomjssmith'
});
addEngineTest({
  engineName: 'gm',
  module: 'gmsmith'
});
addEngineTest({
  engineName: 'canvas',
  module: 'canvassmith'
});
<commit_msg>Moved to single quotes for consistency<commit_after>// Load in modules
var assert = require('assert'),
    fs = require('fs'),
    path = require('path'),
    _ = require('underscore'),
    spritesmith = require('../src/smith.js');

// Set up paths
var spriteDir = path.join(__dirname, 'test_sprites'),
    expectedDir = __dirname + '/expected_files';

// DEV: These were unsorted for testing `sort: false` but these work for all tests as is =D
var multipleSprites = [
  path.join(spriteDir, 'sprite1.png'),
  path.join(spriteDir, 'sprite3.png'),
  path.join(spriteDir, 'sprite2.jpg')
];

// Define common utilities
var spritesmithUtils = {
  process: function (params) {
    before(function processViaSpritesmithFn (done) {
      // Require and save namespace for later
      this.namespace = params.namespace;
      assert(this.namespace, '`params.namespace` was not defined for `spritesmithUtils.process`, please define it');

      // Load in params and add on to src
      var options = params.options || {},
          spritesmithParams = _.extend({'src': params.sprites}, options);

      // Attempt to spritesmith out the sprites
      var that = this;
      spritesmith(spritesmithParams, function saveResult (err, result) {
        // Save the result and callback
        that.result = result;
        done(err);
      });
    });
    after(function cleanupResult () {
      delete this.namespace;
      delete this.result;
    });
  },

  assertCoordinates: function () {
    // Load in the coordinates
    var result = this.result,
        expectedCoords = require(expectedDir + '/' + this.namespace + '.coordinates.json');

    // Normalize the actual coordinates
    var actualCoords = result.coordinates,
        normCoords = {};
    assert(actualCoords, 'Result does not have a coordinates property');

    Object.getOwnPropertyNames(actualCoords).forEach(function (filepath) {
      var file = path.relative(spriteDir, filepath);
      normCoords[file] = actualCoords[filepath];
    });

    // Assert that the returned coordinates deep equal those in the coordinates.json
    assert.deepEqual(expectedCoords, normCoords, 'Actual coordinates do not match expected coordinates');
  },

  assertProps: function() {
    // Load in the properties
    var actualProps = this.result.properties,
        expectedProps = require(expectedDir + '/' + this.namespace + '.properties.json');

    // Assert that the returned properties equals the expected properties
    assert.deepEqual(expectedProps, actualProps, 'Actual properties do not match expected properties');
  },

  assertSpritesheet: function () {
    var result = this.result,
        namespace = this.namespace;

    // DEV: Write out to actual_files
    if (process.env.TEST_DEBUG) {
      try { fs.mkdirSync(__dirname + '/actual_files'); } catch (e) {}
      fs.writeFileSync(__dirname + '/actual_files/' + namespace + '.sprite.png', result.image, 'binary');
      fs.writeFileSync(__dirname + '/actual_files/' + namespace + '.sprite.jpg', result.image, 'binary');
      fs.writeFileSync(__dirname + '/actual_files/' + namespace + '.coordinates.json', JSON.stringify(result.coordinates, null, 4));
      fs.writeFileSync(__dirname + '/actual_files/' + namespace + '.properties.json', JSON.stringify(result.properties, null, 4));
    }

    // Assert the actual image is the same expected
    var actualImage = result.image,
        expectedFilenames = ['canvas.png', 'gm.png', 'gm2.png', 'phantomjs.png', 'phantomjs2.png'],
        matchesAnImage = false;

    // ANTI-PATTERN: Looping over set without identifiable lines for stack traces
    expectedFilenames.forEach(function testAgainstExpected (filename) {
      if (!matchesAnImage) {
        var filepath = path.join(expectedDir, namespace + '.' + filename);
        if (fs.existsSync(filepath)) {
          var expectedImage = fs.readFileSync(filepath, 'binary');
          matchesAnImage = actualImage === expectedImage;
        }
      }
    });

    assert(matchesAnImage, 'Actual image does not match expected image');
  }
};

describe('An array of sprites', function () {
  describe('when processed via spritesmith', function () {
    spritesmithUtils.process({
      namespace: 'topDown',
      sprites: multipleSprites
    });

    it('renders a top-down spritesheet', spritesmithUtils.assertSpritesheet);
    it('has the proper coordinates', spritesmithUtils.assertCoordinates);
    it('has the proper properties', spritesmithUtils.assertProps);
  });

  describe('when converted from left to right', function () {
    spritesmithUtils.process({
      'namespace': 'leftRight',
      'sprites': multipleSprites,
      'options': {
        'algorithm': 'left-right'
      }
    });

    it('renders a left-right spritesheet', spritesmithUtils.assertSpritesheet);
    it('has the proper coordinates', spritesmithUtils.assertCoordinates);
    it('has the proper properties', spritesmithUtils.assertProps);
  });

  describe('when provided with a padding parameter', function () {
    spritesmithUtils.process({
      'namespace': 'padding',
      'sprites': multipleSprites,
      'options': {
        'algorithm': 'binary-tree',
        'padding': 2
      }
    });

    it('renders a padded spritesheet', spritesmithUtils.assertSpritesheet);
    it('has the proper coordinates', spritesmithUtils.assertCoordinates);
    it('has the proper properties', spritesmithUtils.assertProps);
  });

  describe('when told not to sort', function () {
    spritesmithUtils.process({
      'namespace': 'unsorted',
      'sprites': multipleSprites,
      'options': {
        'algorithm': 'top-down',
        'algorithmOpts': {'sort': false}
      }
    });

    it('renders an unsorted spritesheet', spritesmithUtils.assertSpritesheet);
    it('has the proper coordinates', spritesmithUtils.assertCoordinates);
    it('has the proper properties', spritesmithUtils.assertProps);
  });
});

describe('An empty array', function () {
  var emptySprites = [];

  describe('when processed via spritesmith', function () {
    spritesmithUtils.process({
      'namespace': 'empty',
      'sprites': emptySprites
    });

    it('renders an empty spritesheet', function () {
      assert.strictEqual(this.result.image, '');
    });
    it('returns an empty coordinate mapping', function () {
      assert.deepEqual(this.result.coordinates, {});
    });
    it('has the proper properties', spritesmithUtils.assertProps);
  });
});

function addEngineTest(params) {
  // Attempt to load the engine
  try {
    require(params.module);
  } catch (e) {}

  // Create an engine-specific test
  describe(params.engineName , function () {
    describe('when processed via spritesmith', function () {
      spritesmithUtils.process({
        // Use engine as namespace (e.g. `phantomjs`)
        'namespace': params.engineName,
        'sprites': multipleSprites,
        'options': {
          'engine': params.engineName
        }
      });

      it('returns an image', function () {
        // DEV: Write out to actual_files
        if (process.env.TEST_DEBUG) {
          try { fs.mkdirSync(__dirname + '/actual_files'); } catch (e) {}
          fs.writeFileSync(__dirname + '/actual_files/' + this.namespace + '.sprite.png', this.result.image, 'binary');
        }

        assert.notEqual(this.result.image, '');
      });
    });
  });
}

// Test specific engines
addEngineTest({
  engineName: 'phantomjs',
  module: 'phantomjssmith'
});
addEngineTest({
  engineName: 'gm',
  module: 'gmsmith'
});
addEngineTest({
  engineName: 'canvas',
  module: 'canvassmith'
});
<|endoftext|>


<commit_before>
/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */
var _ = require('lodash');
var bows = require('bows');
var React = require('react');
var ReactDOM = require('react-dom');
var sundial = require('sundial');

// tideline dependencies & plugins
var tidelineBlip = require('tideline/plugins/blip');
var chartWeeklyFactory = tidelineBlip.twoweek;

var vizComponents = require('@tidepool/viz').components;
var Loader = vizComponents.Loader;

var Header = require('./header');
var Footer = require('./footer');

var tideline = {
  log: bows('Two Weeks')
};

var WeeklyChart = React.createClass({
  chartOpts: ['bgClasses', 'bgUnits', 'timePrefs'],
  log: bows('Weekly Chart'),
  propTypes: {
    bgClasses: React.PropTypes.object.isRequired,
    bgUnits: React.PropTypes.string.isRequired,
    initialDatetimeLocation: React.PropTypes.string,
    patient: React.PropTypes.object,
    patientData: React.PropTypes.object.isRequired,
    timePrefs: React.PropTypes.object.isRequired,
    // handlers
    onDatetimeLocationChange: React.PropTypes.func.isRequired,
    onMostRecent: React.PropTypes.func.isRequired,
    onClickValues: React.PropTypes.func.isRequired,
    onSelectSMBG: React.PropTypes.func.isRequired,
    onTransition: React.PropTypes.func.isRequired,
    isClinicAccount: React.PropTypes.bool.isRequired,
  },

  mount: function() {
    this.mountChart(ReactDOM.findDOMNode(this));
    this.initializeChart(this.props.patientData, this.props.initialDatetimeLocation);
  },

  componentWillUnmount: function() {
    this.unmountChart();
  },

  mountChart: function(node, chartOpts) {
    this.log('Mounting...');
    chartOpts = chartOpts || {};
    this.chart = chartWeeklyFactory(node, _.assign(chartOpts, _.pick(this.props, this.chartOpts)));
    this.chart.node = node;
    this.bindEvents();
  },

  unmountChart: function() {
    this.log('Unmounting...');
    this.chart.destroy();
  },

  rerenderChart: function() {
    this.log('Rerendering...');
    this.unmountChart();
    this.mount();
  },

  bindEvents: function() {
    this.chart.emitter.on('inTransition', this.props.onTransition);
    this.chart.emitter.on('navigated', this.handleDatetimeLocationChange);
    this.chart.emitter.on('mostRecent', this.props.onMostRecent);
    this.chart.emitter.on('selectSMBG', this.props.onSelectSMBG);
  },

  initializeChart: function(data, datetimeLocation) {
    this.log('Initializing...');
    if (_.isEmpty(data)) {
      throw new Error('Cannot create new chart with no data');
    }

    if (datetimeLocation) {
      this.chart.load(data, datetimeLocation);
    }
    else {
      this.chart.load(data);
    }
    if (this.props.isClinicAccount){
      this.chart.showValues();
    }
  },

  render: function() {
    /* jshint ignore:start */
    return (

      );
    /* jshint ignore:end */
  },

  // handlers
  handleDatetimeLocationChange: function(datetimeLocationEndpoints) {
    this.setState({
      datetimeLocation: datetimeLocationEndpoints[1]
    });
    this.props.onDatetimeLocationChange(datetimeLocationEndpoints);
  },

  getCurrentDay: function(timePrefs) {
    return this.chart.getCurrentDay(timePrefs).toISOString();
  },

  goToMostRecent: function() {
    this.chart.clear();
    this.bindEvents();
    this.chart.load(this.props.patientData);
  },

  hideValues: function() {
    this.chart.hideValues();
  },

  panBack: function() {
    this.chart.panBack();
  },

  panForward: function() {
    this.chart.panForward();
  },

  showValues: function() {
    this.chart.showValues();
  }
});

var Weekly = React.createClass({
  chartType: 'weekly',
  log: bows('Weekly View'),
  propTypes: {
    bgPrefs: React.PropTypes.object.isRequired,
    chartPrefs: React.PropTypes.object.isRequired,
    initialDatetimeLocation: React.PropTypes.string,
    isClinicAccount: React.PropTypes.bool.isRequired,
    onClickRefresh: React.PropTypes.func.isRequired,
    onClickNoDataRefresh: React.PropTypes.func.isRequired,
    onSwitchToBasics: React.PropTypes.func.isRequired,
    onSwitchToDaily: React.PropTypes.func.isRequired,
    onSwitchToSettings: React.PropTypes.func.isRequired,
    onSwitchToWeekly: React.PropTypes.func.isRequired,
    onUpdateChartDateRange: React.PropTypes.func.isRequired,
    patientData: React.PropTypes.object.isRequired,
    loading: React.PropTypes.bool.isRequired,
    timePrefs: React.PropTypes.object.isRequired,
    trackMetric: React.PropTypes.func.isRequired,
    updateDatetimeLocation: React.PropTypes.func.isRequired,
    uploadUrl: React.PropTypes.string.isRequired,
  },

  getInitialState: function() {
    return {
      atMostRecent: false,
      inTransition: false,
      showingValues: this.props.isClinicAccount,
      title: ''
    };
  },

  componentDidMount:function () {
    if (this.refs.chart) {
      this.refs.chart.mount();
    }
  },

  componentWillReceiveProps:function (nextProps) {
    console.log('this.props.loading', this.props.loading);
    console.log('nextProps.loading', nextProps.loading);

    if (this.props.loading && !nextProps.loading) {
      this.refs.chart.rerenderChart();
    }
  },

  render: function() {
    return (

        {this.isMissingSMBG() ? this.renderMissingSMBGHeader() : this.renderHeader()}

              <Loader show={this.props.loading} overlay={true} />
              {this.isMissingSMBG() ? this.renderMissingSMBGMessage() : this.renderChart()}

    );
  },

  renderChart: function() {
    return (
      <WeeklyChart
        bgClasses={this.props.bgPrefs.bgClasses}
        bgUnits={this.props.bgPrefs.bgUnits}
        initialDatetimeLocation={this.props.initialDatetimeLocation}
        patientData={this.props.patientData}
        timePrefs={this.props.timePrefs}
        // handlers
        onDatetimeLocationChange={this.handleDatetimeLocationChange}
        onMostRecent={this.handleMostRecent}
        onClickValues={this.toggleValues}
        onSelectSMBG={this.handleSelectSMBG}
        onTransition={this.handleInTransition}
        ref="chart"
        isClinicAccount={this.props.isClinicAccount} />
    );
  },

  renderHeader: function() {
    return (
      <Header
        chartType={this.chartType}
        patient={this.props.patient}
        atMostRecent={this.state.atMostRecent}
        inTransition={this.state.inTransition}
        title={this.state.title}
        iconBack={'icon-back-down'}
        iconNext={'icon-next-up'}
        iconMostRecent={'icon-most-recent-up'}
        onClickBack={this.handlePanBack}
        onClickBasics={this.props.onSwitchToBasics}
        onClickTrends={this.handleClickTrends}
        onClickMostRecent={this.handleClickMostRecent}
        onClickNext={this.handlePanForward}
        onClickOneDay={this.handleClickOneDay}
        onClickSettings={this.props.onSwitchToSettings}
        onClickTwoWeeks={this.handleClickTwoWeeks}
      ref="header" />
    );
  },

  renderMissingSMBGHeader: function() {
    return (

    );
  },

  renderMissingSMBGMessage: function() {
    var self = this;
    var handleClickUpload = function() {
      self.props.trackMetric('Clicked Partial Data Upload, No SMBG');
    };

    return (

{'The Weekly view shows a history of your finger stick BG data, but it looks like you haven\'t uploaded finger stick data yet.'}

{'To see your data in the Weekly view, '}
          upload
          {' your pump or BG meter.'}

{'If you just uploaded, try '}
          refreshing
          {'.'}

    );
  },

  formatDate: function(datetime) {
    // even when timezoneAware, labels should be generated as if UTC; just trust me (JEB)
    return sundial.formatInTimezone(datetime, 'UTC', 'MMM D, YYYY');
  },

  getTitle: function(datetimeLocationEndpoints) {
    return this.formatDate(datetimeLocationEndpoints[0]) + ' - ' + this.formatDate(datetimeLocationEndpoints[1]);
  },

  isMissingSMBG: function() {
    var data = this.props.patientData;
    if (_.isEmpty(data.grouped.smbg)) {
      return true;
    }
    return false;
  },

  // handlers
  handleClickTrends: function(e) {
    if(e) {
      e.preventDefault();
    }
    var datetime;
    if (this.refs.chart) {
      datetime = this.refs.chart.getCurrentDay(this.props.timePrefs);
    }
    this.props.onSwitchToTrends(datetime);
  },

  handleClickMostRecent: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.setState({showingValues: false});
    this.refs.chart.goToMostRecent();
  },

  handleClickOneDay: function(e) {
    if (e) {
      e.preventDefault();
    }
    var datetime;
    if (this.refs.chart) {
      datetime = this.refs.chart.getCurrentDay(this.props.timePrefs);
    }
    this.props.onSwitchToDaily(datetime);
  },

  handleClickTwoWeeks: function(e) {
    if (e) {
      e.preventDefault();
    }
    return;
  },

  handleDatetimeLocationChange: function(datetimeLocationEndpoints) {
    this.setState({
      datetimeLocation: datetimeLocationEndpoints[1],
      title: this.getTitle(datetimeLocationEndpoints)
    });
    this.props.updateDatetimeLocation(this.refs.chart.getCurrentDay());

    if (this.state.debouncedDateRangeUpdate) {
      this.state.debouncedDateRangeUpdate.cancel();
    }

    // Update the chart date range in the patientData component
    const debouncedDateRangeUpdate = _.debounce(this.props.onUpdateChartDateRange, 250);
    debouncedDateRangeUpdate(datetimeLocationEndpoints, this.refs.chart);
    this.setState({ debouncedDateRangeUpdate });
  },

  handleInTransition: function(inTransition) {
    this.setState({
      inTransition: inTransition
    });
  },

  handleMostRecent: function(atMostRecent) {
    this.setState({
      atMostRecent: atMostRecent
    });
  },

  handlePanBack: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.refs.chart.panBack();
  },

  handlePanForward: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.refs.chart.panForward();
  },

  handleSelectSMBG: function(datetime) {
    this.props.onSwitchToDaily(datetime);
  },

  toggleValues: function(e) {
    if (this.state.showingValues) {
      this.props.trackMetric('Clicked Show Values Off');
      this.refs.chart.hideValues();
    }
    else {
      this.props.trackMetric('Clicked Show Values On');
      this.refs.chart.showValues();
    }
    this.setState({showingValues: !this.state.showingValues});
  }
});

module.exports = Weekly;
<commit_msg>removing a debugging console log<commit_after>
/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */
var _ = require('lodash');
var bows = require('bows');
var React = require('react');
var ReactDOM = require('react-dom');
var sundial = require('sundial');

// tideline dependencies & plugins
var tidelineBlip = require('tideline/plugins/blip');
var chartWeeklyFactory = tidelineBlip.twoweek;

var vizComponents = require('@tidepool/viz').components;
var Loader = vizComponents.Loader;

var Header = require('./header');
var Footer = require('./footer');

var tideline = {
  log: bows('Two Weeks')
};

var WeeklyChart = React.createClass({
  chartOpts: ['bgClasses', 'bgUnits', 'timePrefs'],
  log: bows('Weekly Chart'),
  propTypes: {
    bgClasses: React.PropTypes.object.isRequired,
    bgUnits: React.PropTypes.string.isRequired,
    initialDatetimeLocation: React.PropTypes.string,
    patient: React.PropTypes.object,
    patientData: React.PropTypes.object.isRequired,
    timePrefs: React.PropTypes.object.isRequired,
    // handlers
    onDatetimeLocationChange: React.PropTypes.func.isRequired,
    onMostRecent: React.PropTypes.func.isRequired,
    onClickValues: React.PropTypes.func.isRequired,
    onSelectSMBG: React.PropTypes.func.isRequired,
    onTransition: React.PropTypes.func.isRequired,
    isClinicAccount: React.PropTypes.bool.isRequired,
  },

  mount: function() {
    this.mountChart(ReactDOM.findDOMNode(this));
    this.initializeChart(this.props.patientData, this.props.initialDatetimeLocation);
  },

  componentWillUnmount: function() {
    this.unmountChart();
  },

  mountChart: function(node, chartOpts) {
    this.log('Mounting...');
    chartOpts = chartOpts || {};
    this.chart = chartWeeklyFactory(node, _.assign(chartOpts, _.pick(this.props, this.chartOpts)));
    this.chart.node = node;
    this.bindEvents();
  },

  unmountChart: function() {
    this.log('Unmounting...');
    this.chart.destroy();
  },

  rerenderChart: function() {
    this.log('Rerendering...');
    this.unmountChart();
    this.mount();
  },

  bindEvents: function() {
    this.chart.emitter.on('inTransition', this.props.onTransition);
    this.chart.emitter.on('navigated', this.handleDatetimeLocationChange);
    this.chart.emitter.on('mostRecent', this.props.onMostRecent);
    this.chart.emitter.on('selectSMBG', this.props.onSelectSMBG);
  },

  initializeChart: function(data, datetimeLocation) {
    this.log('Initializing...');
    if (_.isEmpty(data)) {
      throw new Error('Cannot create new chart with no data');
    }

    if (datetimeLocation) {
      this.chart.load(data, datetimeLocation);
    }
    else {
      this.chart.load(data);
    }
    if (this.props.isClinicAccount){
      this.chart.showValues();
    }
  },

  render: function() {
    /* jshint ignore:start */
    return (

      );
    /* jshint ignore:end */
  },

  // handlers
  handleDatetimeLocationChange: function(datetimeLocationEndpoints) {
    this.setState({
      datetimeLocation: datetimeLocationEndpoints[1]
    });
    this.props.onDatetimeLocationChange(datetimeLocationEndpoints);
  },

  getCurrentDay: function(timePrefs) {
    return this.chart.getCurrentDay(timePrefs).toISOString();
  },

  goToMostRecent: function() {
    this.chart.clear();
    this.bindEvents();
    this.chart.load(this.props.patientData);
  },

  hideValues: function() {
    this.chart.hideValues();
  },

  panBack: function() {
    this.chart.panBack();
  },

  panForward: function() {
    this.chart.panForward();
  },

  showValues: function() {
    this.chart.showValues();
  }
});

var Weekly = React.createClass({
  chartType: 'weekly',
  log: bows('Weekly View'),
  propTypes: {
    bgPrefs: React.PropTypes.object.isRequired,
    chartPrefs: React.PropTypes.object.isRequired,
    initialDatetimeLocation: React.PropTypes.string,
    isClinicAccount: React.PropTypes.bool.isRequired,
    onClickRefresh: React.PropTypes.func.isRequired,
    onClickNoDataRefresh: React.PropTypes.func.isRequired,
    onSwitchToBasics: React.PropTypes.func.isRequired,
    onSwitchToDaily: React.PropTypes.func.isRequired,
    onSwitchToSettings: React.PropTypes.func.isRequired,
    onSwitchToWeekly: React.PropTypes.func.isRequired,
    onUpdateChartDateRange: React.PropTypes.func.isRequired,
    patientData: React.PropTypes.object.isRequired,
    loading: React.PropTypes.bool.isRequired,
    timePrefs: React.PropTypes.object.isRequired,
    trackMetric: React.PropTypes.func.isRequired,
    updateDatetimeLocation: React.PropTypes.func.isRequired,
    uploadUrl: React.PropTypes.string.isRequired,
  },

  getInitialState: function() {
    return {
      atMostRecent: false,
      inTransition: false,
      showingValues: this.props.isClinicAccount,
      title: ''
    };
  },

  componentDidMount:function () {
    if (this.refs.chart) {
      this.refs.chart.mount();
    }
  },

  componentWillReceiveProps:function (nextProps) {
    if (this.props.loading && !nextProps.loading) {
      this.refs.chart.rerenderChart();
    }
  },

  render: function() {
    return (

        {this.isMissingSMBG() ? this.renderMissingSMBGHeader() : this.renderHeader()}

              <Loader show={this.props.loading} overlay={true} />
              {this.isMissingSMBG() ? this.renderMissingSMBGMessage() : this.renderChart()}

    );
  },

  renderChart: function() {
    return (
      <WeeklyChart
        bgClasses={this.props.bgPrefs.bgClasses}
        bgUnits={this.props.bgPrefs.bgUnits}
        initialDatetimeLocation={this.props.initialDatetimeLocation}
        patientData={this.props.patientData}
        timePrefs={this.props.timePrefs}
        // handlers
        onDatetimeLocationChange={this.handleDatetimeLocationChange}
        onMostRecent={this.handleMostRecent}
        onClickValues={this.toggleValues}
        onSelectSMBG={this.handleSelectSMBG}
        onTransition={this.handleInTransition}
        ref="chart"
        isClinicAccount={this.props.isClinicAccount} />
    );
  },

  renderHeader: function() {
    return (
      <Header
        chartType={this.chartType}
        patient={this.props.patient}
        atMostRecent={this.state.atMostRecent}
        inTransition={this.state.inTransition}
        title={this.state.title}
        iconBack={'icon-back-down'}
        iconNext={'icon-next-up'}
        iconMostRecent={'icon-most-recent-up'}
        onClickBack={this.handlePanBack}
        onClickBasics={this.props.onSwitchToBasics}
        onClickTrends={this.handleClickTrends}
        onClickMostRecent={this.handleClickMostRecent}
        onClickNext={this.handlePanForward}
        onClickOneDay={this.handleClickOneDay}
        onClickSettings={this.props.onSwitchToSettings}
        onClickTwoWeeks={this.handleClickTwoWeeks}
      ref="header" />
    );
  },

  renderMissingSMBGHeader: function() {
    return (

    );
  },

  renderMissingSMBGMessage: function() {
    var self = this;
    var handleClickUpload = function() {
      self.props.trackMetric('Clicked Partial Data Upload, No SMBG');
    };

    return (

{'The Weekly view shows a history of your finger stick BG data, but it looks like you haven\'t uploaded finger stick data yet.'}

{'To see your data in the Weekly view, '}
          upload
          {' your pump or BG meter.'}

{'If you just uploaded, try '}
          refreshing
          {'.'}

    );
  },

  formatDate: function(datetime) {
    // even when timezoneAware, labels should be generated as if UTC; just trust me (JEB)
    return sundial.formatInTimezone(datetime, 'UTC', 'MMM D, YYYY');
  },

  getTitle: function(datetimeLocationEndpoints) {
    return this.formatDate(datetimeLocationEndpoints[0]) + ' - ' + this.formatDate(datetimeLocationEndpoints[1]);
  },

  isMissingSMBG: function() {
    var data = this.props.patientData;
    if (_.isEmpty(data.grouped.smbg)) {
      return true;
    }
    return false;
  },

  // handlers
  handleClickTrends: function(e) {
    if(e) {
      e.preventDefault();
    }
    var datetime;
    if (this.refs.chart) {
      datetime = this.refs.chart.getCurrentDay(this.props.timePrefs);
    }
    this.props.onSwitchToTrends(datetime);
  },

  handleClickMostRecent: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.setState({showingValues: false});
    this.refs.chart.goToMostRecent();
  },

  handleClickOneDay: function(e) {
    if (e) {
      e.preventDefault();
    }
    var datetime;
    if (this.refs.chart) {
      datetime = this.refs.chart.getCurrentDay(this.props.timePrefs);
    }
    this.props.onSwitchToDaily(datetime);
  },

  handleClickTwoWeeks: function(e) {
    if (e) {
      e.preventDefault();
    }
    return;
  },

  handleDatetimeLocationChange: function(datetimeLocationEndpoints) {
    this.setState({
      datetimeLocation: datetimeLocationEndpoints[1],
      title: this.getTitle(datetimeLocationEndpoints)
    });
    this.props.updateDatetimeLocation(this.refs.chart.getCurrentDay());

    if (this.state.debouncedDateRangeUpdate) {
      this.state.debouncedDateRangeUpdate.cancel();
    }

    // Update the chart date range in the patientData component
    const debouncedDateRangeUpdate = _.debounce(this.props.onUpdateChartDateRange, 250);
    debouncedDateRangeUpdate(datetimeLocationEndpoints, this.refs.chart);
    this.setState({ debouncedDateRangeUpdate });
  },

  handleInTransition: function(inTransition) {
    this.setState({
      inTransition: inTransition
    });
  },

  handleMostRecent: function(atMostRecent) {
    this.setState({
      atMostRecent: atMostRecent
    });
  },

  handlePanBack: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.refs.chart.panBack();
  },

  handlePanForward: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.refs.chart.panForward();
  },

  handleSelectSMBG: function(datetime) {
    this.props.onSwitchToDaily(datetime);
  },

  toggleValues: function(e) {
    if (this.state.showingValues) {
      this.props.trackMetric('Clicked Show Values Off');
      this.refs.chart.hideValues();
    }
    else {
      this.props.trackMetric('Clicked Show Values On');
      this.refs.chart.showValues();
    }
    this.setState({showingValues: !this.state.showingValues});
  }
});

module.exports = Weekly;
<|endoftext|>


<commit_before>/*function jquerytest(){
  var ww = $(window).width();
  if(ww<0){
    alert("This window is impossibly small");
  }else{
    alert("This is a jquery test.  Would you like your " + ww + " pixel window washed?");
  }
  return ww;
};

*/
var logo = $('.site-avatar');
var info = $('.site-info');
var info_h1 = $('.site-info h1');
var nav = $('nav');
function tw(){
/*	  TweenMax.to(nav, 2.3, {
		display:'block',
		position:'relative',
		'z-index':4,
		float:'left',
		ease: Power0.easeNone
		})*/
	//use the defaults
	TweenLite.to(info_h1, 1, {scrambleText:"THIS IS NEW TEXT"});

}
$('.site-info').click( function() {

  tw();
});
<commit_msg>Update jquerytest.js<commit_after>/*function jquerytest(){
  var ww = $(window).width();
  if(ww<0){
    alert("This window is impossibly small");
  }else{
    alert("This is a jquery test.  Would you like your " + ww + " pixel window washed?");
  }
  return ww;
};

*/
var logo = $('.site-avatar');
var info = $('.site-info');
var info_h1 = $('.site-info h1');
var nav = $('nav');
function tw(){
	  TweenMax.to(".entry", 2.3, {

		textAlign: 'center',
		ease: Power0.easeNone
		})

}
$('.site-info').click( function() {

  tw();
});
<|endoftext|>


<commit_before>(function() {

    var Slider = function(options) {
        Backbone.View.call(this, options);
        this.sliderInitialize(options);
    };

    // Add the Slider to the kuba-bootstrap global namespace
    var root = this;
    root.kb = root.kb || {};
    root.kb.Slider = Slider;

    // Sniff touch events that indicate a mobile device
    var isMobile = 'ontouchend' in root;
    var downEvent = (isMobile) ? 'touchstart ' : 'mousedown ',
        moveEvent = (isMobile) ? 'touchmove ' : 'mousemove ',
        upEvent = (isMobile) ? 'touchend ' : 'mouseup ';

    Slider.extend = Backbone.View.extend;

    _.extend(Slider.prototype, Backbone.View.prototype, {
        // TODO Allow prefixes to be configured with an option
        // A blank prefix results in "transform" and is used by modern IE
        _prefixes: ['', '-webkit-', '-moz-'],
        sliderInitialize: function(options) {
            // Set sane options
            var o = this.options;
            // Element dimensions
            // Width and height are set dynamically in resetItems
            // But these options allow manual override
            this._width = _.isNumber(o.width) ? o.width : undefined;
            this._height = _.isNumber(o.height) ? o.height : undefined;

            this._paddingX = _.isNumber(o.paddingX) ? o.paddingX : 25;
            this._paddingY = _.isNumber(o.paddingY) ? o.paddingY : 50;
            this._force = _.isNumber(o.force) ? o.force : 4;
            this._threshold = _.isNumber(o.threshold) ? o.threshold : 5;

            // View and Collection
            // TODO confirm that these are backbone view / collection types
            this.collection || (this.collection = new Backbone.Collection());
            this.view = o.view || Backbone.View;

            // Inject the className
            // TODO This will overwrite any existing className, don't do this!
            // this.view.prototype.className = 'ease-box-double';

            // The lock will be set true when the slider is being moved
            this.lock = false;

            // Save the rendered view objects from each model
            this._views = [];

            // Default to a single row
            this._single = _.isBoolean(o.single) ? o.single : true;

            // Initialize private variables for scrolling
            this._pointerX = 0;
            this._pointerY = 0;
            this._scrollSurfacePos = 0;
            this._rightLimit = 0;

            // Render
            this.render();

            // Render the elements in the collection with the given view
            this.resetItems();

            // Check for any changes in viewport width
            // TODO on window?

            // Listen for 'add', 'remove' and 'reset' events in the collection
            // TODO 'reset' changed in backbone 1.0.0 to the smarter set()
            this.listenTo(this.collection, 'add', this.addItem);
            // TODO The remove event should be more specific than a reset
            this.listenTo(this.collection, 'remove', this.resetItems);
            this.listenTo(this.collection, 'reset', this.resetItems);
            // Also listen to sort events
            this.listenTo(this.collection, 'sort', this.resetItems);
        },
        sliderTemplate: '

',
        render: function() {
            // Render the inner slider
            this.$el.html(this.sliderTemplate);
            this.$scrollSurface = this.$('.con-slide-d');
            return this;
        },
        // TODO Combine functionality with resetItems / positionItems
        addItem: function(item) {
            // Allow child views to inspect parent properties (such as lock)
            var view = new this.view({model: item, parent: this});
            this._views.push(view);
            this.$scrollSurface.append(view.render().el);

            // TODO A better way to find index?
            var index = this.collection.length ? this.collection.indexOf(item) : 0;

            // If index is zero, reset the pointers
            if (index == 0) {
                this._pointerX = 0;
                this._pointerY = 1;
            }

            this.calculatePosition(view.$el, index);
        },
        resetItems: function() {
            // Reset existing items
            this.$scrollSurface.html('');
            this._views = [];
            this._rightLimit = 0;

            // Render all elements with the given view
            this.collection.models.reverse();

            _.each(this.collection.models, function(m) {
                var view = new this.view({model: m, parent: this});
                // TODO better way to tie a model and its view together?
                this._views.push(view);
                this.$scrollSurface.append(view.render().el);
            }, this);

            // Determine the width and height of a box
            // Items must be the same size!
            if (this.options.width && this.options.height) {
                this._width = this.options.width;
                this._height = this.options.height;
            } else if (this._views.length) {
                this._width = this._views[0].$el.outerWidth();
                this._height = this._views[0].$el.outerHeight();
            }
            // TODO Error if neither are set

            // Also set the scroll surface position to 0 to prevent a smaller
            // number of items from being locked into position off-screen
            this.$scrollSurface.addClass('fx');
            this.moveScrollSurface(0);

            this.positionItems();

            // Enable events, only needs to be called once
            this.bindEvents();
        },
        positionItems: function() {
            // Reset variables
            this._columns = 0;

            // The _views array is populated by the resetItems function
            var len = this.collection.length;
            if (len) {
                this._pointerX = 0;
                this._pointerY = 1;
                _.each(this._views, function(view, index) {
                    this.calculatePosition(view.$el, index);
                }, this);
            }

            // Change positioning depending on number of rows
            // TODO columns does nothing
            if (!this._single) {
                this._columns = ((len - (len % 2)) / 2) + (len % 5);
            } else {
                this._columns = len;
            }
        },
        // TODO Allow click events to bubble up (either based on time
        // between mouse/touch up and down or deltaX == 0)
        bindEvents: function() {
            // Disable the slider events to prevent duplicate binds
            this.$el.off(downEvent + ' ' + upEvent);

            // Event variables, enclosed during assignment
            var initialX, viewport;
            var startX = 0;
            var currentX = 0;
            var deltaX = 0;
            var boxPos = 0;
            var self = this;

            // TODO Different handlers for mobile / desktop
            self.$el.on(downEvent, function(e) {
                startX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX;
                initialX = startX;

                // Remove the lock
                self.lock = false;

                // Prevent native text selection
                e.preventDefault();

                // Disallow slide if the viewport is wider than the elements
                viewport = self.$el.width();
                if (viewport > self._rightLimit) {
                    // TODO messages should be DEBUG only
                    // console.log('Viewport is wider than items, slider disabled');
                } else {
                    self.$el.on(moveEvent, function(e) {
                        currentX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX;
                        boxPos = 0;

                        deltaX = currentX - startX;
                        startX += deltaX;
                        boxPos = deltaX + self._scrollSurfacePos;

                        // Once the slider moves a threshold number of pixels,
                        // add a lock that child views can inspect
                        if (!self.lock) {
                            var diffX = currentX - initialX;
                            if (Math.abs(diffX) > self._threshold) self.lock = true;
                        }

                        // The function must be called with the View as context
                        self.$scrollSurface.removeClass('fx');
                        self.moveScrollSurface.call(self, boxPos);

                        // TODO The usage of boxPos seems overly complicated
                        self._scrollSurfacePos = boxPos;
                    });
                }

            // TODO Should also be called when mouse leaves frame
            }).on(upEvent, function(e) {
                // TODO Hard-coded threshold for movement
                // Only move if deltaX is greater than a specified threshold
                if (Math.abs(deltaX) > 3) {
                    boxPos = (deltaX * self._force) + self._scrollSurfacePos;
                }

                // If the content is smaller than the width of the viewport,
                // anchor the content to the left of the viewport
                if (viewport > self._rightLimit) {
                    boxPos = 0;
                } else {
                    var overflowWidth = self._rightLimit - viewport;
                    // If the viewport is to the left of the boxes, return the
                    // left edge of the viewport to the start of the boxes
                    if (boxPos > 0) {
                        boxPos = 0;
                    // If the viewport is to the right of the boxes, return
                    // the right edge of the viewport to the end of the boxes
                    } else if (boxPos < -overflowWidth) {
                        boxPos = -overflowWidth;
                    }
                }

                // The function must be called with the View as context
                self.$scrollSurface.addClass('fx');
                self.moveScrollSurface.call(self, boxPos);

                self._scrollSurfacePos = boxPos;

                // TODO Should be reset on mouse/touch down, not up?
                deltaX = 0;
                startX = 0;

                // Remove the move event handler
                self.$el.off(moveEvent);

                // Remove the slider "lock" after a tiny delay
                // setTimeout(function() { self.lock = false; });
            });
        },
        moveLeft: function(x) {
            var boxPos = this._scrollSurfacePos - x,
                viewport = this.$el.width();

            // If the content is smaller than the width of the viewport,
            // anchor the content to the left of the viewport
            if (viewport > this._rightLimit) {
                boxPos = 0;
            } else {
                var overflowWidth = this._rightLimit - viewport;
                // If the viewport is to the left of the boxes, return the
                // left edge of the viewport to the start of the boxes

                if (boxPos > 0) {
                    boxPos = 0;
                // If the viewport is to the right of the boxes, return
                // the right edge of the viewport to the end of the boxes
                } else if (boxPos < -overflowWidth) {
                    boxPos = -overflowWidth;
                }
            }

            this.moveScrollSurface.call(this, boxPos);
            this._scrollSurfacePos = boxPos;
        },
        moveRight: function(x) {
            var boxPos = this._scrollSurfacePos + x,
                viewport = this.$el.width();

            // If the content is smaller than the width of the viewport,
            // anchor the content to the left of the viewport
            if (viewport > this._rightLimit) {
                boxPos = 0;
            } else {
                var overflowWidth = this._rightLimit - viewport;
                // If the viewport is to the left of the boxes, return the
                // left edge of the viewport to the start of the boxes
                if (boxPos > 0) {
                    boxPos = 0;
                // If the viewport is to the right of the boxes, return
                // the right edge of the viewport to the end of the boxes
                } else if (boxPos < -overflowWidth) {
                    boxPos = -overflowWidth;
                }
            }

            this.moveScrollSurface.call(this, boxPos);
            this._scrollSurfacePos = boxPos;
        },
        moveScrollSurface: function(x) {
            // Create the cross-platform CSS transform
            // TODO Use CSS sniffing to reduce prefixes
            var transform = 'translate3d(' + x + 'px, 0px, 0px)';
            var styles = {};
            _.each(this._prefixes, function(prefix) {
                styles[prefix + 'transform'] = transform;
            });
            this.$scrollSurface.css(styles);
        },
        calculatePosition: function(box, index) {
            var pos = {};
            // TODO rem is block group?
            var rem = index % 1;

            // TODO Re-calculate for 'n' rows and integrate with _columns
            if (!this._single) {
                if (rem === 0){
                    if (this._pointerY == 0){
                        this._pointerY = 1;
                        this._pointerX = this._pointerX - 1;
                    } else {
                        this._pointerY = 0;
                    }
                }
            } else {
                this._pointerY = 0;
            }

            pos.x = (this._width * this._pointerX) + (this._paddingX * this._pointerX) + this._paddingX;
            pos.y = (this._paddingY + this._height) * this._pointerY;
            var rightEdge = pos.x + this._width + this._paddingX;
            // Save the x-coord of the right edge for the element farthest
            // to the right. This will be used for force / viewport focus.
            if (rightEdge > this._rightLimit) this._rightLimit = rightEdge;

            // Create the cross-platform CSS transform for box positioning
            var transform = 'translate3d(' + pos.x + 'px, ' + pos.y + 'px, 0px)';
            var styles = {};
            _.each(this._prefixes, function(prefix) {
                styles[prefix + 'transform'] = transform;
            });

            box.css(styles);

            this._pointerX++;
            return this;
        }
    });

    window.Slider = Slider;

}).call(this);
<commit_msg>reverse collection<commit_after>(function() {

    var Slider = function(options) {
        Backbone.View.call(this, options);
        this.sliderInitialize(options);
    };

    // Add the Slider to the kuba-bootstrap global namespace
    var root = this;
    root.kb = root.kb || {};
    root.kb.Slider = Slider;

    // Sniff touch events that indicate a mobile device
    var isMobile = 'ontouchend' in root;
    var downEvent = (isMobile) ? 'touchstart ' : 'mousedown ',
        moveEvent = (isMobile) ? 'touchmove ' : 'mousemove ',
        upEvent = (isMobile) ? 'touchend ' : 'mouseup ';

    Slider.extend = Backbone.View.extend;

    _.extend(Slider.prototype, Backbone.View.prototype, {
        // TODO Allow prefixes to be configured with an option
        // A blank prefix results in "transform" and is used by modern IE
        _prefixes: ['', '-webkit-', '-moz-'],
        sliderInitialize: function(options) {
            // Set sane options
            var o = this.options;
            // Element dimensions
            // Width and height are set dynamically in resetItems
            // But these options allow manual override
            this._width = _.isNumber(o.width) ? o.width : undefined;
            this._height = _.isNumber(o.height) ? o.height : undefined;

            this._paddingX = _.isNumber(o.paddingX) ? o.paddingX : 25;
            this._paddingY = _.isNumber(o.paddingY) ? o.paddingY : 50;
            this._force = _.isNumber(o.force) ? o.force : 4;
            this._threshold = _.isNumber(o.threshold) ? o.threshold : 5;

            // View and Collection
            // TODO confirm that these are backbone view / collection types
            this.collection || (this.collection = new Backbone.Collection());
            this.view = o.view || Backbone.View;

            // Inject the className
            // TODO This will overwrite any existing className, don't do this!
            // this.view.prototype.className = 'ease-box-double';

            // The lock will be set true when the slider is being moved
            this.lock = false;

            // Save the rendered view objects from each model
            this._views = [];

            // Default to a single row
            this._single = _.isBoolean(o.single) ? o.single : true;

            // Initialize private variables for scrolling
            this._pointerX = 0;
            this._pointerY = 0;
            this._scrollSurfacePos = 0;
            this._rightLimit = 0;

            // Render
            this.render();

            // Render the elements in the collection with the given view
            this.resetItems();

            // Check for any changes in viewport width
            // TODO on window?

            // Listen for 'add', 'remove' and 'reset' events in the collection
            // TODO 'reset' changed in backbone 1.0.0 to the smarter set()
            this.listenTo(this.collection, 'add', this.addItem);
            // TODO The remove event should be more specific than a reset
            this.listenTo(this.collection, 'remove', this.resetItems);
            this.listenTo(this.collection, 'reset', this.resetItems);
            // Also listen to sort events
            this.listenTo(this.collection, 'sort', this.resetItems);
        },
        sliderTemplate: '

',
        render: function() {
            // Render the inner slider
            this.$el.html(this.sliderTemplate);
            this.$scrollSurface = this.$('.con-slide-d');
            return this;
        },
        // TODO Combine functionality with resetItems / positionItems
        addItem: function(item) {
            // Allow child views to inspect parent properties (such as lock)
            var view = new this.view({model: item, parent: this});
            this._views.push(view);
            this.$scrollSurface.prepend(view.render().el);

            // TODO A better way to find index?
            var index = this.collection.length ? this.collection.indexOf(item) : 0;

            // If index is zero, reset the pointers
            if (index == 0) {
                this._pointerX = 0;
                this._pointerY = 1;
            }

            this.calculatePosition(view.$el, index);
        },
        resetItems: function() {
            // Reset existing items
            this.$scrollSurface.html('');
            this._views = [];
            this._rightLimit = 0;

            // Render all elements with the given view
            this.collection.models.reverse();

            _.each(this.collection.models, function(m) {
                var view = new this.view({model: m, parent: this});
                // TODO better way to tie a model and its view together?
                this._views.push(view);
                this.$scrollSurface.append(view.render().el);
            }, this);

            // Determine the width and height of a box
            // Items must be the same size!
            if (this.options.width && this.options.height) {
                this._width = this.options.width;
                this._height = this.options.height;
            } else if (this._views.length) {
                this._width = this._views[0].$el.outerWidth();
                this._height = this._views[0].$el.outerHeight();
            }
            // TODO Error if neither are set

            // Also set the scroll surface position to 0 to prevent a smaller
            // number of items from being locked into position off-screen
            this.$scrollSurface.addClass('fx');
            this.moveScrollSurface(0);

            this.positionItems();

            // Enable events, only needs to be called once
            this.bindEvents();
        },
        positionItems: function() {
            // Reset variables
            this._columns = 0;

            // The _views array is populated by the resetItems function
            var len = this.collection.length;
            if (len) {
                this._pointerX = 0;
                this._pointerY = 1;
                _.each(this._views, function(view, index) {
                    this.calculatePosition(view.$el, index);
                }, this);
            }

            // Change positioning depending on number of rows
            // TODO columns does nothing
            if (!this._single) {
                this._columns = ((len - (len % 2)) / 2) + (len % 5);
            } else {
                this._columns = len;
            }
        },
        // TODO Allow click events to bubble up (either based on time
        // between mouse/touch up and down or deltaX == 0)
        bindEvents: function() {
            // Disable the slider events to prevent duplicate binds
            this.$el.off(downEvent + ' ' + upEvent);

            // Event variables, enclosed during assignment
            var initialX, viewport;
            var startX = 0;
            var currentX = 0;
            var deltaX = 0;
            var boxPos = 0;
            var self = this;

            // TODO Different handlers for mobile / desktop
            self.$el.on(downEvent, function(e) {
                startX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX;
                initialX = startX;

                // Remove the lock
                self.lock = false;

                // Prevent native text selection
                e.preventDefault();

                // Disallow slide if the viewport is wider than the elements
                viewport = self.$el.width();
                if (viewport > self._rightLimit) {
                    // TODO messages should be DEBUG only
                    // console.log('Viewport is wider than items, slider disabled');
                } else {
                    self.$el.on(moveEvent, function(e) {
                        currentX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX;
                        boxPos = 0;

                        deltaX = currentX - startX;
                        startX += deltaX;
                        boxPos = deltaX + self._scrollSurfacePos;

                        // Once the slider moves a threshold number of pixels,
                        // add a lock that child views can inspect
                        if (!self.lock) {
                            var diffX = currentX - initialX;
                            if (Math.abs(diffX) > self._threshold) self.lock = true;
                        }

                        // The function must be called with the View as context
                        self.$scrollSurface.removeClass('fx');
                        self.moveScrollSurface.call(self, boxPos);

                        // TODO The usage of boxPos seems overly complicated
                        self._scrollSurfacePos = boxPos;
                    });
                }

            // TODO Should also be called when mouse leaves frame
            }).on(upEvent, function(e) {
                // TODO Hard-coded threshold for movement
                // Only move if deltaX is greater than a specified threshold
                if (Math.abs(deltaX) > 3) {
                    boxPos = (deltaX * self._force) + self._scrollSurfacePos;
                }

                // If the content is smaller than the width of the viewport,
                // anchor the content to the left of the viewport
                if (viewport > self._rightLimit) {
                    boxPos = 0;
                } else {
                    var overflowWidth = self._rightLimit - viewport;
                    // If the viewport is to the left of the boxes, return the
                    // left edge of the viewport to the start of the boxes
                    if (boxPos > 0) {
                        boxPos = 0;
                    // If the viewport is to the right of the boxes, return
                    // the right edge of the viewport to the end of the boxes
                    } else if (boxPos < -overflowWidth) {
                        boxPos = -overflowWidth;
                    }
                }

                // The function must be called with the View as context
                self.$scrollSurface.addClass('fx');
                self.moveScrollSurface.call(self, boxPos);

                self._scrollSurfacePos = boxPos;

                // TODO Should be reset on mouse/touch down, not up?
                deltaX = 0;
                startX = 0;

                // Remove the move event handler
                self.$el.off(moveEvent);

                // Remove the slider "lock" after a tiny delay
                // setTimeout(function() { self.lock = false; });
            });
        },
        moveLeft: function(x) {
            var boxPos = this._scrollSurfacePos - x,
                viewport = this.$el.width();

            // If the content is smaller than the width of the viewport,
            // anchor the content to the left of the viewport
            if (viewport > this._rightLimit) {
                boxPos = 0;
            } else {
                var overflowWidth = this._rightLimit - viewport;
                // If the viewport is to the left of the boxes, return the
                // left edge of the viewport to the start of the boxes

                if (boxPos > 0) {
                    boxPos = 0;
                // If the viewport is to the right of the boxes, return
                // the right edge of the viewport to the end of the boxes
                } else if (boxPos < -overflowWidth) {
                    boxPos = -overflowWidth;
                }
            }

            this.moveScrollSurface.call(this, boxPos);
            this._scrollSurfacePos = boxPos;
        },
        moveRight: function(x) {
            var boxPos = this._scrollSurfacePos + x,
                viewport = this.$el.width();

            // If the content is smaller than the width of the viewport,
            // anchor the content to the left of the viewport
            if (viewport > this._rightLimit) {
                boxPos = 0;
            } else {
                var overflowWidth = this._rightLimit - viewport;
                // If the viewport is to the left of the boxes, return the
                // left edge of the viewport to the start of the boxes
                if (boxPos > 0) {
                    boxPos = 0;
                // If the viewport is to the right of the boxes, return
                // the right edge of the viewport to the end of the boxes
                } else if (boxPos < -overflowWidth) {
                    boxPos = -overflowWidth;
                }
            }

            this.moveScrollSurface.call(this, boxPos);
            this._scrollSurfacePos = boxPos;
        },
        moveScrollSurface: function(x) {
            // Create the cross-platform CSS transform
            // TODO Use CSS sniffing to reduce prefixes
            var transform = 'translate3d(' + x + 'px, 0px, 0px)';
            var styles = {};
            _.each(this._prefixes, function(prefix) {
                styles[prefix + 'transform'] = transform;
            });
            this.$scrollSurface.css(styles);
        },
        calculatePosition: function(box, index) {
            var pos = {};
            // TODO rem is block group?
            var rem = index % 1;

            // TODO Re-calculate for 'n' rows and integrate with _columns
            if (!this._single) {
                if (rem === 0){
                    if (this._pointerY == 0){
                        this._pointerY = 1;
                        this._pointerX = this._pointerX - 1;
                    } else {
                        this._pointerY = 0;
                    }
                }
            } else {
                this._pointerY = 0;
            }

            pos.x = (this._width * this._pointerX) + (this._paddingX * this._pointerX) + this._paddingX;
            pos.y = (this._paddingY + this._height) * this._pointerY;
            var rightEdge = pos.x + this._width + this._paddingX;
            // Save the x-coord of the right edge for the element farthest
            // to the right. This will be used for force / viewport focus.
            if (rightEdge > this._rightLimit) this._rightLimit = rightEdge;

            // Create the cross-platform CSS transform for box positioning
            var transform = 'translate3d(' + pos.x + 'px, ' + pos.y + 'px, 0px)';
            var styles = {};
            _.each(this._prefixes, function(prefix) {
                styles[prefix + 'transform'] = transform;
            });

            box.css(styles);

            this._pointerX++;
            return this;
        }
    });

    window.Slider = Slider;

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


<commit_before>import Ember from 'ember';
import ENV from 'irene/config/environment';
import ENUMS from 'irene/enums';
import { translationMacro as t } from 'ember-i18n';
import triggerAnalytics from 'irene/utils/trigger-analytics';
import poll from 'irene/services/poll';

export default Ember.Component.extend({
  tagName: "",
  apiScanModal: false,
  dynamicScanModal: false,

  i18n: Ember.inject.service(),
  trial: Ember.inject.service(),
  ajax: Ember.inject.service(),
  notify: Ember.inject.service('notification-messages-service'),
  poll: Ember.inject.service(),

  tStartingScan: t("startingScan"),

  didInsertElement() {
    this.send('pollDynamicStatus');
  },

  actions: {

    setAPIScanOption() {
      const tStartingScan = this.get("tStartingScan");
      const isApiScanEnabled = this.get("isApiScanEnabled");
      const data = {
        isApiScanEnabled: isApiScanEnabled === true
      };
      const file = this.get('file');
      const fileId = file.id;
      const dynamicUrl = [ENV.endpoints.dynamic, fileId].join('/');
      this.get("ajax").put(dynamicUrl, {data})
        .then(() => {
          this.get("notify").success(tStartingScan);
          if(!this.isDestroyed) {
            this.send('pollDynamicStatus');
            this.send("closeModal");
          }
        })
        .catch(function(error) {
          file.setNone();
          this.get("notify").error(error.payload.error);
        });
    },

    pollDynamicStatus() {
      const isDynamicReady = this.get('file.isReady');
      const fileId = this.get('file.id');
      if (isDynamicReady) {
        return;
      }
      if(!fileId) {
        return;
      }
      var stopPoll = poll(() => {
        return this.get('store').find('file', fileId)
        .then(() => {
          const dynamicStatus = this.get('file.dynamicStatus');
          if (dynamicStatus === ENUMS.DYNAMIC_STATUS.NONE || dynamicStatus === ENUMS.DYNAMIC_STATUS.READY) {
            stopPoll();
          }
        }, () => {
          stopPoll();
        });
      }, 5000);
    },

    doNotRunAPIScan() {
      triggerAnalytics('feature', ENV.csb.runDynamicScan);
      this.set("isApiScanEnabled", false);
      this.set("startingDynamicScan", true);
      this.send("setAPIScanOption");
    },

    runAPIScan() {
      triggerAnalytics('feature', ENV.csb.runAPIScan);
      this.set("startingDynamicScan", true);
      this.set("isApiScanEnabled", true);
      this.send("setAPIScanOption");
    },

    showURLFilter(param){
      this.set("showAPIURLFilterScanModal", true);
      if (param === 'api') {
        this.set("showAPIScanModal", false);
        this.set("apiScanModal", true);
        this.set("dynamicScanModal", false);
      }
      if (param === 'dynamic') {
        this.set("showRunDynamicScanModal", false);
        this.set("dynamicScanModal", true);
        this.set("apiScanModal", false);
      }
    },

    openAPIScanModal() {
      const platform = this.get("file.project.platform");
      if ([ENUMS.PLATFORM.ANDROID,ENUMS.PLATFORM.IOS].includes(platform)) { // TEMPIOSDYKEY
        this.set("showAPIScanModal", true);
      } else {
        this.send("doNotRunAPIScan");
      }
    },

    goBack() {
      this.set("showAPIURLFilterScanModal", false);
      if (this.get("apiScanModal")) {
        this.set("showAPIScanModal", true);
      }
      if (this.get("dynamicScanModal")) {
        this.set("showRunDynamicScanModal", true);
      }
    },

    closeModal() {
      this.set("showAPIScanModal", false);
      this.set("showAPIURLFilterScanModal", false);
      this.set("showRunDynamicScanModal", false);
    },

    openRunDynamicScanModal() {
      this.set("showRunDynamicScanModal", true);
    },

    closeRunDynamicScanModal() {
      this.set("showRunDynamicScanModal", false);
    },

    dynamicShutdown() {
      const file = this.get("file");
      file.setShuttingDown();
      this.set("isPoppedOut", false);
      const fileId = this.get("file.id");
      const dynamicUrl = [ENV.endpoints.dynamic, fileId].join('/');
      this.get("ajax").delete(dynamicUrl)
      .then(function() {
        if(!that.isDestroyed) {
          file.setNone();
        }
      }, (error) => {
        file.setNone();
        this.get("notify").error(error.payload.error);
      });
    },

  }
});
<commit_msg>fix: enable the button after successful request<commit_after>import Ember from 'ember';
import ENV from 'irene/config/environment';
import ENUMS from 'irene/enums';
import { translationMacro as t } from 'ember-i18n';
import triggerAnalytics from 'irene/utils/trigger-analytics';
import poll from 'irene/services/poll';

export default Ember.Component.extend({
  tagName: "",
  apiScanModal: false,
  dynamicScanModal: false,

  i18n: Ember.inject.service(),
  trial: Ember.inject.service(),
  ajax: Ember.inject.service(),
  notify: Ember.inject.service('notification-messages-service'),
  poll: Ember.inject.service(),

  tStartingScan: t("startingScan"),

  didInsertElement() {
    this.send('pollDynamicStatus');
  },

  actions: {

    setAPIScanOption() {
      const tStartingScan = this.get("tStartingScan");
      const isApiScanEnabled = this.get("isApiScanEnabled");
      const data = {
        isApiScanEnabled: isApiScanEnabled === true
      };
      const file = this.get('file');
      const fileId = file.id;
      const dynamicUrl = [ENV.endpoints.dynamic, fileId].join('/');
      this.get("ajax").put(dynamicUrl, {data})
        .then(() => {
          this.get("notify").success(tStartingScan);
          if(!this.isDestroyed) {
            this.send('pollDynamicStatus');
            this.send("closeModal");
            this.set("startingDynamicScan", true);
          }
        })
        .catch(function(error) {
          file.setNone();
          this.get("notify").error(error.payload.error);
        });
    },

    pollDynamicStatus() {
      const isDynamicReady = this.get('file.isReady');
      const fileId = this.get('file.id');
      if (isDynamicReady) {
        return;
      }
      if(!fileId) {
        return;
      }
      var stopPoll = poll(() => {
        return this.get('store').find('file', fileId)
        .then(() => {
          const dynamicStatus = this.get('file.dynamicStatus');
          if (dynamicStatus === ENUMS.DYNAMIC_STATUS.NONE || dynamicStatus === ENUMS.DYNAMIC_STATUS.READY) {
            stopPoll();
          }
        }, () => {
          stopPoll();
        });
      }, 5000);
    },

    doNotRunAPIScan() {
      triggerAnalytics('feature', ENV.csb.runDynamicScan);
      this.set("isApiScanEnabled", false);
      this.set("startingDynamicScan", true);
      this.send("setAPIScanOption");
    },

    runAPIScan() {
      triggerAnalytics('feature', ENV.csb.runAPIScan);
      this.set("startingDynamicScan", true);
      this.set("isApiScanEnabled", true);
      this.send("setAPIScanOption");
    },

    showURLFilter(param){
      this.set("showAPIURLFilterScanModal", true);
      if (param === 'api') {
        this.set("showAPIScanModal", false);
        this.set("apiScanModal", true);
        this.set("dynamicScanModal", false);
      }
      if (param === 'dynamic') {
        this.set("showRunDynamicScanModal", false);
        this.set("dynamicScanModal", true);
        this.set("apiScanModal", false);
      }
    },

    openAPIScanModal() {
      const platform = this.get("file.project.platform");
      if ([ENUMS.PLATFORM.ANDROID,ENUMS.PLATFORM.IOS].includes(platform)) { // TEMPIOSDYKEY
        this.set("showAPIScanModal", true);
      } else {
        this.send("doNotRunAPIScan");
      }
    },

    goBack() {
      this.set("showAPIURLFilterScanModal", false);
      if (this.get("apiScanModal")) {
        this.set("showAPIScanModal", true);
      }
      if (this.get("dynamicScanModal")) {
        this.set("showRunDynamicScanModal", true);
      }
    },

    closeModal() {
      this.set("showAPIScanModal", false);
      this.set("showAPIURLFilterScanModal", false);
      this.set("showRunDynamicScanModal", false);
    },

    openRunDynamicScanModal() {
      this.set("showRunDynamicScanModal", true);
    },

    closeRunDynamicScanModal() {
      this.set("showRunDynamicScanModal", false);
    },

    dynamicShutdown() {
      const file = this.get("file");
      file.setShuttingDown();
      this.set("isPoppedOut", false);
      const fileId = this.get("file.id");
      const dynamicUrl = [ENV.endpoints.dynamic, fileId].join('/');
      this.get("ajax").delete(dynamicUrl)
      .then(function() {
        if(!that.isDestroyed) {
          file.setNone();
        }
      }, (error) => {
        file.setNone();
        this.get("notify").error(error.payload.error);
      });
    },

  }
});
<|endoftext|>


<commit_before>/**
 * tracing_layout_view.js
 * @flow
 */

import React from "react";
import { Provider } from "react-redux";
import app from "app";
import Store from "oxalis/throttled_store";
import OxalisController from "oxalis/controller";
import SettingsView from "oxalis/view/settings/settings_view";
import ActionBarView from "oxalis/view/action_bar_view";
import RightMenuView from "oxalis/view/right_menu_view";
import TracingView from "oxalis/view/tracing_view";
import UserScriptsModal from "oxalis/view/user_scripts_modal";
import enUS from "antd/lib/locale-provider/en_US";
import { LocaleProvider, Layout, Button, Icon } from "antd";
import type { SkeletonTracingTypeTracingType } from "oxalis/store";
import type { ControlModeType } from "oxalis/constants";

const { Header, Sider } = Layout;

class TracingLayoutView extends React.PureComponent {
  props: {
    initialTracingType: SkeletonTracingTypeTracingType,
    initialTracingId: string,
    initialControlmode: ControlModeType,
  };

  state = {
    isSettingsCollapsed: true,
    isUserScriptsModalOpen: false,
  };

  componentDidMount() {
    const addScriptLink = document.getElementById("add-script-link");
    if (addScriptLink) {
      addScriptLink.classList.remove("hide");
      addScriptLink.addEventListener("click", () => this.showUserScriptsModal());
    }
  }

  componentWillUnmount() {
    window.app.oxalis = null;
  }

  showUserScriptsModal = () => {
    this.setState({
      isUserScriptsModalOpen: true,
    });
  };

  closeUserScriptsModal = () => {
    this.setState({
      isUserScriptsModalOpen: false,
    });
  };

  handleSettingsCollapse = () => {
    this.setState({
      isSettingsCollapsed: !this.state.isSettingsCollapsed,
    });
  };

  render() {
    return (
      <LocaleProvider locale={enUS}>
        <Provider store={Store}>

            <OxalisController
              initialTracingType={this.props.initialTracingType}
              initialTracingId={this.props.initialTracingId}
              initialControlmode={this.props.initialControlmode}
              ref={ref => {
                app.oxalis = ref;
              }}
            />

            <Layout className="tracing-layout">

                <Button
                  size="large"
                  onClick={this.handleSettingsCollapse}
                  style={{ float: "left", marginTop: "10px" }}
                >
                  <Icon type={this.state.isSettingsCollapsed ? "menu-unfold" : "menu-fold"} />
                  Settings
                </Button>
                <ActionBarView />

              <Layout>
                <Sider
                  collapsible
                  trigger={null}
                  collapsed={this.state.isSettingsCollapsed}
                  collapsedWidth={0}
                  width={350}
                  style={{ zIndex: 100 }}
                >
                  <SettingsView />
                </Sider>

                    <UserScriptsModal
                      visible={this.state.isUserScriptsModalOpen}
                      onClose={this.closeUserScriptsModal}
                    />
                    <TracingView />

                    <RightMenuView />

              </Layout>
            </Layout>

        </Provider>
      </LocaleProvider>
    );
  }
}

export default TracingLayoutView;
<commit_msg>make tracing view header fixed<commit_after>/**
 * tracing_layout_view.js
 * @flow
 */

import React from "react";
import { Provider } from "react-redux";
import app from "app";
import Store from "oxalis/throttled_store";
import OxalisController from "oxalis/controller";
import SettingsView from "oxalis/view/settings/settings_view";
import ActionBarView from "oxalis/view/action_bar_view";
import RightMenuView from "oxalis/view/right_menu_view";
import TracingView from "oxalis/view/tracing_view";
import UserScriptsModal from "oxalis/view/user_scripts_modal";
import enUS from "antd/lib/locale-provider/en_US";
import { LocaleProvider, Layout, Button, Icon } from "antd";
import type { SkeletonTracingTypeTracingType } from "oxalis/store";
import type { ControlModeType } from "oxalis/constants";

const { Header, Sider } = Layout;

class TracingLayoutView extends React.PureComponent {
  props: {
    initialTracingType: SkeletonTracingTypeTracingType,
    initialTracingId: string,
    initialControlmode: ControlModeType,
  };

  state = {
    isSettingsCollapsed: true,
    isUserScriptsModalOpen: false,
  };

  componentDidMount() {
    const addScriptLink = document.getElementById("add-script-link");
    if (addScriptLink) {
      addScriptLink.classList.remove("hide");
      addScriptLink.addEventListener("click", () => this.showUserScriptsModal());
    }
  }

  componentWillUnmount() {
    window.app.oxalis = null;
  }

  showUserScriptsModal = () => {
    this.setState({
      isUserScriptsModalOpen: true,
    });
  };

  closeUserScriptsModal = () => {
    this.setState({
      isUserScriptsModalOpen: false,
    });
  };

  handleSettingsCollapse = () => {
    this.setState({
      isSettingsCollapsed: !this.state.isSettingsCollapsed,
    });
  };

  render() {
    return (
      <LocaleProvider locale={enUS}>
        <Provider store={Store}>

            <OxalisController
              initialTracingType={this.props.initialTracingType}
              initialTracingId={this.props.initialTracingId}
              initialControlmode={this.props.initialControlmode}
              ref={ref => {
                app.oxalis = ref;
              }}
            />

            <Layout className="tracing-layout">

                <Button
                  size="large"
                  onClick={this.handleSettingsCollapse}
                  style={{ float: "left", marginTop: "10px" }}
                >
                  <Icon type={this.state.isSettingsCollapsed ? "menu-unfold" : "menu-fold"} />
                  Settings
                </Button>
                <ActionBarView />

              <Layout style={{ marginTop: 64 }}>
                <Sider
                  collapsible
                  trigger={null}
                  collapsed={this.state.isSettingsCollapsed}
                  collapsedWidth={0}
                  width={350}
                  style={{ zIndex: 100 }}
                >
                  <SettingsView />
                </Sider>

                    <UserScriptsModal
                      visible={this.state.isUserScriptsModalOpen}
                      onClose={this.closeUserScriptsModal}
                    />
                    <TracingView />

                    <RightMenuView />

              </Layout>
            </Layout>

        </Provider>
      </LocaleProvider>
    );
  }
}

export default TracingLayoutView;
<|endoftext|>


<commit_before>const gulp = require('gulp');
const $ = require('gulp-load-plugins')();
const path = require('path');

const setup = require('setup/setup');

module.exports = function() {
  const assets = setup.assets;

  const src = path.join(assets.dist, assets.dest.index);
  const dest = setup.root;

  const options = setup.plugins.gulpRobots;

  return gulp.src(src)
    .pipe($.robots(options))
    .pipe(gulp.dest(dest, {cwd: assets.build}));
};
<commit_msg>Fix task error<commit_after>const gulp = require('gulp');
const $ = require('gulp-load-plugins')();
const path = require('path');

const setup = require('setup/setup');

module.exports = function() {
  const assets = setup.assets;

  const src = path.join(assets.build, assets.dest.index);
  const dest = setup.root;

  const options = setup.plugins.gulpRobots;

  return gulp.src(src)
    .pipe($.robots(options))
    .pipe(gulp.dest(dest, {cwd: assets.build}));
};
<|endoftext|>


<commit_before>var loaders = require("./loaders");
var BrowserSyncPlugin = require('browser-sync-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpack = require('webpack');
module.exports = {
    entry: ['./src/index.ts'],
    output: {
        filename: 'build.js',
        path: 'dist'
    },
    resolve: {
        root: __dirname,
        extensions: ['', '.ts', '.js', '.json']
    },
    resolveLoader: {
        modulesDirectories: ["node_modules"]
    },
    devtool: "source-map",
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            inject: 'body',
            hash: true
        }),
        new BrowserSyncPlugin({
            host: 'localhost',
            port: 8080,
            server: {
                baseDir: 'dist'
            },
            ui: false,
            online: false,
            notify: false
        }),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            'window.jquery': 'jquery'
        })
    ],
    module:{
        loaders: loaders
    }
};<commit_msg>inline source maps to increase performance.<commit_after>var loaders = require("./loaders");
var BrowserSyncPlugin = require('browser-sync-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpack = require('webpack');
module.exports = {
    entry: ['./src/index.ts'],
    output: {
        filename: 'build.js',
        path: 'dist'
    },
    resolve: {
        root: __dirname,
        extensions: ['', '.ts', '.js', '.json']
    },
    resolveLoader: {
        modulesDirectories: ["node_modules"]
    },
    devtool: "inline-eval-cheap-source-map",
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            inject: 'body',
            hash: true
        }),
        new BrowserSyncPlugin({
            host: 'localhost',
            port: 8080,
            server: {
                baseDir: 'dist'
            },
            ui: false,
            online: false,
            notify: false
        }),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            'window.jquery': 'jquery'
        })
    ],
    module:{
        loaders: loaders
    }
};
<|endoftext|>