<commit_before>import FileSaver from 'file-saver';
import LZString from 'lz-string';
import applyPolyfills from './polyfills';
import initWebAudio from './initWebAudio';

// Shim drag and drop for mobile browsers
var iosDragDropShim = { enableEnterLeave: true };
require('drag-drop-webkit-mobile');

applyPolyfills();

const availableBlockClasses = {}; // maps block class id to block class
[
  'bigben',
  'convolux',
  'egen',
  'gainer',
  'orinami',
  'scope',
  'thumper',
  'waverly',
].forEach(n => {
  availableBlockClasses[n] = require('./blocks/' + n + '/block.js').default; // hacky for now
});

import createRacketWithBlocks from './blocks/racket';
const availableBlockClassesIncludingRacks = Object.assign({}, availableBlockClasses);
availableBlockClassesIncludingRacks['racket'] = createRacketWithBlocks(availableBlockClasses);

// Create a Web Audio context
const audioContext = initWebAudio(window);

let rootBlockClassId;
let rootBlockInst;

function loadRootBlock(blockClassId, settings) {
  // Unload any current root block
  if (rootBlockInst) {
    rootBlockInst.outputs.audio.node.disconnect(audioContext.destination);
    if (rootBlockInst.deactivate) {
      rootBlockInst.deactivate();
    }
    document.querySelector('#root-container').innerHTML = '';
  }

  rootBlockClassId = blockClassId;

  // Instantiate the root block, which will let the user dynamically instantiate
  //  and connect up other blocks.
  rootBlockInst = new (availableBlockClassesIncludingRacks[blockClassId])(document, audioContext, settings);

  // Mount the root block's window view
  // TODO: Handle case where windowView is undefined
  document.querySelector('#root-container').appendChild(rootBlockInst.windowView);

  // Connect root audio output to context final output
  rootBlockInst.outputs.audio.node.connect(audioContext.destination);
}

function loadEmptyRack() {
  loadRootBlock('racket', undefined);
}

const loadScreenElem = document.querySelector('#load-screen');
const loadScreenCloseButtonElem = document.querySelector('#load-screen-close-button');

const LOAD_SCREEN_FADE_TIME = 0.15;

function showLoadScreen() {
  if (rootBlockInst) {
    loadScreenCloseButtonElem.style.visibility = 'visible';
  } else {
    loadScreenCloseButtonElem.style.visibility = 'hidden';
  }

  loadScreenElem.style.transition = 'visibility 0s,opacity ' + LOAD_SCREEN_FADE_TIME + 's linear';
  loadScreenElem.style.visibility = 'visible';
  loadScreenElem.style.opacity = '1';
}

function hideLoadScreen() {
  loadScreenElem.style.transition = 'visibility 0s linear ' + LOAD_SCREEN_FADE_TIME + 's,opacity ' + LOAD_SCREEN_FADE_TIME + 's linear';
  loadScreenElem.style.visibility = 'hidden';
  loadScreenElem.style.opacity = '0';
}

loadScreenCloseButtonElem.addEventListener('click', e => {
  e.preventDefault();
  hideLoadScreen();
});

document.querySelector('#new-patch-button').addEventListener('click', e => {
  e.preventDefault();
  showLoadScreen();
});

document.querySelector('#load-empty-rack-button').addEventListener('click', e => {
  e.preventDefault();
  loadEmptyRack();
  hideLoadScreen();
});

const loadPresetFileChooserElem = document.querySelector('#load-preset-file-chooser');
loadPresetFileChooserElem.addEventListener('change', e => {
  e.preventDefault();

  const files = loadPresetFileChooserElem.files;
  if (files.length < 1) {
    // No file chosen
    return;
  }
  loadPresetFileChooserElem.files = null;
  const file = files[0];
  const reader = new FileReader();
  reader.onload = (e) => {
    // TODO: various error handling
    const presetJSON = e.target.result;
    const presetObj = JSON.parse(presetJSON);
    if (!presetObj.plinthPreset) {
      console.log('not a preset');
    }
    loadRootBlock(presetObj.b, presetObj.s);
    hideLoadScreen();
  };
  reader.readAsText(file, 'utf-8');
});

document.querySelector('#save-preset-button').addEventListener('click', e => {
  e.preventDefault();

  let settings = null;
  if (rootBlockInst.save) {
    settings = rootBlockInst.save();
  } else {
    console.log("Loaded block doesn't support saving settings");
  }

  const presetObj = {
    plinthPreset: '0.1.0',
    b: rootBlockClassId,
    s: settings,
  };

  const presetJSON = JSON.stringify(presetObj);

  const uriPresetJSON = LZString.compressToEncodedURIComponent(presetJSON);
  console.log('encoded URI length:', uriPresetJSON.length);

  FileSaver.saveAs(new Blob([presetJSON], {type: "application/json;charset=utf-8"}), 'preset.json');
});
<commit_msg>Fix bug with load screen pointer events<commit_after>import FileSaver from 'file-saver';
import LZString from 'lz-string';
import applyPolyfills from './polyfills';
import initWebAudio from './initWebAudio';

// Shim drag and drop for mobile browsers
var iosDragDropShim = { enableEnterLeave: true };
require('drag-drop-webkit-mobile');

applyPolyfills();

const availableBlockClasses = {}; // maps block class id to block class
[
  'bigben',
  'convolux',
  'egen',
  'gainer',
  'orinami',
  'scope',
  'thumper',
  'waverly',
].forEach(n => {
  availableBlockClasses[n] = require('./blocks/' + n + '/block.js').default; // hacky for now
});

import createRacketWithBlocks from './blocks/racket';
const availableBlockClassesIncludingRacks = Object.assign({}, availableBlockClasses);
availableBlockClassesIncludingRacks['racket'] = createRacketWithBlocks(availableBlockClasses);

// Create a Web Audio context
const audioContext = initWebAudio(window);

let rootBlockClassId;
let rootBlockInst;

function loadRootBlock(blockClassId, settings) {
  // Unload any current root block
  if (rootBlockInst) {
    rootBlockInst.outputs.audio.node.disconnect(audioContext.destination);
    if (rootBlockInst.deactivate) {
      rootBlockInst.deactivate();
    }
    document.querySelector('#root-container').innerHTML = '';
  }

  rootBlockClassId = blockClassId;

  // Instantiate the root block, which will let the user dynamically instantiate
  //  and connect up other blocks.
  rootBlockInst = new (availableBlockClassesIncludingRacks[blockClassId])(document, audioContext, settings);

  // Mount the root block's window view
  // TODO: Handle case where windowView is undefined
  document.querySelector('#root-container').appendChild(rootBlockInst.windowView);

  // Connect root audio output to context final output
  rootBlockInst.outputs.audio.node.connect(audioContext.destination);
}

function loadEmptyRack() {
  loadRootBlock('racket', undefined);
}

const loadScreenElem = document.querySelector('#load-screen');
const loadScreenCloseButtonElem = document.querySelector('#load-screen-close-button');

const LOAD_SCREEN_FADE_TIME = 0.15;

function showLoadScreen() {
  if (rootBlockInst) {
    loadScreenCloseButtonElem.style.visibility = 'visible';
  } else {
    loadScreenCloseButtonElem.style.visibility = 'hidden';
  }

  loadScreenElem.style.transition = 'visibility 0s,opacity ' + LOAD_SCREEN_FADE_TIME + 's linear';
  loadScreenElem.style.visibility = 'visible';
  loadScreenElem.style.opacity = '1';
  loadScreenElem.style.pointerEvents = 'auto';
}

function hideLoadScreen() {
  loadScreenElem.style.transition = 'visibility 0s linear ' + LOAD_SCREEN_FADE_TIME + 's,opacity ' + LOAD_SCREEN_FADE_TIME + 's linear';
  loadScreenElem.style.visibility = 'hidden';
  loadScreenElem.style.opacity = '0';
  loadScreenElem.style.pointerEvents = 'none';
}

loadScreenCloseButtonElem.addEventListener('click', e => {
  e.preventDefault();
  hideLoadScreen();
});

document.querySelector('#new-patch-button').addEventListener('click', e => {
  e.preventDefault();
  showLoadScreen();
});

document.querySelector('#load-empty-rack-button').addEventListener('click', e => {
  e.preventDefault();
  loadEmptyRack();
  hideLoadScreen();
});

const loadPresetFileChooserElem = document.querySelector('#load-preset-file-chooser');
loadPresetFileChooserElem.addEventListener('change', e => {
  e.preventDefault();

  const files = loadPresetFileChooserElem.files;
  if (files.length < 1) {
    // No file chosen
    return;
  }
  loadPresetFileChooserElem.files = null;
  const file = files[0];
  const reader = new FileReader();
  reader.onload = (e) => {
    // TODO: various error handling
    const presetJSON = e.target.result;
    const presetObj = JSON.parse(presetJSON);
    if (!presetObj.plinthPreset) {
      console.log('not a preset');
    }
    loadRootBlock(presetObj.b, presetObj.s);
    hideLoadScreen();
  };
  reader.readAsText(file, 'utf-8');
});

document.querySelector('#save-preset-button').addEventListener('click', e => {
  e.preventDefault();

  let settings = null;
  if (rootBlockInst.save) {
    settings = rootBlockInst.save();
  } else {
    console.log("Loaded block doesn't support saving settings");
  }

  const presetObj = {
    plinthPreset: '0.1.0',
    b: rootBlockClassId,
    s: settings,
  };

  const presetJSON = JSON.stringify(presetObj);

  const uriPresetJSON = LZString.compressToEncodedURIComponent(presetJSON);
  console.log('encoded URI length:', uriPresetJSON.length);

  FileSaver.saveAs(new Blob([presetJSON], {type: "application/json;charset=utf-8"}), 'preset.json');
});
<|endoftext|>


<commit_before>import e from './events';
import { $, $$, handleJSON } from './helpers';
import { initInput, addPostingRow, addMetadataRow, entryFormToJSON } from './entry-forms';

function submitTransactionForm(form, successCallback) {
  const jsonData = {
    entries: [
      entryFormToJSON(form.querySelector('.entry-form')),
    ],
  };

  $.fetch(form.getAttribute('action'), {
    method: 'PUT',
    body: JSON.stringify(jsonData),
    headers: { 'Content-Type': 'application/json' },
  })
    .then(handleJSON)
    .then((data) => {
      $$('.metadata', form).forEach((el) => {
        el.remove();
      });
      $$('.posting', form).forEach((el) => {
        el.remove();
      });
      addPostingRow(form);
      addPostingRow(form);
      form.querySelector('input[name="date"]').focus();
      e.trigger('reload');
      e.trigger('info', data.message);
      if (successCallback) {
        successCallback();
      }
    }, (error) => {
      e.trigger('error', `Adding transaction failed: ${error}`);
    });
}

let initialized = false;
export default function showTransactionOverlay() {
  const form = $('#transaction #transaction-form');
  if (!initialized) {
    $$('input', form).forEach((input) => {
      initInput(input);
    });
    addPostingRow(form);
    addPostingRow(form);
    initialized = true;
  }
  $('#transaction').classList.add('shown');
  form.querySelector('input[name="date"]').focus();
}

e.on('page-init', () => {
  const form = $('#transaction #transaction-form');

  form.querySelector('#transaction-form-submit').addEventListener('click', (event) => {
    event.preventDefault();
    submitTransactionForm(form, () => {
      $('#transaction').classList.remove('shown');
    });
  });

  form.querySelector('#transaction-form-submit-and-new').addEventListener('click', (event) => {
    event.preventDefault();
    submitTransactionForm(form);
  });

  form.querySelector('#add-metadata').addEventListener('click', (event) => {
    event.preventDefault();
    const newMetadata = addMetadataRow(form);
    newMetadata.querySelector('.metadata-key').focus();
  });
});
<commit_msg>properly close transaction overlay after adding an transaction<commit_after>import e from './events';
import { $, $$, handleJSON } from './helpers';
import { initInput, addPostingRow, addMetadataRow, entryFormToJSON } from './entry-forms';
import { closeOverlay } from './overlays';

function submitTransactionForm(form, successCallback) {
  const jsonData = {
    entries: [
      entryFormToJSON(form.querySelector('.entry-form')),
    ],
  };

  $.fetch(form.getAttribute('action'), {
    method: 'PUT',
    body: JSON.stringify(jsonData),
    headers: { 'Content-Type': 'application/json' },
  })
    .then(handleJSON)
    .then((data) => {
      $$('.metadata', form).forEach((el) => {
        el.remove();
      });
      $$('.posting', form).forEach((el) => {
        el.remove();
      });
      addPostingRow(form);
      addPostingRow(form);
      form.querySelector('input[name="date"]').focus();
      e.trigger('reload');
      e.trigger('info', data.message);
      if (successCallback) {
        successCallback();
      }
    }, (error) => {
      e.trigger('error', `Adding transaction failed: ${error}`);
    });
}

let initialized = false;
export default function showTransactionOverlay() {
  const form = $('#transaction #transaction-form');
  if (!initialized) {
    $$('input', form).forEach((input) => {
      initInput(input);
    });
    addPostingRow(form);
    addPostingRow(form);
    initialized = true;
  }
  $('#transaction').classList.add('shown');
  form.querySelector('input[name="date"]').focus();
}

e.on('page-init', () => {
  const form = $('#transaction #transaction-form');

  form.querySelector('#transaction-form-submit').addEventListener('click', (event) => {
    event.preventDefault();
    submitTransactionForm(form, closeOverlay);
  });

  form.querySelector('#transaction-form-submit-and-new').addEventListener('click', (event) => {
    event.preventDefault();
    submitTransactionForm(form);
  });

  form.querySelector('#add-metadata').addEventListener('click', (event) => {
    event.preventDefault();
    const newMetadata = addMetadataRow(form);
    newMetadata.querySelector('.metadata-key').focus();
  });
});
<|endoftext|>


<commit_before>'use strict';

var should = require('should');
var By = require('selenium-webdriver').By;

const pageLoadTimeout = 30 * 1000;
const timeoutObject = {timeout: pageLoadTimeout};

// Deal with the non-standard webdriver promises.
function handleErr(cb) {
  return function(err) {
    cb(err);
  };
}

/**
 * Given parameters on the world object, load a URL.
 * @param  {Function} callback Cucumber done callback OR a custom callback.
 * @return {undefined}
 * @this World
 */
function getProjectFromUrl(callback) {
  var world = this;
  var projectRetrievalUrl = 'http://localhost:' + world.appPort + '/?repo_url=' + encodeURIComponent(world.repoUrl);

  world.browser.get(projectRetrievalUrl)
    .then(world.browser.getPageSource.bind(world.browser), handleErr(callback))
    .then(function (body) {
      world.body = body;
      callback();
    }, handleErr(callback));
}

// The returned function is passed as a callback to getProjectFromUrl.
function getScenarioFromProject(callback, world) {
  return function(error) {
    if (error) {
      callback(error);
      return;
    }

    world.browser.findElements(By.css('.spec-link'))
      .then(function (specLinks) {
        var featureLink = specLinks[specLinks.length - 1];
        return world.browser.get(featureLink.getAttribute('href'));
      }, handleErr(callback))
      .then(world.browser.getPageSource.bind(world.browser), handleErr(callback))
      .then(function (body) {
        world.body = body;
        callback();
      }, handleErr(callback));
  };
}

module.exports = function () {

  this.Given(/^a URL representing a remote Git repo "([^"]*)"$/, function (repoUrl, callback) {
    this.repoUrl = repoUrl;
    callback();
  });

  this.When(/^an interested party wants to view the features in that repo\.?$/, timeoutObject, getProjectFromUrl);
  this.When(/^they request the features for the same repository again\.?$/, timeoutObject, getProjectFromUrl);
  this.When(/^an interested party wants to view the scenarios within a feature\.?$/, timeoutObject, function (callback) {
    var world = this;
    getProjectFromUrl.bind(world)(getScenarioFromProject(callback, world));
  });

  this.When(/^interested party wants to view HTML features in the repo$/, timeoutObject, function (callback) {
    this.browser.find(By.className('spec-link'))
        .then(function () {
          callback();
        });
  });

  this.When(/^they decide to change which branch is being displayed$/, function (callback) {
    var world = this;
    var burgerMenuId = 'expand-collapse-repository-controls';
    var repositoryCongtrolsId = 'repository-controls';
    var projectShaElId = 'project-commit';
    var changeBranchSelectElId = 'change-branch-control';
    var testingBranchOptionValue = 'refs%2Fremotes%2Forigin%2Ftest%2FdoNotDelete';
    var burgerMenuEl;
    var repoControlsEl;

    // Get the burger menu element.
    world.browser.findElement(By.id(burgerMenuId))
      .then(function(_burgerMenuEl) {
        burgerMenuEl = _burgerMenuEl;
        return world.browser.findElement(By.id(repositoryCongtrolsId));

        // Get the repo controls element.
      })
      .then(function(_repoControlsEl) {
        repoControlsEl = _repoControlsEl;
        return repoControlsEl.getAttribute('class');

        // Open the repo controls.
      })
      .then(function(repoControlsClass) {
        var isClosed = repoControlsClass.indexOf('collapse') !== -1;
        if (isClosed) {
          return burgerMenuEl.click();
        }
        return;

        // Grab the current SHA
      })
      .then(function() {
        return world.browser.findElement(By.id(projectShaElId));
      })
      .then(function(_projectShaEl) {
        return _projectShaEl.getText();
      })
      .then(function(originalSha) {
        world.oringalSha = originalSha;

        // Grab the branch selecting control.
        return world.browser.findElement(By.id(changeBranchSelectElId));

        // Request to change branch.
      })
      .then(function(_changeBranchSelectEl) {
        return _changeBranchSelectEl.findElement(By.xpath('option[@value=\'' + testingBranchOptionValue + '\']'));
      })
      .then(function(_testBranchOptionEl) {
        return _testBranchOptionEl.click();
      })
      .then(function () {
        callback();
      })
      .catch(function () {
        handleErr(callback);
      });
  });

  this.Then(/^the list of features will be visible\.?$/, function () {
    should.equal(
      /\.feature/i.test(this.body) && /\.md/i.test(this.body),
      true,
      'The returned document body does not contain the strings \'.feature\' and \'.md\'' + this.body);
  });

  this.Then(/^the scenarios will be visible\.?$/, function () {
    should.equal(/feature-title/i.test(this.body),
      true,
      'The returned document body does not contain a feature title');
  });

  // This has to wait for a page to load so it gets the page load time out.
  this.Then(/^the files from the selected branch are displayed\.$/, timeoutObject, function (callback) {
    var world = this;

    var projectShaElId = 'project-commit';

    // Get the new SHA.
    world.browser.findElement(By.id(projectShaElId))
      .then(function(_projectShaEl) {
        return _projectShaEl.getText();
      }, handleErr(callback))
      .then(function(newSha) {
        should.notEqual(newSha, world.oringalSha, 'The SHA did not change on changing branch.');
        callback();
      }, handleErr(callback));
  });

  this.When(/^the results are retrieved from a CI server\.?$/, timeoutObject, function (callback) {
    var world = this;

    var getResultsID='get-jenkins-results';
    var getResults;
    // get the get results button
    world.browser.findElement(By.id(getResultsID))
      .then(function(_getResults) {
        getResults = _getResults;
        return getResults.click();
      }, handleErr(callback))
      .then(world.browser.findElement(By.id(getResultsID)))
      .then(
        getProjectFromUrl.bind(world)(
        getScenarioFromProject(callback, world)
      )
    );
  });

  this.Then(/^the list of results for the feature will be visible\.$/, timeoutObject, function (callback) {
    var world = this;
    world.browser.findElement(By.css('.resultLink .PASSED'))
      .then(function(_resultButton) {
        return _resultButton.getAttribute('value');
      }, handleErr(callback))
      .then(function(resultValue) {
        should.equal(resultValue, 'PASSED', 'The value of the button was not PASSED, value was '+resultValue);
        callback();
      }, handleErr(callback));
  });

  this.When(/^an interested party wants to view the results for the features in that repo$/, timeoutObject, getProjectFromUrl);

  this.Then(/^the get results button is displayed\.$/, timeoutObject, function (callback) {
    var world = this;
    world.browser.findElement(By.css('.get-results')).then(function() {
      should.equal(true,true);
    }, function(err) {
      if (err.name && err.name === 'NoSuchElementError') {
        // should.equal(false,true,'element not displayed');
        should.fail('Could not find a get results button');
      } else {
        should.fail('Got the following unexpected error - ' + err);
      }
    });
    callback();
  });

  this.When(/^they decide to view HTML specification$/, function (callback) {
    var world = this;

    world.browser.findElements(By.css('.spec-link[href*=\\.html]'))
        .then(function (specLinks) {
          var featureLink = specLinks[specLinks.length - 1];

          // Navigates to a feature file
          return world.browser.get(featureLink.getAttribute('href'));
        })
        .then(function () {
          callback();
        })
        .catch(function() {
          handleErr(callback);
        });
  });

  this.Then(/^HTML specification is displayed$/, function (callback) {
    var browser = this.browser;
    browser.findElement(By.css('section.html-body iframe'))
      .then(function (iframe) {
        return browser.switchTo().frame(iframe);
      })
      .then(function () {
        return browser.findElement(By.css('h1'));
      })
      .then(function (el) {
        return el.getText();
      })
      .then(function (h1Text) {
        should.equal(h1Text, 'Title');
        callback();
      })
      .catch(function () {
        handleErr(callback);
      });
  });

};<commit_msg>Updating test to wait for the page to reload after switching branch. It was skiping over too quickly<commit_after>'use strict';

var should = require('should');
var By = require('selenium-webdriver').By;
var until = require('selenium-webdriver').until;

const pageLoadTimeout = 30 * 1000;
const timeoutObject = {timeout: pageLoadTimeout};

// Deal with the non-standard webdriver promises.
function handleErr(cb) {
  return function(err) {
    cb(err);
  };
}

/**
 * Given parameters on the world object, load a URL.
 * @param  {Function} callback Cucumber done callback OR a custom callback.
 * @return {undefined}
 * @this World
 */
function getProjectFromUrl(callback) {
  var world = this;
  var projectRetrievalUrl = 'http://localhost:' + world.appPort + '/?repo_url=' + encodeURIComponent(world.repoUrl);

  world.browser.get(projectRetrievalUrl)
    .then(world.browser.getPageSource.bind(world.browser), handleErr(callback))
    .then(function (body) {
      world.body = body;
      callback();
    }, handleErr(callback));
}

// The returned function is passed as a callback to getProjectFromUrl.
function getScenarioFromProject(callback, world) {
  return function(error) {
    if (error) {
      callback(error);
      return;
    }

    world.browser.findElements(By.css('.spec-link'))
      .then(function (specLinks) {
        var featureLink = specLinks[specLinks.length - 1];
        return world.browser.get(featureLink.getAttribute('href'));
      }, handleErr(callback))
      .then(world.browser.getPageSource.bind(world.browser), handleErr(callback))
      .then(function (body) {
        world.body = body;
        callback();
      }, handleErr(callback));
  };
}

module.exports = function () {

  this.Given(/^a URL representing a remote Git repo "([^"]*)"$/, function (repoUrl, callback) {
    this.repoUrl = repoUrl;
    callback();
  });

  this.When(/^an interested party wants to view the features in that repo\.?$/, timeoutObject, getProjectFromUrl);
  this.When(/^they request the features for the same repository again\.?$/, timeoutObject, getProjectFromUrl);
  this.When(/^an interested party wants to view the scenarios within a feature\.?$/, timeoutObject, function (callback) {
    var world = this;
    getProjectFromUrl.bind(world)(getScenarioFromProject(callback, world));
  });

  this.When(/^interested party wants to view HTML features in the repo$/, timeoutObject, function (callback) {
    this.browser.find(By.className('spec-link'))
        .then(function () {
          callback();
        });
  });

  this.When(/^they decide to change which branch is being displayed$/, function (callback) {
    var world = this;
    var burgerMenuId = 'expand-collapse-repository-controls';
    var repositoryCongtrolsId = 'repository-controls';
    var projectShaElId = 'project-commit';
    var changeBranchSelectElId = 'change-branch-control';
    var testingBranchOptionValue = 'refs%2Fremotes%2Forigin%2Ftest%2FdoNotDelete';
    var burgerMenuEl;
    var repoControlsEl;

    // Get the burger menu element.
    world.browser.findElement(By.id(burgerMenuId))
      .then(function(_burgerMenuEl) {
        burgerMenuEl = _burgerMenuEl;
        return world.browser.findElement(By.id(repositoryCongtrolsId));

        // Get the repo controls element.
      })
      .then(function(_repoControlsEl) {
        repoControlsEl = _repoControlsEl;
        return repoControlsEl.getAttribute('class');

        // Open the repo controls.
      })
      .then(function(repoControlsClass) {
        var isClosed = repoControlsClass.indexOf('collapse') !== -1;
        if (isClosed) {
          return burgerMenuEl.click();
        }
        return;

        // Grab the current SHA
      })
      .then(function() {
        return world.browser.findElement(By.id(projectShaElId));
      })
      .then(function(_projectShaEl) {
        return _projectShaEl.getText();
      })
      .then(function(originalSha) {
        world.oringalSha = originalSha;

        // Grab the branch selecting control.
        return world.browser.findElement(By.id(changeBranchSelectElId));

        // Request to change branch.
      })
      .then(function(_changeBranchSelectEl) {
        return _changeBranchSelectEl.findElement(By.xpath('option[@value=\'' + testingBranchOptionValue + '\']'));
      })
      .then(function(_testBranchOptionEl) {
        world._testBranchOptionEl = _testBranchOptionEl;
        return _testBranchOptionEl.click();
      })
      .then(function () {
        // Waiting for the page to refresh after the click
        return world.browser.wait(until.stalenessOf(world._testBranchOptionEl));
      })
      .then(function () {
        callback();
      })
      .catch(function () {
        handleErr(callback);
      });
  });

  this.Then(/^the list of features will be visible\.?$/, function () {
    should.equal(
      /\.feature/i.test(this.body) && /\.md/i.test(this.body),
      true,
      'The returned document body does not contain the strings \'.feature\' and \'.md\'' + this.body);
  });

  this.Then(/^the scenarios will be visible\.?$/, function () {
    should.equal(/feature-title/i.test(this.body),
      true,
      'The returned document body does not contain a feature title');
  });

  // This has to wait for a page to load so it gets the page load time out.
  this.Then(/^the files from the selected branch are displayed\.$/, timeoutObject, function (callback) {
    var world = this;

    var projectShaElId = 'project-commit';

    // Get the new SHA.
    world.browser.findElement(By.id(projectShaElId))
      .then(function(_projectShaEl) {
        return _projectShaEl.getText();
      }, handleErr(callback))
      .then(function(newSha) {
        should.notEqual(newSha, world.oringalSha, 'The SHA did not change on changing branch.');
        callback();
      }, handleErr(callback));
  });

  this.When(/^the results are retrieved from a CI server\.?$/, timeoutObject, function (callback) {
    var world = this;

    var getResultsID='get-jenkins-results';
    var getResults;
    // get the get results button
    world.browser.findElement(By.id(getResultsID))
      .then(function(_getResults) {
        getResults = _getResults;
        return getResults.click();
      }, handleErr(callback))
      .then(world.browser.findElement(By.id(getResultsID)))
      .then(
        getProjectFromUrl.bind(world)(
        getScenarioFromProject(callback, world)
      )
    );
  });

  this.Then(/^the list of results for the feature will be visible\.$/, timeoutObject, function (callback) {
    var world = this;
    world.browser.findElement(By.css('.resultLink .PASSED'))
      .then(function(_resultButton) {
        return _resultButton.getAttribute('value');
      }, handleErr(callback))
      .then(function(resultValue) {
        should.equal(resultValue, 'PASSED', 'The value of the button was not PASSED, value was '+resultValue);
        callback();
      }, handleErr(callback));
  });

  this.When(/^an interested party wants to view the results for the features in that repo$/, timeoutObject, getProjectFromUrl);

  this.Then(/^the get results button is displayed\.$/, timeoutObject, function (callback) {
    var world = this;
    world.browser.findElement(By.css('.get-results')).then(function() {
      should.equal(true,true);
    }, function(err) {
      if (err.name && err.name === 'NoSuchElementError') {
        // should.equal(false,true,'element not displayed');
        should.fail('Could not find a get results button');
      } else {
        should.fail('Got the following unexpected error - ' + err);
      }
    });
    callback();
  });

  this.When(/^they decide to view HTML specification$/, function (callback) {
    var world = this;

    world.browser.findElements(By.css('.spec-link[href*=\\.html]'))
        .then(function (specLinks) {
          var featureLink = specLinks[specLinks.length - 1];

          // Navigates to a feature file
          return world.browser.get(featureLink.getAttribute('href'));
        })
        .then(function () {
          callback();
        })
        .catch(function() {
          handleErr(callback);
        });
  });

  this.Then(/^HTML specification is displayed$/, function (callback) {
    var browser = this.browser;
    browser.findElement(By.css('section.html-body iframe'))
      .then(function (iframe) {
        return browser.switchTo().frame(iframe);
      })
      .then(function () {
        return browser.findElement(By.css('h1'));
      })
      .then(function (el) {
        return el.getText();
      })
      .then(function (h1Text) {
        should.equal(h1Text, 'Title');
        callback();
      })
      .catch(function () {
        handleErr(callback);
      });
  });

};<|endoftext|>


<commit_before>'use strict'

var DocumentStyle = require('../style/document')
var PDF = require('../pdf')

var Document = module.exports = function(opts) {
  Document.super_.call(this, require('../pdf/nodes/document'))

  opts        = opts || {}
  opts.width  = opts.width  || 612
  opts.height = opts.height || 792

  this.style   = new DocumentStyle(opts)
  this._header = null
  this._footer = null
}

require('../pdf/utils').inherits(Document, require('./container'))

var Box = require('./box')

Document.prototype.header = function(opts) {
  if (this._header) {
    return _header
  }

  if (opts && !opts.width) {
    opts.width = '100%'
  }

  this._header = new Box(this.style.merge(DocumentStyle.super_.paddingReset), opts)
  return this._header
}

Document.prototype.footer = function(opts) {
  if (this._footer) {
    return _footer
  }

  if (opts && !opts.width) {
    opts.width = '100%'
  }

  this._footer = new Box(this.style.merge(DocumentStyle.super_.paddingReset), opts)
  return this._footer
}

Document.prototype.render = function() {
  return new PDF(this.createNode(this))
}
<commit_msg>make A4 the default page size<commit_after>'use strict'

var DocumentStyle = require('../style/document')
var PDF = require('../pdf')

var Document = module.exports = function(opts) {
  Document.super_.call(this, require('../pdf/nodes/document'))

  opts        = opts || {}
  opts.width  = opts.width  || 595.296
  opts.height = opts.height || 841.896

  this.style   = new DocumentStyle(opts)
  this._header = null
  this._footer = null
}

require('../pdf/utils').inherits(Document, require('./container'))

var Box = require('./box')

Document.prototype.header = function(opts) {
  if (this._header) {
    return _header
  }

  if (opts && !opts.width) {
    opts.width = '100%'
  }

  this._header = new Box(this.style.merge(DocumentStyle.super_.paddingReset), opts)
  return this._header
}

Document.prototype.footer = function(opts) {
  if (this._footer) {
    return _footer
  }

  if (opts && !opts.width) {
    opts.width = '100%'
  }

  this._footer = new Box(this.style.merge(DocumentStyle.super_.paddingReset), opts)
  return this._footer
}

Document.prototype.render = function() {
  return new PDF(this.createNode(this))
}
<|endoftext|>


<commit_before>// #DROPZONE#
// This script implements the dropzone settings
'use strict';

var Dropzone;

if (Dropzone) {
    Dropzone.autoDiscover = false;
}

/* global Dropzone, django */
django.jQuery(function ($) {
    var dropzoneTemplateSelector = '.js-filer-dropzone-template';
    var previewImageSelector = '.js-img-preview';
    var dropzoneSelector = '.js-filer-dropzone';
    var dropzones = $(dropzoneSelector);
    var messageSelector = '.js-filer-dropzone-message';
    var lookupButtonSelector = '.js-related-lookup';
    var progressSelector = '.js-filer-dropzone-progress';
    var previewImageWrapperSelector = '.js-img-wrapper';
    var filerClearerSelector = '.filerClearer';
    var fileChooseSelector = '.js-file-selector';
    var fileIdInputSelector = '.vForeignKeyRawIdAdminField';
    var dragHoverClass = 'dz-drag-hover';
    var hiddenClass = 'hidden';
    var mobileClass = 'filer-dropzone-mobile';
    var objectAttachedClass = 'js-object-attached';
    // var dataMaxFileSize = 'max-file-size';
    var minWidth = 500;
    var checkMinWidth = function (element) {
        element.toggleClass(mobileClass, element.width() < minWidth);
    };
    var showError = function (message) {
        try {
            window.parent.CMS.API.Messages.open({
                message: message
            });
        } catch (errorText) {
            console.log(errorText);
        }
    };

    var createDropzone = function () {
        var dropzone = $(this);
        var dropzoneUrl = dropzone.data('url');
        var inputId = dropzone.find(fileIdInputSelector);
        var isImage = inputId.is('[name="image"]');
        var lookupButton = dropzone.find(lookupButtonSelector);
        var message = dropzone.find(messageSelector);
        var clearButton = dropzone.find(filerClearerSelector);
        var fileChoose = dropzone.find(fileChooseSelector);

        if (this.dropzone) {
            return;
        }

        $(window).on('resize', function () {
            checkMinWidth(dropzone);
        });

        new Dropzone(this, {
            url: dropzoneUrl,
            paramName: 'file',
            maxFiles: 1,
            // for now disabled as we don't have the correct file size limit
            // maxFilesize: dropzone.data(dataMaxFileSize) || 20, // MB
            previewTemplate: $(dropzoneTemplateSelector).html(),
            clickable: false,
            addRemoveLinks: false,
            init: function () {
                checkMinWidth(dropzone);
                this.on('removedfile', function () {
                    fileChoose.show();
                    dropzone.removeClass(objectAttachedClass);
                    this.removeAllFiles();
                    clearButton.trigger('click');
                });
                $('img', this.element).on('dragstart', function (event) {
                    event.preventDefault();
                });
                clearButton.on('click', function () {
                    dropzone.removeClass(objectAttachedClass);
                });
            },
            maxfilesexceeded: function () {
                this.removeAllFiles(true);
            },
            drop: function () {
                this.removeAllFiles(true);
                fileChoose.hide();
                lookupButton.addClass(hiddenClass);
                message.addClass(hiddenClass);
                dropzone.removeClass(dragHoverClass);
                dropzone.addClass(objectAttachedClass);
            },
            success: function (file, response) {
                $(progressSelector).addClass(hiddenClass);
                if (file && file.status === 'success' && response) {
                    if (response.file_id) {
                        inputId.val(response.file_id);
                    }
                    if (response.thumbnail_180) {
                        if (isImage) {
                            $(previewImageSelector).css({
                                'background-image': 'url(' + response.thumbnail_180 + ')'
                            });
                            $(previewImageWrapperSelector).removeClass(hiddenClass);
                        }
                    }
                } else {
                    if (response && response.error) {
                        window.showError(file.name + ': ' + response.error);
                    }
                    this.removeAllFiles(true);
                }

                $('img', this.element).on('dragstart', function (event) {
                    event.preventDefault();
                });
            },
            error: function (file, response) {
                showError(file.name + ': ' + response.error);
                this.removeAllFiles(true);
            },
            reset: function () {
                if (isImage) {
                    $(previewImageWrapperSelector).addClass(hiddenClass);
                    $(previewImageSelector).css({'background-image': 'none'});
                }
                dropzone.removeClass(objectAttachedClass);
                inputId.val('');
                lookupButton.removeClass(hiddenClass);
                message.removeClass(hiddenClass);
            }
        });
    };

    if (dropzones.length && Dropzone) {
        if (!window.filerDropzoneInitialized) {
            window.filerDropzoneInitialized = true;
            Dropzone.autoDiscover = false;
        }
        dropzones.each(createDropzone);
        $(document).on('formset:added', function (ev, row) {
            var dropzones = $(row).find(dropzoneSelector);
            dropzones.each(createDropzone);
        });
    }
});
<commit_msg>adds global dropzone and remove var<commit_after>// #DROPZONE#
// This script implements the dropzone settings
/* global Dropzone */
'use strict';

if (Dropzone) {
    Dropzone.autoDiscover = false;
}

/* global Dropzone, django */
django.jQuery(function ($) {
    var dropzoneTemplateSelector = '.js-filer-dropzone-template';
    var previewImageSelector = '.js-img-preview';
    var dropzoneSelector = '.js-filer-dropzone';
    var dropzones = $(dropzoneSelector);
    var messageSelector = '.js-filer-dropzone-message';
    var lookupButtonSelector = '.js-related-lookup';
    var progressSelector = '.js-filer-dropzone-progress';
    var previewImageWrapperSelector = '.js-img-wrapper';
    var filerClearerSelector = '.filerClearer';
    var fileChooseSelector = '.js-file-selector';
    var fileIdInputSelector = '.vForeignKeyRawIdAdminField';
    var dragHoverClass = 'dz-drag-hover';
    var hiddenClass = 'hidden';
    var mobileClass = 'filer-dropzone-mobile';
    var objectAttachedClass = 'js-object-attached';
    // var dataMaxFileSize = 'max-file-size';
    var minWidth = 500;
    var checkMinWidth = function (element) {
        element.toggleClass(mobileClass, element.width() < minWidth);
    };
    var showError = function (message) {
        try {
            window.parent.CMS.API.Messages.open({
                message: message
            });
        } catch (errorText) {
            console.log(errorText);
        }
    };

    var createDropzone = function () {
        var dropzone = $(this);
        var dropzoneUrl = dropzone.data('url');
        var inputId = dropzone.find(fileIdInputSelector);
        var isImage = inputId.is('[name="image"]');
        var lookupButton = dropzone.find(lookupButtonSelector);
        var message = dropzone.find(messageSelector);
        var clearButton = dropzone.find(filerClearerSelector);
        var fileChoose = dropzone.find(fileChooseSelector);

        if (this.dropzone) {
            return;
        }

        $(window).on('resize', function () {
            checkMinWidth(dropzone);
        });

        new Dropzone(this, {
            url: dropzoneUrl,
            paramName: 'file',
            maxFiles: 1,
            // for now disabled as we don't have the correct file size limit
            // maxFilesize: dropzone.data(dataMaxFileSize) || 20, // MB
            previewTemplate: $(dropzoneTemplateSelector).html(),
            clickable: false,
            addRemoveLinks: false,
            init: function () {
                checkMinWidth(dropzone);
                this.on('removedfile', function () {
                    fileChoose.show();
                    dropzone.removeClass(objectAttachedClass);
                    this.removeAllFiles();
                    clearButton.trigger('click');
                });
                $('img', this.element).on('dragstart', function (event) {
                    event.preventDefault();
                });
                clearButton.on('click', function () {
                    dropzone.removeClass(objectAttachedClass);
                });
            },
            maxfilesexceeded: function () {
                this.removeAllFiles(true);
            },
            drop: function () {
                this.removeAllFiles(true);
                fileChoose.hide();
                lookupButton.addClass(hiddenClass);
                message.addClass(hiddenClass);
                dropzone.removeClass(dragHoverClass);
                dropzone.addClass(objectAttachedClass);
            },
            success: function (file, response) {
                $(progressSelector).addClass(hiddenClass);
                if (file && file.status === 'success' && response) {
                    if (response.file_id) {
                        inputId.val(response.file_id);
                    }
                    if (response.thumbnail_180) {
                        if (isImage) {
                            $(previewImageSelector).css({
                                'background-image': 'url(' + response.thumbnail_180 + ')'
                            });
                            $(previewImageWrapperSelector).removeClass(hiddenClass);
                        }
                    }
                } else {
                    if (response && response.error) {
                        window.showError(file.name + ': ' + response.error);
                    }
                    this.removeAllFiles(true);
                }

                $('img', this.element).on('dragstart', function (event) {
                    event.preventDefault();
                });
            },
            error: function (file, response) {
                showError(file.name + ': ' + response.error);
                this.removeAllFiles(true);
            },
            reset: function () {
                if (isImage) {
                    $(previewImageWrapperSelector).addClass(hiddenClass);
                    $(previewImageSelector).css({'background-image': 'none'});
                }
                dropzone.removeClass(objectAttachedClass);
                inputId.val('');
                lookupButton.removeClass(hiddenClass);
                message.removeClass(hiddenClass);
            }
        });
    };

    if (dropzones.length && Dropzone) {
        if (!window.filerDropzoneInitialized) {
            window.filerDropzoneInitialized = true;
            Dropzone.autoDiscover = false;
        }
        dropzones.each(createDropzone);
        $(document).on('formset:added', function (ev, row) {
            var dropzones = $(row).find(dropzoneSelector);
            dropzones.each(createDropzone);
        });
    }
});
<|endoftext|>


<commit_before>var _ = require('underscore');

var Enemy = require('./enemy');

var EnemyCollection = (function() {

	function EnemyCollection() {
		this.collection = [];
	};

	EnemyCollection.prototype.add = function(enemy) {
		if (!enemy instanceof Enemy) {
			return;
		}
		this.collection.push(enemy);
	};

	EnemyCollection.prototype.remove = function(id) {
		this.collection = _.reject(this.collection, function(enemy) {
			enemy._id === id;
		});
	};

	EnemyCollection.prototype.isEmpty = function() {
		return this.collection.length === 0;
	};

	EnemyCollection.prototype.byId = function(id) {
		return _.find(this.collection, function(enemy) {
			return enemy._id === id;
		});
	};

	EnemyCollection.prototype.getAll = function() {
		return this.collection;
	};

	EnemyCollection.prototype.summary = function() {
		var summary = {};
		_.each(this.collection, function(enemy) {
			if (typeof summary[enemy.type] === 'undefined') {
				summary[enemy.type] = 1;
			} else {
				summary[enemy.type] += 1;
			}
		});
		return summary;
	};

	EnemyCollection.prototype.list = function() {
		var list = [];
		_.each(this.collection, function(enemy) {
			list.push(enemy.describe());
		});
		return list;
	}

	EnemyCollection.prototype.massAttack = function() {
		var totalDamage = 0;
		_.each(this.collection, function(enemy) {
			totalDamage += enemy.attack();
		});

		return totalDamage;
	};

	return EnemyCollection;

}());

module.exports = EnemyCollection;
<commit_msg>Linted enemy_collection.js<commit_after>var _ = require('underscore');

var Enemy = require('./enemy');

var EnemyCollection = (function() {

	function EnemyCollection() {
		this.collection = [];
	}

	EnemyCollection.prototype.add = function(enemy) {
		if (!enemy instanceof Enemy) {
			return;
		}
		this.collection.push(enemy);
	};

	EnemyCollection.prototype.remove = function(id) {
		this.collection = _.reject(this.collection, function(enemy) {
			return enemy._id === id;
		});
	};

	EnemyCollection.prototype.isEmpty = function() {
		return this.collection.length === 0;
	};

	EnemyCollection.prototype.byId = function(id) {
		return _.find(this.collection, function(enemy) {
			return enemy._id === id;
		});
	};

	EnemyCollection.prototype.getAll = function() {
		return this.collection;
	};

	EnemyCollection.prototype.summary = function() {
		var summary = {};
		_.each(this.collection, function(enemy) {
			if (typeof summary[enemy.type] === 'undefined') {
				summary[enemy.type] = 1;
			} else {
				summary[enemy.type] += 1;
			}
		});
		return summary;
	};

	EnemyCollection.prototype.list = function() {
		var list = [];
		_.each(this.collection, function(enemy) {
			list.push(enemy.describe());
		});
		return list;
	};

	EnemyCollection.prototype.massAttack = function() {
		var totalDamage = 0;
		_.each(this.collection, function(enemy) {
			totalDamage += enemy.attack();
		});

		return totalDamage;
	};

	return EnemyCollection;

}());

module.exports = EnemyCollection;
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------- \\
// File: ListView.js                                                          \\
// Module: View                                                               \\
// Requires: UnorderedCollectionView.js                                       \\
// Author: Neil Jenkins                                                       \\
// License: © 2010–2012 Opera Software ASA. All rights reserved.              \\
// -------------------------------------------------------------------------- \\

/*global document */

"use strict";

( function ( NS ) {

var ListView = NS.Class({

    Extends: NS.UnorderedCollectionView,

    Mixin: NS.TrueVisibleRect,

    _batchSize: 10,
    _triggerInPx: 200,

    itemHeight: 100,

    contentLength: NS.bind( 'content.length' ),

    init: function ( options ) {
        this._renderRange = { start: 0, end: 0 };
        ListView.parent.init.call( this, options );
    },

    positioning: 'absolute',

    layout: function () {
        return {
             top: 0,
             left: 0,
             right: 0,
             height: this.get( 'itemHeight' ) *
                 ( this.get( 'contentLength' ) || 0 )
        };
    }.property( 'itemHeight', 'contentLength' ),

    contentWasUpdated: function ( event ) {
        var scrollView = this.getParent( NS.ScrollView );
        if ( scrollView ) {
            // Update scroll view correctly.
            var itemHeight = this.get( 'itemHeight' ),
                // Index of first item rendered
                top = ~~( this.get( 'visibleRect' ).y / itemHeight ),
                removedIndexes = event.removedIndexes,
                addedIndexes = event.addedIndexes,
                change = 0,
                i, l;

            if ( top < 3 && addedIndexes[0] < 3 ) {
                change = -( top + 1 );
            }
            else {
                for ( i = 0, l = removedIndexes.length; i < l; i += 1 ) {
                    if ( removedIndexes[i] < top ) { change -= 1; }
                    // Guaranteed in ascending order.
                    else { break; }
                }
                top += change;
                for ( i = 0, l = addedIndexes.length; i < l; i += 1 ) {
                    if ( addedIndexes[i] <= top ) { change += 1; }
                    // Guaranteed in ascending order.
                    else { break; }
                }
            }
            if ( change ) {
                scrollView.scrollBy( 0, change * itemHeight );
            }
        }
    },

    _simulateScroll: function ( _, __, oldLength, length ) {
        // Convert null/undefined length to 0.
        if ( !length ) { length = 0; }
        // In IE or Opera, if the scrollTop of the containing overflowed div was
        // past the new maximum scrollTop, then although it correctly changes
        // to the new maximum scrollTop, no scroll event is fired. Therefore we
        // have to simulate this firing in the next event loop.
        if ( length < oldLength ) {
            NS.RunLoop.invokeInNextEventLoop(
                this.fire.bind( this, 'scroll', null, null )
            );
        }
    }.observes( 'contentLength' ),

    visibleRectDidChange: function () {
        // We only care about changes when we're visible.
        if ( this.get( 'isInDocument' ) ) {
            var visible = this.get( 'visibleRect' ),
                extension = this._triggerInPx,
                batchSize = this._batchSize,
                height = this.get( 'itemHeight' ) * batchSize,
                y = visible.y,
                // Index of first item we want rendered
                start = Math.max( 0,
                    ~~( ( y - extension ) / height ) * batchSize ),
                // Index of last item we want rendered
                end = ~~( ( y + visible.height + extension ) / height ) *
                    batchSize + batchSize,
                _renderRange = this._renderRange;

            if ( start !== _renderRange.start || end !== _renderRange.end ) {
                _renderRange.start = start;
                _renderRange.end = end;
                this._redraw();
            }
        }
    }.observes( 'visibleRect' )
});

NS.ListView = ListView;

}( this.O ) );
<commit_msg>Redraw list view if item height changes.<commit_after>// -------------------------------------------------------------------------- \\
// File: ListView.js                                                          \\
// Module: View                                                               \\
// Requires: UnorderedCollectionView.js                                       \\
// Author: Neil Jenkins                                                       \\
// License: © 2010–2012 Opera Software ASA. All rights reserved.              \\
// -------------------------------------------------------------------------- \\

/*global document */

"use strict";

( function ( NS ) {

var ListView = NS.Class({

    Extends: NS.UnorderedCollectionView,

    Mixin: NS.TrueVisibleRect,

    _batchSize: 10,
    _triggerInPx: 200,

    itemHeight: 100,

    contentLength: NS.bind( 'content.length' ),

    init: function ( options ) {
        this._renderRange = { start: 0, end: 0 };
        ListView.parent.init.call( this, options );
    },

    positioning: 'absolute',

    layout: function () {
        return {
             top: 0,
             left: 0,
             right: 0,
             height: this.get( 'itemHeight' ) *
                 ( this.get( 'contentLength' ) || 0 )
        };
    }.property( 'itemHeight', 'contentLength' ),

    contentWasUpdated: function ( event ) {
        var scrollView = this.getParent( NS.ScrollView );
        if ( scrollView ) {
            // Update scroll view correctly.
            var itemHeight = this.get( 'itemHeight' ),
                // Index of first item rendered
                top = ~~( this.get( 'visibleRect' ).y / itemHeight ),
                removedIndexes = event.removedIndexes,
                addedIndexes = event.addedIndexes,
                change = 0,
                i, l;

            if ( top < 3 && addedIndexes[0] < 3 ) {
                change = -( top + 1 );
            }
            else {
                for ( i = 0, l = removedIndexes.length; i < l; i += 1 ) {
                    if ( removedIndexes[i] < top ) { change -= 1; }
                    // Guaranteed in ascending order.
                    else { break; }
                }
                top += change;
                for ( i = 0, l = addedIndexes.length; i < l; i += 1 ) {
                    if ( addedIndexes[i] <= top ) { change += 1; }
                    // Guaranteed in ascending order.
                    else { break; }
                }
            }
            if ( change ) {
                scrollView.scrollBy( 0, change * itemHeight );
            }
        }
    },

    _simulateScroll: function ( _, __, oldLength, length ) {
        // Convert null/undefined length to 0.
        if ( !length ) { length = 0; }
        // In IE or Opera, if the scrollTop of the containing overflowed div was
        // past the new maximum scrollTop, then although it correctly changes
        // to the new maximum scrollTop, no scroll event is fired. Therefore we
        // have to simulate this firing in the next event loop.
        if ( length < oldLength ) {
            NS.RunLoop.invokeInNextEventLoop(
                this.fire.bind( this, 'scroll', null, null )
            );
        }
    }.observes( 'contentLength' ),

    visibleRectDidChange: function () {
        // We only care about changes when we're visible.
        if ( this.get( 'isInDocument' ) ) {
            var visible = this.get( 'visibleRect' ),
                extension = this._triggerInPx,
                batchSize = this._batchSize,
                height = this.get( 'itemHeight' ) * batchSize,
                y = visible.y,
                // Index of first item we want rendered
                start = Math.max( 0,
                    ~~( ( y - extension ) / height ) * batchSize ),
                // Index of last item we want rendered
                end = ~~( ( y + visible.height + extension ) / height ) *
                    batchSize + batchSize,
                _renderRange = this._renderRange;

            if ( start !== _renderRange.start || end !== _renderRange.end ) {
                _renderRange.start = start;
                _renderRange.end = end;
                this._redraw();
            }
        }
    }.observes( 'visibleRect', 'itemHeight' )
});

NS.ListView = ListView;

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


<commit_before>import assert from 'assert';
import StyleSheet from '../';
import { parse } from 'css' ;
import * as style from './fixtures';

const unique = arr => [...new Set(arr)];
const values = obj => Object.keys(obj).map( key => obj[key] );

describe('stilr', () => {

  describe('#create(obj)', () => {
    beforeEach(() => {
      StyleSheet.clear();
    });

    it('creates an entry in the stylesheet', () => {
      const entries = Object.keys(style.basic);
      StyleSheet.create(style.basic);
      assert.equal(
        StyleSheet.__stylesheet.size,
        entries.length
      );
    });

    it('returns an object', () => {
      const styles = StyleSheet.create(style.basic);
      assert.equal( typeof styles, 'object' );
    });

    it('has the same keys', () => {
      const keys = Object.keys( StyleSheet.create(style.basic) );
      const originalKeys = Object.keys( style.basic );

      assert.equal(
        keys.join(''),
        originalKeys.join('')
      );
    });

    it('assigns the same class name to duplicate styles', () => {
      const styles = StyleSheet.create( style.duplicates );
      const classNames = Object.keys( styles );

      classNames.map(
        className => assert.equal( styles[classNames[0]], styles[className] )
      );
    });

    it('handles pseudo classes', () => {
      const styles = StyleSheet.create( style.pseudos );
      assert.equal(
        unique( values(styles) ).length,
        Object.keys(styles).length,
        `All classnames should be unique: .${ values( styles ).join(' .') }`
      );
    });

    it('handles media queries', () => {
      const styles = StyleSheet.create( style.mediaQueries );

      assert.equal(
        unique( values(styles) ).length,
        Object.keys(styles).length,
        `All classnames should be unique: .${ values( styles ).join(' .') }`
      );
    });

    it('accepts a alternative stylesheet', () => {
      const altStylesheet = new Map();
      const entries = Object.keys(style.basic);
      StyleSheet.create( style.basic, altStylesheet );

      StyleSheet.create(style.basic);
      assert.equal(
        altStylesheet.size,
        entries.length
      );

      assert.notEqual(
        altStylesheet,
        StyleSheet.__stylesheet
      );
    });

    it('assigns unique class names', () => {
      const uniqueStyles = StyleSheet.create({
        unique1: {
          justifyContent: 'center'
        },
        unique2: {
          alignItems: 'center'
        },
        unique3: {
          textAlign: 'center'
        },
        unique4: {
          color: 'red',
          ':hover': {
            color: 'green'
          }
        },
        unique5: {
          color: 'red',
          ':active': {
            color: 'green'
          }
        }
      });
      const keys = Object.keys(uniqueStyles);
      const classes = unique( values(uniqueStyles) );

      assert.equal(
        keys.length,
        classes.length
      );
    });

  });

  describe('#render()', () => {
    beforeEach(() => {
      StyleSheet.clear();
    });

    it('returns a string', () => {
      StyleSheet.create(style.basic);
      const stylesheet = StyleSheet.render();
      assert.equal( typeof stylesheet, 'string' );
    });

    it('is parseable css', () => {
      StyleSheet.create(style.basic);
      const parsedCss = parse( StyleSheet.render() );
      assert.ok( parsedCss );

      const renderedClassNames = parsedCss.stylesheet.rules.map( rule => rule.selectors[0] );

      for ( let className of StyleSheet.__stylesheet.keys() ) {
        assert.ok( !!~renderedClassNames.indexOf( `.${ className }` ), `.${ className } should be part of the rendered css classes: '${ renderedClassNames }'`);
      }
    });

    it('outputs pseudo classes correctly', () => {
      const hover = /(\._[\s\S]+)(:hover{)/g;

      StyleSheet.create({
        style: {
          color: 'tomato',
          ':hover': {
            color: 'red'
          }
        }
      });

      const css = StyleSheet.render();
      assert.ok(
        css.match(hover).length === 1
      );
    });

    it('outputs media queries correctly', () => {
      const breakpoint = '@media (max-width: 600px)';
      const mediaQueryStyles = {
        style1: {
          color: 'blue',
          [breakpoint]: {
            color: 'red'
          }
        },
        style2: {
          color: 'green',
          [breakpoint]: {
            color: 'blue'
          }
        }
      };

      StyleSheet.create(mediaQueryStyles);

      const css = StyleSheet.render();
      const rules = parse(css).stylesheet.rules;
      assert.equal(rules[0].type, 'rule', 'Rule should be before media queries');
      assert.equal(rules[2].type, 'media');
      assert.equal(rules[2].media, breakpoint.replace('@media ', ''));

      const mediaQueryContent = rules[2].rules;
      assert.equal(
        mediaQueryContent.length, 2,
        'Media query should contain two rules'
      );

      const mediaQueryStyleEntry1 = mediaQueryContent[0].declarations[0];
      assert.equal(
        mediaQueryStyleEntry1.value,
        mediaQueryStyles.style1[breakpoint][mediaQueryStyleEntry1.property],
      );

      const mediaQueryStyleEntry2 = mediaQueryContent[1].declarations[0];
      assert.equal(
        mediaQueryStyleEntry2.value,
        mediaQueryStyles.style2[breakpoint][mediaQueryStyleEntry2.property],
      );
    });

    it('should not output empty styles', () => {
      const breakpoint = '@media (max-width: 600px)';
      const emptyStyles = StyleSheet.create({
        beforeBreakpoint: {
          [breakpoint]: {
            color: 'red'
          }
        },
        withEmptyPseudo: {
          color: 'red',
          ':hover': {}
        },
        all: {}
      });

      const css = StyleSheet.render();
      const parsedCss = parse(css);

      assert.equal(
        emptyStyles.all, '',
        'should return empty class string when style is empty'
      );
      assert.equal(
        parsedCss.stylesheet.rules.length, 2,
        'stylesheet should contain two rules'
      );
      assert.equal(
        parsedCss.stylesheet.rules[1].rules.length, 1,
        '[beforeBreakpoint]-media-query should contain one rule'
      );
    });

    it('handles nested pseudo selectors in media queries', () => {
      const breakpoint = '@media (max-width: 600px)';
      const styles = {
        base: {
          color: 'red',
          ':hover': {
            color: 'blue'
          },
          ':active': {
            color: 'papayawhip'
          },
          [breakpoint]: {
            color: 'orange',
            ':hover': {
              color: 'green'
            },
            ':active': {
              color: 'tomato'
            }
          }
        }
      };

      StyleSheet.create(styles);
      const css = StyleSheet.render({ pretty: true });
      const { rules } = parse(css).stylesheet;

      assert.equal(rules[0].declarations[0].value, styles.base.color);
      assert.equal(rules[1].declarations[0].value, styles.base[':hover'].color);
      assert.equal(rules[2].declarations[0].value, styles.base[':active'].color);

      // Media Query
      assert.equal(rules[3].type, 'media');
      const mediaRules = rules[3].rules;
      assert.equal(mediaRules[0].declarations[0].value, styles.base[breakpoint].color);
      assert.equal(mediaRules[1].declarations[0].value, styles.base[breakpoint][':hover'].color);
      assert.equal(mediaRules[2].declarations[0].value, styles.base[breakpoint][':active'].color);
    });
  });

  describe('#clear()', () => {
    beforeEach(() => {
      StyleSheet.clear();
    });

    it('clears the stylesheet store', () => {
      StyleSheet.create(style.basic);
      assert.equal(StyleSheet.clear(), true);
      assert.equal(StyleSheet.__stylesheet.size, 0);
    });
  });
});
<commit_msg>[test] create should be able to handle arrays as values<commit_after>import assert from 'assert';
import StyleSheet from '../';
import { parse } from 'css' ;
import * as style from './fixtures';

const unique = arr => [...new Set(arr)];
const values = obj => Object.keys(obj).map( key => obj[key] );

describe('stilr', () => {

  describe('#create(obj)', () => {
    beforeEach(() => {
      StyleSheet.clear();
    });

    it('creates an entry in the stylesheet', () => {
      const entries = Object.keys(style.basic);
      StyleSheet.create(style.basic);
      assert.equal(
        StyleSheet.__stylesheet.size,
        entries.length
      );
    });

    it('returns an object', () => {
      const styles = StyleSheet.create(style.basic);
      assert.equal( typeof styles, 'object' );
    });

    it('has the same keys', () => {
      const keys = Object.keys( StyleSheet.create(style.basic) );
      const originalKeys = Object.keys( style.basic );

      assert.equal(
        keys.join(''),
        originalKeys.join('')
      );
    });

    it('assigns the same class name to duplicate styles', () => {
      const styles = StyleSheet.create( style.duplicates );
      const classNames = Object.keys( styles );

      classNames.map(
        className => assert.equal( styles[classNames[0]], styles[className] )
      );
    });

    it('handles pseudo classes', () => {
      const styles = StyleSheet.create( style.pseudos );
      assert.equal(
        unique( values(styles) ).length,
        Object.keys(styles).length,
        `All classnames should be unique: .${ values( styles ).join(' .') }`
      );
    });

    it('handles media queries', () => {
      const styles = StyleSheet.create( style.mediaQueries );

      assert.equal(
        unique( values(styles) ).length,
        Object.keys(styles).length,
        `All classnames should be unique: .${ values( styles ).join(' .') }`
      );
    });

    it('accepts a alternative stylesheet', () => {
      const altStylesheet = new Map();
      const entries = Object.keys(style.basic);
      StyleSheet.create( style.basic, altStylesheet );

      StyleSheet.create(style.basic);
      assert.equal(
        altStylesheet.size,
        entries.length
      );

      assert.notEqual(
        altStylesheet,
        StyleSheet.__stylesheet
      );
    });

    it('assigns unique class names', () => {
      const uniqueStyles = StyleSheet.create({
        unique1: {
          justifyContent: 'center'
        },
        unique2: {
          alignItems: 'center'
        },
        unique3: {
          textAlign: 'center'
        },
        unique4: {
          color: 'red',
          ':hover': {
            color: 'green'
          }
        },
        unique5: {
          color: 'red',
          ':active': {
            color: 'green'
          }
        }
      });
      const keys = Object.keys(uniqueStyles);
      const classes = unique( values(uniqueStyles) );

      assert.equal(
        keys.length,
        classes.length
      );
    });

  });

  describe('#render()', () => {
    beforeEach(() => {
      StyleSheet.clear();
    });

    it('returns a string', () => {
      StyleSheet.create(style.basic);
      const stylesheet = StyleSheet.render();
      assert.equal( typeof stylesheet, 'string' );
    });

    it('is parseable css', () => {
      StyleSheet.create(style.basic);
      const parsedCss = parse( StyleSheet.render() );
      assert.ok( parsedCss );

      const renderedClassNames = parsedCss.stylesheet.rules.map( rule => rule.selectors[0] );

      for ( let className of StyleSheet.__stylesheet.keys() ) {
        assert.ok( !!~renderedClassNames.indexOf( `.${ className }` ), `.${ className } should be part of the rendered css classes: '${ renderedClassNames }'`);
      }
    });

    it('outputs pseudo classes correctly', () => {
      const hover = /(\._[\s\S]+)(:hover{)/g;

      StyleSheet.create({
        style: {
          color: 'tomato',
          ':hover': {
            color: 'red'
          }
        }
      });

      const css = StyleSheet.render();
      assert.ok(
        css.match(hover).length === 1
      );
    });

    it('outputs media queries correctly', () => {
      const breakpoint = '@media (max-width: 600px)';
      const mediaQueryStyles = {
        style1: {
          color: 'blue',
          [breakpoint]: {
            color: 'red'
          }
        },
        style2: {
          color: 'green',
          [breakpoint]: {
            color: 'blue'
          }
        }
      };

      StyleSheet.create(mediaQueryStyles);

      const css = StyleSheet.render();
      const rules = parse(css).stylesheet.rules;
      assert.equal(rules[0].type, 'rule', 'Rule should be before media queries');
      assert.equal(rules[2].type, 'media');
      assert.equal(rules[2].media, breakpoint.replace('@media ', ''));

      const mediaQueryContent = rules[2].rules;
      assert.equal(
        mediaQueryContent.length, 2,
        'Media query should contain two rules'
      );

      const mediaQueryStyleEntry1 = mediaQueryContent[0].declarations[0];
      assert.equal(
        mediaQueryStyleEntry1.value,
        mediaQueryStyles.style1[breakpoint][mediaQueryStyleEntry1.property],
      );

      const mediaQueryStyleEntry2 = mediaQueryContent[1].declarations[0];
      assert.equal(
        mediaQueryStyleEntry2.value,
        mediaQueryStyles.style2[breakpoint][mediaQueryStyleEntry2.property],
      );
    });

    it('should not output empty styles', () => {
      const breakpoint = '@media (max-width: 600px)';
      const emptyStyles = StyleSheet.create({
        beforeBreakpoint: {
          [breakpoint]: {
            color: 'red'
          }
        },
        withEmptyPseudo: {
          color: 'red',
          ':hover': {}
        },
        all: {}
      });

      const css = StyleSheet.render();
      const parsedCss = parse(css);

      assert.equal(
        emptyStyles.all, '',
        'should return empty class string when style is empty'
      );
      assert.equal(
        parsedCss.stylesheet.rules.length, 2,
        'stylesheet should contain two rules'
      );
      assert.equal(
        parsedCss.stylesheet.rules[1].rules.length, 1,
        '[beforeBreakpoint]-media-query should contain one rule'
      );
    });

    it('handles nested pseudo selectors in media queries', () => {
      const breakpoint = '@media (max-width: 600px)';
      const styles = {
        base: {
          color: 'red',
          ':hover': {
            color: 'blue'
          },
          ':active': {
            color: 'papayawhip'
          },
          [breakpoint]: {
            color: 'orange',
            ':hover': {
              color: 'green'
            },
            ':active': {
              color: 'tomato'
            }
          }
        }
      };

      StyleSheet.create(styles);
      const css = StyleSheet.render({ pretty: true });
      const { rules } = parse(css).stylesheet;

      assert.equal(rules[0].declarations[0].value, styles.base.color);
      assert.equal(rules[1].declarations[0].value, styles.base[':hover'].color);
      assert.equal(rules[2].declarations[0].value, styles.base[':active'].color);

      // Media Query
      assert.equal(rules[3].type, 'media');
      const mediaRules = rules[3].rules;
      assert.equal(mediaRules[0].declarations[0].value, styles.base[breakpoint].color);
      assert.equal(mediaRules[1].declarations[0].value, styles.base[breakpoint][':hover'].color);
      assert.equal(mediaRules[2].declarations[0].value, styles.base[breakpoint][':active'].color);
    });

    it('handles values as arrays', () => {
      const styles = {
        base: {
          boxShadow: [
            '1px 1px black',
            '0 0 5px red'
          ]
        }
      };
      StyleSheet.create(styles);

      const css = StyleSheet.render({ pretty: true });
      const { rules } = parse(css).stylesheet;
      assert.equal(rules[0].declarations[0].value, styles.base.boxShadow.join(','));
    });
  });

  describe('#clear()', () => {
    beforeEach(() => {
      StyleSheet.clear();
    });

    it('clears the stylesheet store', () => {
      StyleSheet.create(style.basic);
      assert.equal(StyleSheet.clear(), true);
      assert.equal(StyleSheet.__stylesheet.size, 0);
    });
  });
});
<|endoftext|>


<commit_before>var Operator = new function() {
	var operators = {
		add: '+', subtract: '-', multiply: '*', divide: '/', equals: '==',
		modulo: '%'
	};
	var operatorNames = {
		add: 'Addition', subtract: 'Subtraction', multiply: 'Multiplication',
		divide: 'Division', equals: 'Comparison', modulo: 'Modulo'
	};

	return {
		isOperator: function(symbol) {
			// As a convention, only add non static bean properties to
			// the documentation. static properties are all supposed to
			// be uppercase and constants.
			return symbol.params.length == 1 && !symbol.isStatic && (
					/^(add|subtract|multiply|divide|modulo)(\^[0-9])*$/.test(symbol.name)
					&& (symbol.operator != 'none')
				) || ( // equals
					symbol.name == 'equals'
					&& symbol.returns.length && symbol.returns[0].type == 'boolean'
				);
		},

		getOperator: function(symbol) {
			return operators[symbol.name.replace(/\^[0-9]$/,'')];
		}
	};
};<commit_msg>jsdoc template: fix Operator.isOperator's handling of == operators.<commit_after>var Operator = new function() {
	var operators = {
		add: '+', subtract: '-', multiply: '*', divide: '/', equals: '==',
		modulo: '%'
	};
	var operatorNames = {
		add: 'Addition', subtract: 'Subtraction', multiply: 'Multiplication',
		divide: 'Division', equals: 'Comparison', modulo: 'Modulo'
	};

	return {
		isOperator: function(symbol) {
			// As a convention, only add non static bean properties to
			// the documentation. static properties are all supposed to
			// be uppercase and constants.
			return symbol.params.length == 1 && !symbol.isStatic && (
					/^(add|subtract|multiply|divide|modulo)(\^[0-9])*$/.test(symbol.name)
					&& (symbol.operator != 'none')
				) || ( // equals
					symbol.name == 'equals'
					&& symbol.returns.length
					&& symbol.returns[0].type.toLowerCase() == 'boolean'
				);
		},

		getOperator: function(symbol) {
			return operators[symbol.name.replace(/\^[0-9]$/,'')];
		}
	};
};<|endoftext|>


<commit_before>RESP = $('#title');
URL = "https://student.p4ed.com/notas/dados/";

function _get_bonus(data, bimester)
{
    notas = data.Dados.DadosPagina.Materias[5].Frentes[0].NotasBimestre;
    if (notas.length <= bimester)
    {
        return 0;
    }
    return parseFloat(notas[bimester].Provas[0].Nota.replace(',', '.'));
}

function success(data)
{
    if (!data.Sucesso)
    {
        return displayError();
    }

    $('#title').html(data.Dados.Pessoa.Nome);
    $('#slider').show();
    $('#bimester').on('change', function()
                      {
                        setBimester(this.value);
                      });

    bonusList = [0, 0, 0, 0];
    for (i = 0; i < 4; i++)
    {
        bonusList[i] = _get_bonus(data, i);
    }

    $.each(data.Dados.DadosPagina.Materias, function (_, subject)
    {
        handleSubject(subject, bonusList);
    });

    setBimester(data.Dados.DadosPagina.Ciclos.length - 1);
}

function handleSubject(data, bonusList)
{
    if (data.Frentes.length)
    {
        $.each(data.Frentes, function (_, front)
        {
            handleFront(front, bonusList);
        });
    }

    else
    {
        handleFront(data, bonusList);
    }
}

function handleFront(data, bonusList)
{
    blacklist = ['Red', 'Rubeval', 'Victor Amorim'];
    blacklisted = false;
    $.each(blacklist, function (_, name)
    {
        blacklisted |= (data.Nome.indexOf(name) != -1);
    });

    if (!blacklisted)
    {
        grades = data.NotasBimestre.slice(0); // Make a copy

        // Parse grades
        hasTests = false;
        bimesters = [];

        for (i = 0; i < 4; i++)
        {
            grades.push({});
            bd = grades.shift();

            p1 = undefined;
            p2 = undefined;
            bonus = bonusList[i];

            if (bd && bd.Provas && bd.Provas.length)
            {
                hasTests = true;
                $.each(bd.Provas, function (_, test)
                {
                    if (test.Nome.indexOf('Prova 1') != -1)
                    {
                        p1 = parseFloat(test.Nota.replace(',', '.'))
                    }

                    else if (test.Nome.indexOf('Prova 2') != -1 && test.Respostas && test.Respostas.length)
                    {
                        p2 = parseFloat(test.Nota.replace(',', '.'))
                    }
                });
            }

            bimesters.push([p1, p2, bonus]);
        }

        if (hasTests)
        {
            for (i = 0; i < 4; i++)
            {
                boxHTML = '

' + data.Nome + ' - ' + (i + 1) + 'º Bimestre' + '
';

                bim = bimesters[i];
                p1 = bim[0];
                p2 = bim[1];
                bonus = bim[2];

                if (p1 == undefined)
                {
                    // Got no grades at all
                    boxHTML += '
Sem dados
';
                }

                else if (p2 == undefined)
                {
                    boxHTML += '
P1: ' + p1 + '
P2:';
                    // Calc how many questions you need
                    missingPoints = 12 - p1 - bonus;
                    boxHTML += ' você precisa de ' + missingPoints + ' ponto' + ((missingPoints >= 2) ? 's': '') + '
';

                    if (missingPoints > 10)
                    {
                        // Too bad
                        boxHTML += 'Situação irrecuperável, você já está de rec.';
                    }

                    else
                    {
                        lastMin = 0;
                        gotFirstGroup = 0;
                        temp = []
                        for (j = 3; j <= 24; j++)
                        {
                            value = 10.0 / j;
                            qmin = Math.ceil(missingPoints / value);
                            if (qmin > lastMin || j == 24)
                            {
                                if (gotFirstGroup)
                                {
                                    if (temp.length > 1)
                                    {
                                        last = temp.pop();
                                        temp.push('ou');
                                        temp.push(last);
                                        numsStr = temp.join(', ').replace(', ou,', ' ou');
                                    }

                                    else
                                    {
                                    numsStr = temp[0];
                                    }

                                    boxHTML += (gotFirstGroup > 1) ? '
' : '';
                                    boxHTML += 'Para ' + numsStr + ' questões, você precisa acertar ' + lastMin;
                                    temp = [];
                                }

                                gotFirstGroup++;
                            }

                            lastMin = qmin;
                            temp.push(j);
                        }
                    }
                }

                else
                {
                    boxHTML += '
P1: ' + p1 + '
P2: ' + p2 + '
= 0) ? 'verde">Situação: aprovado
' : 'vermelho">Situação: Rec por ' + dt + ' pontos
';
                }

                boxHTML += '
';

                $('#main').append(boxHTML);
            }
        }
    }
}

function setBimester(bimester)
{
    for (i = 0; i < 4; i++)
    {
        element = $('.bim_' + i);
        if (i == bimester)
        {
            element.show();
        }

        else
        {
            element.hide();
        }
    }
}

function handleError(handler, status, error)
{
    RESP.innerHTML = "Sinto muito, ocorreu um erro. Tente novamente.";
}

$.ajax({
  dataType: "json",
  url: URL,
  success: success,
  error: handleError
});
<commit_msg>Update popup.js<commit_after>RESP = $('#title');
URL = "https://student.p4ed.com/notas/dados/";

function _get_bonus(data, bimester)
{
    notas = data.Dados.DadosPagina.Materias[5].Frentes[0].NotasBimestre;
    if (notas.length <= bimester)
    {
        return 0;
    }
    return parseFloat(notas[bimester].Provas[0].Nota.replace(',', '.'));
}

function success(data)
{
    if (!data.Sucesso)
    {
        return displayError();
    }

    $('#title').html(data.Dados.Pessoa.Nome);
    $('#slider').show();
    $('#bimester').on('change', function()
                      {
                        setBimester(this.value);
                      });

    bonusList = [0, 0, 0, 0];
    for (i = 0; i < 4; i++)
    {
        bonusList[i] = _get_bonus(data, i);
    }

    $.each(data.Dados.DadosPagina.Materias, function (_, subject)
    {
        handleSubject(subject, bonusList);
    });

    setBimester(data.Dados.DadosPagina.Ciclos.length - 1);
}

function handleSubject(data, bonusList)
{
    if (data.Frentes.length)
    {
        $.each(data.Frentes, function (_, front)
        {
            handleFront(front, bonusList);
        });
    }

    else
    {
        handleFront(data, bonusList);
    }
}

function handleFront(data, bonusList)
{
    blacklist = ['Red', 'Rubeval', 'Victor Amorim'];
    blacklisted = false;
    $.each(blacklist, function (_, name)
    {
        blacklisted |= (data.Nome.indexOf(name) != -1);
    });

    if (!blacklisted)
    {
        grades = data.NotasBimestre.slice(0); // Make a copy

        // Parse grades
        hasTests = false;
        bimesters = [];

        for (i = 0; i < 4; i++)
        {
            grades.push({});
            bd = grades.shift();

            p1 = undefined;
            p2 = undefined;
            bonus = bonusList[i];

            if (bd && bd.Provas && bd.Provas.length)
            {
                hasTests = true;
                $.each(bd.Provas, function (_, test)
                {
                    if (test.Nome.indexOf('Prova 1') != -1)
                    {
                        p1 = parseFloat(test.Nota.replace(',', '.'))
                    }

                    else if (test.Nome.indexOf('Prova 2') != -1 && test.Respostas && test.Respostas.length)
                    {
                        p2 = parseFloat(test.Nota.replace(',', '.'))
                    }
                });
            }

            bimesters.push([p1, p2, bonus]);
        }

        if (hasTests)
        {
            for (i = 0; i < 4; i++)
            {
                boxHTML = '

' + data.Nome + ' - ' + (i + 1) + 'º Bimestre' + '
';

                bim = bimesters[i];
                p1 = bim[0];
                p2 = bim[1];
                bonus = bim[2];

                if (p1 == undefined)
                {
                    // Got no grades at all
                    boxHTML += '
Sem dados
';
                }

                else if (p2 == undefined)
                {
                    boxHTML += '
P1: ' + p1 + '
P2:';
                    // Calc how many questions you need
                    missingPoints = 12 - p1 - bonus * 2;
                    boxHTML += ' você precisa de ' + missingPoints + ' ponto' + ((missingPoints >= 2) ? 's': '') + '
';

                    if (missingPoints > 10)
                    {
                        // Too bad
                        boxHTML += 'Situação irrecuperável, você já está de rec.';
                    }

                    else
                    {
                        lastMin = 0;
                        gotFirstGroup = 0;
                        temp = []
                        for (j = 3; j <= 24; j++)
                        {
                            value = 10.0 / j;
                            qmin = Math.ceil(missingPoints / value);
                            if (qmin > lastMin || j == 24)
                            {
                                if (gotFirstGroup)
                                {
                                    if (temp.length > 1)
                                    {
                                        last = temp.pop();
                                        temp.push('ou');
                                        temp.push(last);
                                        numsStr = temp.join(', ').replace(', ou,', ' ou');
                                    }

                                    else
                                    {
                                    numsStr = temp[0];
                                    }

                                    boxHTML += (gotFirstGroup > 1) ? '
' : '';
                                    boxHTML += 'Para ' + numsStr + ' questões, você precisa acertar ' + lastMin;
                                    temp = [];
                                }

                                gotFirstGroup++;
                            }

                            lastMin = qmin;
                            temp.push(j);
                        }
                    }
                }

                else
                {
                    boxHTML += '
P1: ' + p1 + '
P2: ' + p2 + '
= 0) ? 'verde">Situação: aprovado
' : 'vermelho">Situação: Rec por ' + dt + ' pontos
';
                }

                boxHTML += '
';

                $('#main').append(boxHTML);
            }
        }
    }
}

function setBimester(bimester)
{
    for (i = 0; i < 4; i++)
    {
        element = $('.bim_' + i);
        if (i == bimester)
        {
            element.show();
        }

        else
        {
            element.hide();
        }
    }
}

function handleError(handler, status, error)
{
    RESP.innerHTML = "Sinto muito, ocorreu um erro. Tente novamente.";
}

$.ajax({
  dataType: "json",
  url: URL,
  success: success,
  error: handleError
});
<|endoftext|>


<commit_before>;(function(exports) {
  var library = {
    first: function(x) {
      return x[0];
    },
    rest: function(x) {
      return x.slice(1);
    },
    print: function(x) {
      console.log(x);
      return x;
    }
  };

  var Ctx = function(scope, parent) {
    this.scope = scope;
    this.parent = parent;
    this.get = function(identifier) {
      var item = this.scope[identifier];
      if (item !== undefined) {
        return item;
      } else if (this.parent !== undefined) {
        return this.parent.get(identifier);
      }
    };
  };

  var lambda = function(input, ctx) {
    return {
      type: "function",
      value: function(args) {
        var lambdaScope = input[1].reduce(function(acc, x, i) {
          acc[x.value] = args[i];
          return acc;
        }, {});
        return interpret(input[2], new Ctx(lambdaScope, ctx));
      }
    };
  };

  var fn = function(input, ctx) {
    return {
      type: "function",
      value: function(args) {
        return ctx.get(input.value).apply(undefined, args);
      }
    };
  };

  var interpret = function(input, ctx) {
    if (ctx === undefined) {
      return interpret(input, new Ctx(library));
    } else if (input instanceof Array) {
      if (input[0].value === "lambda") {
        return lambda(input, ctx);
      } else {
        var list = input.map(function(x) { return interpret(x, ctx); });
        if (list[0].type === "function") {
          return list[0].value(list.slice(1));
        } else {
          return list;
        }
      }
    } else if (input.type === "identifier") {
      if (typeof ctx.get(input.value) === "function") { // fn
        return fn(input, ctx);
      } else { // var lookup
        return ctx.get(input.value);
      }
    } else { // literal
      return input.value;
    }
  };

  var atDepth = function(output, depth) {
    if (depth === 0) {
      return output;
    } else {
      return atDepth(output[output.length - 1], depth - 1);
    }
  };

  var type = function(input) {
    if (!isNaN(parseFloat(input))) {
      return { type:'literal', value: parseFloat(input) };
    } else if (input[0] === '"' && input.slice(-1) === '"') {
      return { type:'literal', value: input.slice(1, -1) };
    } else {
      return { type:'identifier', value: input };
    }
  };

  var parenthesize = function(input) {
    var output = [];
    var depth = 0;
    while (input.length > 0) {
      var token = input.shift();
      if (token === "(") {
        atDepth(output, depth++).push([]);
      } else if (token === ")") {
        depth--;
      } else {
        atDepth(output, depth).push(type(token));
      }
    }

    return output.pop();
  };

  var tokenize = function(input) {
    return input.split('"').map(function(x, i) {
                   return i % 2 === 0 ? x : x.replace(/ /g, "spaceholder");
                 }).join('"')
                .replace(/\(/g, ' ( ')
                .replace(/\)/g, ' ) ')
                .trim()
                .split(/ +/)
                .map(function(x) {
                  return x.replace(/spaceholder/g, " ");
                });
  };

  var parse = function(input) {
    return parenthesize(tokenize(input));
  };

  exports.tinyLisp = {};
  exports.tinyLisp.parse = parse;
  exports.tinyLisp.interpret = interpret;
})(typeof exports === 'undefined' ? this : exports);
<commit_msg>Use instanceof rather than typeof to check for Function in interpret.<commit_after>;(function(exports) {
  var library = {
    first: function(x) {
      return x[0];
    },
    rest: function(x) {
      return x.slice(1);
    },
    print: function(x) {
      console.log(x);
      return x;
    }
  };

  var Ctx = function(scope, parent) {
    this.scope = scope;
    this.parent = parent;
    this.get = function(identifier) {
      var item = this.scope[identifier];
      if (item !== undefined) {
        return item;
      } else if (this.parent !== undefined) {
        return this.parent.get(identifier);
      }
    };
  };

  var lambda = function(input, ctx) {
    return {
      type: "function",
      value: function(args) {
        var lambdaScope = input[1].reduce(function(acc, x, i) {
          acc[x.value] = args[i];
          return acc;
        }, {});
        return interpret(input[2], new Ctx(lambdaScope, ctx));
      }
    };
  };

  var fn = function(input, ctx) {
    return {
      type: "function",
      value: function(args) {
        return ctx.get(input.value).apply(undefined, args);
      }
    };
  };

  var interpret = function(input, ctx) {
    if (ctx === undefined) {
      return interpret(input, new Ctx(library));
    } else if (input instanceof Array) {
      if (input[0].value === "lambda") {
        return lambda(input, ctx);
      } else {
        var list = input.map(function(x) { return interpret(x, ctx); });
        if (list[0].type === "function") {
          return list[0].value(list.slice(1));
        } else {
          return list;
        }
      }
    } else if (input.type === "identifier") {
      if (ctx.get(input.value) instanceof Function) { // prepare fn
        return fn(input, ctx);
      } else { // var lookup
        return ctx.get(input.value);
      }
    } else { // literal
      return input.value;
    }
  };

  var atDepth = function(output, depth) {
    if (depth === 0) {
      return output;
    } else {
      return atDepth(output[output.length - 1], depth - 1);
    }
  };

  var type = function(input) {
    if (!isNaN(parseFloat(input))) {
      return { type:'literal', value: parseFloat(input) };
    } else if (input[0] === '"' && input.slice(-1) === '"') {
      return { type:'literal', value: input.slice(1, -1) };
    } else {
      return { type:'identifier', value: input };
    }
  };

  var parenthesize = function(input) {
    var output = [];
    var depth = 0;
    while (input.length > 0) {
      var token = input.shift();
      if (token === "(") {
        atDepth(output, depth++).push([]);
      } else if (token === ")") {
        depth--;
      } else {
        atDepth(output, depth).push(type(token));
      }
    }

    return output.pop();
  };

  var tokenize = function(input) {
    return input.split('"').map(function(x, i) {
                   return i % 2 === 0 ? x : x.replace(/ /g, "spaceholder");
                 }).join('"')
                .replace(/\(/g, ' ( ')
                .replace(/\)/g, ' ) ')
                .trim()
                .split(/ +/)
                .map(function(x) {
                  return x.replace(/spaceholder/g, " ");
                });
  };

  var parse = function(input) {
    return parenthesize(tokenize(input));
  };

  exports.tinyLisp = {};
  exports.tinyLisp.parse = parse;
  exports.tinyLisp.interpret = interpret;
})(typeof exports === 'undefined' ? this : exports);
<|endoftext|>