<commit_before>'use strict';

var _ = require('lodash');
var rawbg = require('../plugins/rawbg')();

module.exports = function fitTreatmentsToBGCurve (ddata, settings) {

  function updateTreatmentBG(treatment) {

    function mgdlByTime() {

      var withBGs = _.filter(ddata.sgvs, function(d) {
        return d.mgdl > 39 || settings.isEnabled('rawbg');
      });

      var beforeTreatment = _.findLast(withBGs, function (d) {
        return d.mills <= treatment.mills;
      });
      var afterTreatment = _.find(withBGs, function (d) {
        return d.mills >= treatment.mills;
      });

      var mgdlBefore = mgdlValue(beforeTreatment) || calcRaw(beforeTreatment);
      var mgdlAfter = mgdlValue(afterTreatment) || calcRaw(afterTreatment);

      var calcedBG = 0;
      if (mgdlBefore && mgdlAfter) {
        calcedBG = (mgdlBefore + mgdlAfter) / 2;
      } else if (mgdlBefore) {
        calcedBG = mgdlBefore;
      } else if (mgdlAfter) {
        calcedBG = mgdlAfter;
      }

      return calcedBG || 180;
    }

    function mgdlValue (entry) {
      return entry && entry.mgdl >= 39 && Number(entry.mgdl);
    }

    function calcRaw (entry) {
      var raw;
      if (entry && settings.isEnabled('rawbg')) {
        var cal = _.last(ddata.cals);
        if (cal) {
          raw = rawbg.calc(entry, cal);
        }
      }
      return raw;
    }

    //to avoid checking if eventType is null everywhere, just default it here
    treatment.eventType = treatment.eventType || '';

    if (treatment.glucose && isNaN(treatment.glucose)) {
      console.warn('found an invalid glucose value', treatment);
    } else if (treatment.glucose && treatment.units) {
      if (treatment.units === 'mmol') {
        treatment.mmol = Number(treatment.glucose);
      } else {
        treatment.mgdl = Number(treatment.glucose);
      }
    } else if (treatment.glucose) {
      //no units, assume everything is the same
      console.warn('found a glucose value without any units, maybe from an old version?', _.pick(treatment, '_id', 'created_at', 'enteredBy'));
      var units = settings.units === 'mmol' ? 'mmol' : 'mgdl';
      treatment[units] = Number(treatment.glucose);
    } else {
      treatment.mgdl = mgdlByTime();
    }
  }

  _.each(ddata.treatments, updateTreatmentBG);

};

<commit_msg>disable a really noisy units warnings<commit_after>'use strict';

var _ = require('lodash');
var rawbg = require('../plugins/rawbg')();

module.exports = function fitTreatmentsToBGCurve (ddata, settings) {

  function updateTreatmentBG(treatment) {

    function mgdlByTime() {

      var withBGs = _.filter(ddata.sgvs, function(d) {
        return d.mgdl > 39 || settings.isEnabled('rawbg');
      });

      var beforeTreatment = _.findLast(withBGs, function (d) {
        return d.mills <= treatment.mills;
      });
      var afterTreatment = _.find(withBGs, function (d) {
        return d.mills >= treatment.mills;
      });

      var mgdlBefore = mgdlValue(beforeTreatment) || calcRaw(beforeTreatment);
      var mgdlAfter = mgdlValue(afterTreatment) || calcRaw(afterTreatment);

      var calcedBG = 0;
      if (mgdlBefore && mgdlAfter) {
        calcedBG = (mgdlBefore + mgdlAfter) / 2;
      } else if (mgdlBefore) {
        calcedBG = mgdlBefore;
      } else if (mgdlAfter) {
        calcedBG = mgdlAfter;
      }

      return calcedBG || 180;
    }

    function mgdlValue (entry) {
      return entry && entry.mgdl >= 39 && Number(entry.mgdl);
    }

    function calcRaw (entry) {
      var raw;
      if (entry && settings.isEnabled('rawbg')) {
        var cal = _.last(ddata.cals);
        if (cal) {
          raw = rawbg.calc(entry, cal);
        }
      }
      return raw;
    }

    //to avoid checking if eventType is null everywhere, just default it here
    treatment.eventType = treatment.eventType || '';

    if (treatment.glucose && isNaN(treatment.glucose)) {
      console.warn('found an invalid glucose value', treatment);
    } else if (treatment.glucose && treatment.units) {
      if (treatment.units === 'mmol') {
        treatment.mmol = Number(treatment.glucose);
      } else {
        treatment.mgdl = Number(treatment.glucose);
      }
    } else if (treatment.glucose) {
      //no units, assume everything is the same
      //console.warn('found a glucose value without any units, maybe from an old version?', _.pick(treatment, '_id', 'created_at', 'enteredBy'));
      var units = settings.units === 'mmol' ? 'mmol' : 'mgdl';
      treatment[units] = Number(treatment.glucose);
    } else {
      treatment.mgdl = mgdlByTime();
    }
  }

  _.each(ddata.treatments, updateTreatmentBG);

};

<|endoftext|>


<commit_before>/**
 * Validates space separated string against an array of accepted values.
 * @param {String} propName -- The name of the prop being validated for better error logging.
 * @param {String} propValue -- Space separated string (provided by the user)
 * @param {Array} validArr -- Array of values that are considered "valid"
 * @param {Boolean} responsive -- Enables validation of validArr values with '@sm', '@md', '@lg' added to them
 */
function validateProp(propValue, validArr, responsive = true) {
  let isValid = false;
  const strArr = propValue.split(' ');
  isValid = strArr.every((mod) => {
    const modValid = validArr.some((validStr) => {
      if (responsive) {
        return (mod === validStr) ||
        (mod === `${validStr}@sm`) ||
        (mod === `${validStr}@md`) ||
        (mod === `${validStr}@lg`);
      }

      return (mod === validStr);
    });
    if (!modValid) {
      console.error(`Invalid prop value: ${mod}`); // eslint-disable-line no-console
    }
    return modValid;
  });
  return isValid;
}

export default validateProp;
<commit_msg>refactor(prop validation): remove extra code<commit_after>/**
 * Validates space separated string against an array of accepted values.
 * @param {String} propName -- The name of the prop being validated for better error logging.
 * @param {String} propValue -- Space separated string (provided by the user)
 * @param {Array} validArr -- Array of values that are considered "valid"
 * @param {Boolean} responsive -- Enables validation of validArr values with '@sm', '@md', '@lg' added to them
 */
function validateProp(propValue, validArr, responsive = true) {
  const strArr = propValue.split(' ');
  return strArr.every((mod) => {
    const modValid = validArr.some((validStr) => {
      if (responsive) {
        return (mod === validStr) ||
        (mod === `${validStr}@sm`) ||
        (mod === `${validStr}@md`) ||
        (mod === `${validStr}@lg`);
      }

      return (mod === validStr);
    });
    if (!modValid) {
      console.error(`Invalid prop value: ${mod}`); // eslint-disable-line no-console
    }
    return modValid;
  });
}

export default validateProp;
<|endoftext|>


<commit_before>import createCampaignConfiguration from './createCampaignConfiguration'

const campaignTitle = '## COVID-19 Relief: Doctors Without Borders'
const campaignDescription = `
#### As COVID-19 continues to spread, it will stress health systems around the globe. In this phase of our [COVID-19 relief](https://tab.gladly.io/covid-19/), we're supporting [Doctors Without Borders](https://www.doctorswithoutborders.org/covid19) and their efforts to ensure access to quality healthcare around the world.
#### In response to COVID-19, Doctors Without Borders is fighting on multiple fronts—caring for patients, offering health education and mental health support, and providing training for vital infection control measures in health facilities around the world. Join us as we support their vital services by opening tabs and donating hearts.
`
const campaignEndTitle = '## Support for Doctors Without Borders'
const campaignEndDescription = `
#### With your help, we raised thousands of dollars to provide medical services through [Doctors Without Borders](https://www.doctorswithoutborders.org/covid19)! Thank you for helping health systems in their fight against COVID-19.
#### Share this achievement:
`
const campaignEndDescriptionTwo =
  '#### This is only part of [our relief efforts](https://tab.gladly.io/covid-19/) for this global health crisis—more to come soon.'

// Hardcode campaign data here.
const CURRENT_CAMPAIGN = createCampaignConfiguration({
  campaignId: 'MSFApril2020',
  charityId: '8f92a859-057f-462f-bb99-ad68a7caf5de',
  content: {
    titleMarkdown: campaignTitle,
    descriptionMarkdown: campaignDescription,
  },
  countMoneyRaised: false,
  countNewUsers: false,
  countTabsOpened: false,
  // Logic on when to end the campaign.
  endTriggers: {
    whenGoalAchieved: true,
    whenTimeEnds: false,
  },
  goal: {
    impactUnitSingular: 'heart',
    impactUnitPlural: 'hearts',
    impactVerbPastParticiple: 'donated',
    impactVerbPastTense: 'donated',
    limitProgressToTargetMax: true,
    numberSource: 'hearts', // One of: hearts, moneyRaised, newUsers, tabsOpened
    showProgressBarLabel: true,
    showProgressBarEndText: false,
    targetNumber: 20e6,
    // transformNumberSourceValue: moneyRaised => {
    //   return Math.floor(moneyRaised / 0.1)
    // },
  },
  // Modifications to the campaign when the campaign has
  // ended.
  onEnd: {
    content: {
      titleMarkdown: campaignEndTitle,
      descriptionMarkdown: campaignEndDescription,
      descriptionMarkdownTwo: campaignEndDescriptionTwo,
    },
    goal: {
      // Keep the progress bar label instead of the ending text.
      showProgressBarLabel: true,
      showProgressBarEndText: false,
    },
    showHeartsDonationButton: false,
    showSocialSharing: true,
    socialSharing: {
      url: 'https://tab.gladly.io/covid-19/',
      FacebookShareButtonProps: {
        quote:
          'We just raised thousands of dollars for Doctors Without Borders. And all we did was open browser tabs.',
      },
      RedditShareButtonProps: {
        title: 'Tabs transformed into vital healthcare',
      },
      TumblrShareButtonProps: {
        title: 'Tabs transformed into healthcare',
        caption:
          'We just raised thousands of dollars for Doctors Without Borders. And all we did was open browser tabs',
      },
      TwitterShareButtonProps: {
        title:
          'On @TabForACause, We just raised thousands of dollars for Doctors Without Borders (@MSF_USA). And all we did was open browser tabs. #tabsTransformed',
        related: ['@TabForACause'],
      },
    },
  },
  showCountdownTimer: false,
  showHeartsDonationButton: true,
  showProgressBar: true,
  showSocialSharing: false,
  // socialSharing: undefined,
  theme: {
    color: {
      main: '#e00',
      light: '#94989e',
    },
  },
  time: {
    start: '2020-04-27T16:00:00.000Z',
    end: '2020-05-11T18:00:00.000Z',
  },
})

/**
 * Return the CampaignConfiguration object for the current campaign.
 * @return {Promise<Object>} campaignConfig- see createCampaignConfiguration
 *   for structure.
 */
const getCurrentCampaignConfig = () => CURRENT_CAMPAIGN

// Outside modules shouldn't use this config. Instead, they should
// call getCampaign.js to get the CampaignData object.
export default getCurrentCampaignConfig
<commit_msg>Extend campaign end time<commit_after>import createCampaignConfiguration from './createCampaignConfiguration'

const campaignTitle = '## COVID-19 Relief: Doctors Without Borders'
const campaignDescription = `
#### As COVID-19 continues to spread, it will stress health systems around the globe. In this phase of our [COVID-19 relief](https://tab.gladly.io/covid-19/), we're supporting [Doctors Without Borders](https://www.doctorswithoutborders.org/covid19) and their efforts to ensure access to quality healthcare around the world.
#### In response to COVID-19, Doctors Without Borders is fighting on multiple fronts—caring for patients, offering health education and mental health support, and providing training for vital infection control measures in health facilities around the world. Join us as we support their vital services by opening tabs and donating hearts.
`
const campaignEndTitle = '## Support for Doctors Without Borders'
const campaignEndDescription = `
#### With your help, we raised thousands of dollars to provide medical services through [Doctors Without Borders](https://www.doctorswithoutborders.org/covid19)! Thank you for helping health systems in their fight against COVID-19.
#### Share this achievement:
`
const campaignEndDescriptionTwo =
  '#### This is only part of [our relief efforts](https://tab.gladly.io/covid-19/) for this global health crisis—more to come soon.'

// Hardcode campaign data here.
const CURRENT_CAMPAIGN = createCampaignConfiguration({
  campaignId: 'MSFApril2020',
  charityId: '8f92a859-057f-462f-bb99-ad68a7caf5de',
  content: {
    titleMarkdown: campaignTitle,
    descriptionMarkdown: campaignDescription,
  },
  countMoneyRaised: false,
  countNewUsers: false,
  countTabsOpened: false,
  // Logic on when to end the campaign.
  endTriggers: {
    whenGoalAchieved: true,
    whenTimeEnds: false,
  },
  goal: {
    impactUnitSingular: 'heart',
    impactUnitPlural: 'hearts',
    impactVerbPastParticiple: 'donated',
    impactVerbPastTense: 'donated',
    limitProgressToTargetMax: true,
    numberSource: 'hearts', // One of: hearts, moneyRaised, newUsers, tabsOpened
    showProgressBarLabel: true,
    showProgressBarEndText: false,
    targetNumber: 20e6,
    // transformNumberSourceValue: moneyRaised => {
    //   return Math.floor(moneyRaised / 0.1)
    // },
  },
  // Modifications to the campaign when the campaign has
  // ended.
  onEnd: {
    content: {
      titleMarkdown: campaignEndTitle,
      descriptionMarkdown: campaignEndDescription,
      descriptionMarkdownTwo: campaignEndDescriptionTwo,
    },
    goal: {
      // Keep the progress bar label instead of the ending text.
      showProgressBarLabel: true,
      showProgressBarEndText: false,
    },
    showHeartsDonationButton: false,
    showSocialSharing: true,
    socialSharing: {
      url: 'https://tab.gladly.io/covid-19/',
      FacebookShareButtonProps: {
        quote:
          'We just raised thousands of dollars for Doctors Without Borders. And all we did was open browser tabs.',
      },
      RedditShareButtonProps: {
        title: 'Tabs transformed into vital healthcare',
      },
      TumblrShareButtonProps: {
        title: 'Tabs transformed into healthcare',
        caption:
          'We just raised thousands of dollars for Doctors Without Borders. And all we did was open browser tabs',
      },
      TwitterShareButtonProps: {
        title:
          'On @TabForACause, We just raised thousands of dollars for Doctors Without Borders (@MSF_USA). And all we did was open browser tabs. #tabsTransformed',
        related: ['@TabForACause'],
      },
    },
  },
  showCountdownTimer: false,
  showHeartsDonationButton: true,
  showProgressBar: true,
  showSocialSharing: false,
  // socialSharing: undefined,
  theme: {
    color: {
      main: '#e00',
      light: '#94989e',
    },
  },
  time: {
    start: '2020-04-27T16:00:00.000Z',
    end: '2020-08-20T18:00:00.000Z',
  },
})

/**
 * Return the CampaignConfiguration object for the current campaign.
 * @return {Promise<Object>} campaignConfig- see createCampaignConfiguration
 *   for structure.
 */
const getCurrentCampaignConfig = () => CURRENT_CAMPAIGN

// Outside modules shouldn't use this config. Instead, they should
// call getCampaign.js to get the CampaignData object.
export default getCurrentCampaignConfig
<|endoftext|>


<commit_before>import io from 'socket.io-client';
import { eventChannel } from 'redux-saga';
import { fork, take, call, put, cancel } from 'redux-saga/effects';
import {
  login, logout, addUser, removeUser, newMessage, sendMessage, isTyping as typing, currentlyTyping,
} from '../actions/actions';

function connect() {
  const socket = io('http://localhost:3000');
  return new Promise(resolve => {
    socket.on('connect', () => {
      resolve(socket);
    });
  });
}

function subscribe(socket) {
  return eventChannel(emit => {
    socket.on('users.login', ({ username, usernames }) => {
      emit(addUser({ username, usernames }));
    });
    socket.on('users.logout', ({ username }) => {
      emit(removeUser({ username }));
    });
    socket.on('userTyping', ({ typingStatus, user, userStatus }) => {
      emit(currentlyTyping({ typingStatus, user, userStatus }));
    })
    socket.on('messages.new', ({ message }) => {
      emit(newMessage({ message }));
    });
    socket.on('disconnect', e => {
      // TODO: handle
    });
    return () => {};
  });
}

function* read(socket) {
  const channel = yield call(subscribe, socket);
  while (true) {
    let action = yield take(channel);
    yield put(action);
  }
}

function* write(socket) {
  while (true) {
    const { payload } = yield take(`${sendMessage}`);
    socket.emit('message', payload);
  }
}

function* userIsTyping(socket) {
  while (true) {
    const { payload } = yield take(`${typing}`);
    socket.emit('typing', payload);
  }
}

function* handleIO(socket) {
  yield fork(read, socket);
  yield fork(write, socket);
  yield fork(userIsTyping, socket);
}

/*
  `loginFlow` saga watches for login and logout events.
  While a user is logged in, loginFlow manages IO process.
  When a user logs out, the logout action is fired and is picked up
  by our saga which then cancels the task.
*/

function* loginFlow() {
  while (true) {
    let { payload } = yield take(`${login}`);
    const socket = yield call(connect);
    socket.emit('login', { username: payload.username });

    const task = yield fork(handleIO, socket);

    let action = yield take(`${logout}`);
    yield cancel(task);
    socket.emit('logout');
  }
}

export default function* rootSaga() {
  yield fork(loginFlow);
}
<commit_msg>feat(sagas/index.js): add new auth sagas to rootSaga<commit_after>import io from 'socket.io-client';
import { eventChannel } from 'redux-saga';
import { fork, take, call, put, cancel } from 'redux-saga/effects';
import {
  login,
  logout,
  addUser,
  removeUser,
  newMessage,
  sendMessage,
  isTyping as typing,
  currentlyTyping
} from '../actions/actions';

import { loginFlow, logoutFlow, registerFlow } from './auth';

function connect() {
  const socket = io('http://localhost:3000');
  return new Promise(resolve => {
    socket.on('connect', () => {
      resolve(socket);
    });
  });
}

function subscribe(socket) {
  return eventChannel(emit => {
    socket.on('users.login', ({ username, usernames }) => {
      emit(addUser({ username, usernames }));
    });
    socket.on('users.logout', ({ username }) => {
      emit(removeUser({ username }));
    });
    socket.on('userTyping', ({ typingStatus, user, userStatus }) => {
      emit(currentlyTyping({ typingStatus, user, userStatus }));
    });
    socket.on('messages.new', ({ message }) => {
      emit(newMessage({ message }));
    });
    socket.on('disconnect', e => {
      // TODO: handle
    });
    return () => {};
  });
}

function* read(socket) {
  const channel = yield call(subscribe, socket);
  while (true) {
    let action = yield take(channel);
    yield put(action);
  }
}

function* write(socket) {
  while (true) {
    const { payload } = yield take(`${sendMessage}`);
    socket.emit('message', payload);
  }
}

function* userIsTyping(socket) {
  while (true) {
    const { payload } = yield take(`${typing}`);
    socket.emit('typing', payload);
  }
}

function* handleIO(socket) {
  yield fork(read, socket);
  yield fork(write, socket);
  yield fork(userIsTyping, socket);
}

/*
  `loginFlow` saga watches for login and logout events.
  While a user is logged in, loginFlow manages IO process.
  When a user logs out, the logout action is fired and is picked up
  by our saga which then cancels the task.
*/

function* loginFlowSockets() {
  while (true) {
    let { payload } = yield take(`${login}`);
    const socket = yield call(connect);
    socket.emit('login', { username: payload.username });

    const task = yield fork(handleIO, socket);

    let action = yield take(`${logout}`);
    yield cancel(task);
    socket.emit('logout');
  }
}

export default function* rootSaga() {
  yield fork(loginFlowSockets);
  yield fork(loginFlow);
  yield fork(logoutFlow);
  yield fork(registerFlow);
}
<|endoftext|>


<commit_before>/**
 * Js-coding-standards
 *
 * @author      Robert Rossmann <rr.rossmann@me.com>
 * @copyright   2016 STRV
 * @license     http://choosealicense.com/licenses/bsd-3-clause  BSD-3-Clause License
 */

'use strict'

module.exports = {

  extends: [
    './recommended.js',
    './accessibility.js',
  ],

  rules: {
    'operator-linebreak': 0,
    'require-jsdoc': 0,
    // Disallow Use of console
    // Turned off for React apps, console is quite useful in browsers
    'no-console': 0,
  },

  plugins: [
    'react',
  ],

  // Configures the react plugin to treat some rules with regard to this specific React.js version
  settings: {
    react: {
      version: '15.5',
    },
  },
}
<commit_msg>Fix console still being turned off for react env<commit_after>/**
 * Js-coding-standards
 *
 * @author      Robert Rossmann <rr.rossmann@me.com>
 * @copyright   2016 STRV
 * @license     http://choosealicense.com/licenses/bsd-3-clause  BSD-3-Clause License
 */

'use strict'

module.exports = {

  extends: [
    './recommended.js',
    './accessibility.js',
  ],

  rules: {
    'operator-linebreak': 0,
    'require-jsdoc': 0,
  },

  plugins: [
    'react',
  ],

  // Configures the react plugin to treat some rules with regard to this specific React.js version
  settings: {
    react: {
      version: '15.5',
    },
  },
}
<|endoftext|>


<commit_before>/**
 * @module  permissions
 * @author  Andrea Jonus <andrea.jonus@caffeina.com>
 */

/*
Include methods used in this module dynamically to avoid that Titanium
static analysis doesn't include native-language methods.
 */
Ti.Calendar;
Ti.Media;
Ti.Contacts;
Ti.Geolocation;
Ti.Filesystem;

/**
 * @property config
 */
exports.config = _.extend({
	// Placeholder for future configurations
}, Alloy.CFG.T ? Alloy.CFG.permissions : {});

var PERMISSIONS_TYPES = [
	{ name: 'Calendar', proxy: 'Calendar'},
	{ name: 'Camera', proxy: 'Media'},
	{ name: 'Contacts', proxy: 'Contacts'},
	{ name: 'Location', proxy: 'Geolocation'},
	{ name: 'Storage', proxy: 'Filesystem'}
];

PERMISSIONS_TYPES.forEach(function(type) {
	exports['request' + type.name + 'Permissions'] = function(success, error) {
		success = _.isFunction(success) ? success : Alloy.Globals.noop;
		error = _.isFunction(error) ? error : Alloy.Globals.noop;

		var has, request;
		switch (type.name) {
			case 'Calendar':
				has     = Ti.Calendar.hasCalendarPermissions;
				request = Ti.Calendar.requestCalendarPermissions;
				break;

			case 'Camera':
				has     = Ti.Media.hasCameraPermissions;
				request = Ti.Media.requestCameraPermissions;
				break;

			case 'Contacts':
				has     = Ti.Contacts.hasContactsPermissions;
				request = Ti.Contacts.requestContactsPermissions;
				break;

			case 'Location':
				has     = Ti.Geolocation.hasLocationPermissions;
				request = Ti.Geolocation.requestLocationPermissions;
				break;

			case 'Storage':
				has     = Ti.Filesystem.hasStoragePermissions;
				request = Ti.Filesystem.requestStoragePermissions;
				break;
		}

		function requestHandler(res) {
			if (res.success === true) {
				success();
			} else {
				Ti.API.error('Permissions: Error while requesting ' + type.name + ' permissions:', res.error);
				error({
					message: L('error_' + type.name.toLowerCase() + '_permissions', 'Missing ' + type.name.toLowerCase() + ' permissions')
				});
			}
		}

		if (false == _.isFunction(Ti[type.proxy]["has" + type.name + "Permissions"]) || false == _.isFunction(Ti[type.proxy]["request" + type.name + "Permissions"])) {
			Ti.API.debug('Either of the functions [Ti.' + type.proxy + '.has' + type.name + 'Permissions(), Ti.' + type.proxy + '.request' + type.name + 'Permissions()] is missing');
			success();
			return;
		}

		if (Ti[type.proxy]["has" + type.name + "Permissions"]() !== true) {
			Ti[type.proxy]["request" + type.name + "Permissions"](requestHandler);
		} else {
			success();
		}
	};
});
<commit_msg>Dynamic code in permissions<commit_after>/**
 * @module  permissions
 * @author  Andrea Jonus <andrea.jonus@caffeina.com>
 */

/*
Include methods used in this module dynamically to avoid that Titanium
static analysis doesn't include native-language methods.
 */
Ti.Calendar;
Ti.Media;
Ti.Contacts;
Ti.Geolocation;
Ti.Filesystem;

/**
 * @property config
 */
exports.config = _.extend({
	// Placeholder for future configurations
}, Alloy.CFG.T ? Alloy.CFG.permissions : {});

var PERMISSIONS_TYPES = [
	{ name: 'Calendar', proxy: 'Calendar'},
	{ name: 'Camera', proxy: 'Media'},
	{ name: 'Contacts', proxy: 'Contacts'},
	{ name: 'Location', proxy: 'Geolocation'},
	{ name: 'Storage', proxy: 'Filesystem'}
];

PERMISSIONS_TYPES.forEach(function(type) {
	exports['request' + type.name + 'Permissions'] = function(success, error) {
		success = success || Alloy.Globals.noop;
		error = error || Alloy.Globals.noop;

		var has = "has" + type.name + "Permissions";
		var request = "request" + type.name + "Permissions";

		function requestHandler(res) {
			if (res.success === true) {
				success();
			} else {
				Ti.API.error('Permissions: Error while requesting ' + type.name + ' permissions:', res.error);
				error({
					message: L('error_' + type.name.toLowerCase() + '_permissions', 'Missing ' + type.name.toLowerCase() + ' permissions')
				});
			}
		}

		if (false === _.isFunction(Ti[type.proxy][has]) || false === _.isFunction(Ti[type.proxy][request])) {
			Ti.API.debug('Either of the functions [Ti.' + type.proxy + '.' + has + ', Ti.' + type.proxy + '.' + request + '] is missing');
			success();
			return;
		}

		if (Ti[type.proxy][has]() !== true) {
			Ti[type.proxy][request](requestHandler);
		} else {
			success();
		}
	};
});
<|endoftext|>


<commit_before>
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is guacamole-common-js.
 *
 * The Initial Developer of the Original Code is
 * Michael Jumper.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

// Guacamole namespace
var Guacamole = Guacamole || {};

/**
 * Dynamic on-screen keyboard. Given the URL to an XML keyboard layout file,
 * this object will download and use the XML to construct a clickable on-screen
 * keyboard with its own key events.
 *
 * @constructor
 * @param {String} url The URL of an XML keyboard layout file.
 */
Guacamole.OnScreenKeyboard = function(url) {

    // For each child of element, call handler defined in next
    function parseChildren(element, next) {

        var children = element.childNodes;
        for (var i=0; i<children.length; i++) {

            // Get child node
            var child = children[i];

            // Do not parse text nodes
            if (!child.tagName)
                continue;

            // Get handler for node
            var handler = next[child.tagName];

            // Call handler if defined
            if (handler)
                handler(child);

            // Throw exception if no handler
            else
                throw new Error(
                      "Unexpected " + child.tagName
                    + " within " + element.tagName
                );

        }

    }

    // Create keyboard
    var keyboard = document.createElement("div");
    keyboard.className = "guacamole-keyboard";

    // Retrieve keyboard XML
    var xmlhttprequest = new XMLHttpRequest();
    xmlhttprequest.open("GET", url, false);
    xmlhttprequest.send(null);

    var xml = xmlhttprequest.responseXML;

    if (xml) {

        var width = 640;
        var size = 20;
        var unit = width / size;

        function parse_row(e) {

            var row = document.createElement("div");
            row.className = "guacamole-keyboard-row";

            parseChildren(e, {

                "column": function(e) {
                    row.appendChild(parse_column(e));
                },

                "gap": function parse_gap(e) {

                    // Get attributes
                    var gap_size = e.attributes["size"];

                    // Create element
                    var gap = document.createElement("div");
                    gap.className = "guacamole-keyboard-gap";
                    gap.textContent = " ";

                    // Set gap size
                    if (gap_size)
                        gap.style.width = gap.style.height =
                            parseFloat(gap_size.value)*unit + "px";

                    row.appendChild(gap);

                },

                "key": function parse_key(e) {

                    // Get attributes
                    var key_size = e.attributes["size"];

                    // Create container element
                    var key_container = document.createElement("div");
                    key_container.style.display = "inline-block";
                    key_container.style.fontSize = unit + "px";
                    key_container.style.lineHeight = unit + "px";
                    key_container.style.height = unit + "px";

                    // Create element
                    var key = document.createElement("div");
                    key.className = "guacamole-keyboard-key";
                    key_container.appendChild(key);

                    // Set key size
                    if (key_size)
                        key_container.style.width = parseFloat(key_size.value)*unit + "px";
                    else
                        key_container.style.width = unit + "px";

                    parseChildren(e, {
                        "cap": function cap(e) {

                            // Get attributes
                            var required = e.attributes["if"];
                            var modifier = e.attributes["modifier"];
                            var keysym   = e.attributes["keysym"];
                            var sticky   = e.attributes["sticky"];

                            // Get content of key cap
                            var content = e.textContent;

                            // If no requirements, then show cap by default
                            if (!required) {
                                key.textContent = content;
                            }

                        }
                    });

                    row.appendChild(key_container);

                }

            });

            return row;

        }

        function parse_column(e) {

            var col = document.createElement("div");
            col.className = "guacamole-keyboard-column";

            var align = col.attributes["align"];

            if (align)
                col.style.textAlign = align.value;

            // Columns can only contain rows
            parseChildren(e, {
                "row": function(e) {
                    col.appendChild(parse_row(e));
                }
            });

            return col;

        }

        // Parse document
        var keyboard_element = xml.documentElement;
        if (keyboard_element.tagName != "keyboard")
            throw new Error("Root element must be keyboard");

        // Get attributes
        var keyboard_size = keyboard_element.attributes["size"];

        parseChildren(keyboard_element, {

            "row": function(e) {
                keyboard.appendChild(parse_row(e));
            },

            "column": function(e) {
                keyboard.appendChild(parse_column(e));
            }

        });

    }

    // Do not allow selection or mouse movement to propagate/register.
    keyboard.onselectstart =
    keyboard.onmousemove   =
    keyboard.onmouseup     =
    keyboard.onmousedown   =
    function(e) {
        e.stopPropagation();
        return false;
    };

    this.onkeypressed  = null;
    this.onkeyreleased = null;

    this.getElement = function() {
        return keyboard;
    };

};

Guacamole.OnScreenKeyboard.Key = function() {

    /**
     * Width of the key, relative to the size of the keyboard.
     */
    this.size = 1;

    /**
     * Whether this key is currently pressed.
     */
    this.pressed = false;

    /**
     * An associative map of all caps by modifier.
     */
    this.caps = {};

}

Guacamole.OnScreenKeyboard.Cap = function(text, keycode, modifier) {

    /**
     * Modifier represented by this keycap
     */
    this.modifier = 0;

    /**
     * The text to be displayed within this keycap
     */
    this.text = text;

    /**
     * The keycode this cap sends when its associated key is pressed/released
     */
    this.keycode = keycode;

    // Set modifier if provided
    if (modifier) this.modifier = modifier;

}
<commit_msg>Style key containers, add line-height.<commit_after>
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is guacamole-common-js.
 *
 * The Initial Developer of the Original Code is
 * Michael Jumper.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

// Guacamole namespace
var Guacamole = Guacamole || {};

/**
 * Dynamic on-screen keyboard. Given the URL to an XML keyboard layout file,
 * this object will download and use the XML to construct a clickable on-screen
 * keyboard with its own key events.
 *
 * @constructor
 * @param {String} url The URL of an XML keyboard layout file.
 */
Guacamole.OnScreenKeyboard = function(url) {

    // For each child of element, call handler defined in next
    function parseChildren(element, next) {

        var children = element.childNodes;
        for (var i=0; i<children.length; i++) {

            // Get child node
            var child = children[i];

            // Do not parse text nodes
            if (!child.tagName)
                continue;

            // Get handler for node
            var handler = next[child.tagName];

            // Call handler if defined
            if (handler)
                handler(child);

            // Throw exception if no handler
            else
                throw new Error(
                      "Unexpected " + child.tagName
                    + " within " + element.tagName
                );

        }

    }

    // Create keyboard
    var keyboard = document.createElement("div");
    keyboard.className = "guacamole-keyboard";

    // Retrieve keyboard XML
    var xmlhttprequest = new XMLHttpRequest();
    xmlhttprequest.open("GET", url, false);
    xmlhttprequest.send(null);

    var xml = xmlhttprequest.responseXML;

    if (xml) {

        var width = 640;
        var size = 20;
        var unit = width / size;

        function parse_row(e) {

            var row = document.createElement("div");
            row.className = "guacamole-keyboard-row";

            parseChildren(e, {

                "column": function(e) {
                    row.appendChild(parse_column(e));
                },

                "gap": function parse_gap(e) {

                    // Get attributes
                    var gap_size = e.attributes["size"];

                    // Create element
                    var gap = document.createElement("div");
                    gap.className = "guacamole-keyboard-gap";
                    gap.textContent = " ";

                    // Set gap size
                    if (gap_size)
                        gap.style.width = gap.style.height =
                            parseFloat(gap_size.value)*unit + "px";

                    row.appendChild(gap);

                },

                "key": function parse_key(e) {

                    // Get attributes
                    var key_size = e.attributes["size"];

                    // Create container element
                    var key_container = document.createElement("div");
                    key_container.className = "guacamole-keyboard-key-container";
                    key_container.style.display = "inline-block";
                    key_container.style.fontSize = unit + "px";
                    key_container.style.height = unit + "px";
                    key_container.style.lineHeight = unit + "px";

                    // Create element
                    var key = document.createElement("div");
                    key.className = "guacamole-keyboard-key";
                    key_container.appendChild(key);

                    // Set key size
                    if (key_size)
                        key_container.style.width = parseFloat(key_size.value)*unit + "px";
                    else
                        key_container.style.width = unit + "px";

                    parseChildren(e, {
                        "cap": function cap(e) {

                            // Get attributes
                            var required = e.attributes["if"];
                            var modifier = e.attributes["modifier"];
                            var keysym   = e.attributes["keysym"];
                            var sticky   = e.attributes["sticky"];

                            // Get content of key cap
                            var content = e.textContent;

                            // If no requirements, then show cap by default
                            if (!required) {
                                key.textContent = content;
                            }

                        }
                    });

                    row.appendChild(key_container);

                }

            });

            return row;

        }

        function parse_column(e) {

            var col = document.createElement("div");
            col.className = "guacamole-keyboard-column";

            var align = col.attributes["align"];

            if (align)
                col.style.textAlign = align.value;

            // Columns can only contain rows
            parseChildren(e, {
                "row": function(e) {
                    col.appendChild(parse_row(e));
                }
            });

            return col;

        }

        // Parse document
        var keyboard_element = xml.documentElement;
        if (keyboard_element.tagName != "keyboard")
            throw new Error("Root element must be keyboard");

        // Get attributes
        var keyboard_size = keyboard_element.attributes["size"];

        parseChildren(keyboard_element, {

            "row": function(e) {
                keyboard.appendChild(parse_row(e));
            },

            "column": function(e) {
                keyboard.appendChild(parse_column(e));
            }

        });

    }

    // Do not allow selection or mouse movement to propagate/register.
    keyboard.onselectstart =
    keyboard.onmousemove   =
    keyboard.onmouseup     =
    keyboard.onmousedown   =
    function(e) {
        e.stopPropagation();
        return false;
    };

    this.onkeypressed  = null;
    this.onkeyreleased = null;

    this.getElement = function() {
        return keyboard;
    };

};

Guacamole.OnScreenKeyboard.Key = function() {

    /**
     * Width of the key, relative to the size of the keyboard.
     */
    this.size = 1;

    /**
     * Whether this key is currently pressed.
     */
    this.pressed = false;

    /**
     * An associative map of all caps by modifier.
     */
    this.caps = {};

}

Guacamole.OnScreenKeyboard.Cap = function(text, keycode, modifier) {

    /**
     * Modifier represented by this keycap
     */
    this.modifier = 0;

    /**
     * The text to be displayed within this keycap
     */
    this.text = text;

    /**
     * The keycode this cap sends when its associated key is pressed/released
     */
    this.keycode = keycode;

    // Set modifier if provided
    if (modifier) this.modifier = modifier;

}
<|endoftext|>


<commit_before>$(document).ready(function() {

	// Upload a photo
	var uploadPhoto = $("#uploadPhotoBtn");

	function readURL(input) {
		if (input.files && input.files[0]) {
			var reader = new FileReader();

			reader.onload = function(event) {
				$("#userPhoto").attr("src", event.target.result);
			}

			reader.readAsDataURL(input.files[0]);
		}
	}

	uploadPhoto.on("change", function(event) {
		readURL(this);
	});

	//Filters - Grayscale

	var imageObj = new Image();

	var grayscaleBtn = document.getElementsByTagName("button")[0];
	var canvas = document.getElementById("imgCanvas");
	var originalPhoto = document.getElementById("userPhoto");
	var grayscaleRangeSlider = $("#grayscaleRange");
	var brightenRangeSlider = $("#brightenRange");
	var blurRangeSlider = $("#blurRange");
	var resetBtn = $("#resetBtn");
	var ctx = canvas.getContext("2d");

	function drawImage(imageObj) {

		var x = 0;
		var y = 0;
		var grayscaleVal = grayscaleRangeSlider.val() * 0.01;

		ctx.drawImage(imageObj, x, y); //namaluj mi nowy obraz na jakimś x i jakimś y

		var imageData = ctx.getImageData(x, y, imageObj.width, imageObj.height);
		//pobierz pozycję i wymiary z kontekstu
		var data = imageData.data;
		//zapisz te dane do zmiennej data, imageData.data przechowuje wartości poszczególnych pikseli (0-255)

		for (var i = 0; i < data.length; i += 4) {
			var brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
			// red
			data[i] = brightness / grayscaleVal;
			// green
			data[i + 1] = brightness / grayscaleVal;
			// blue
			data[i + 2] = brightness / grayscaleVal;
		}

		// overwrite original image
		ctx.putImageData(imageData, x, y); //przetworzone dane umieść z powrotem na danej pozycji x i y

	}

	grayscaleRangeSlider.on("input", function(event) {

		var imgList = $("#imgContainer").find("img");

		if (imgList.length == 1) {
			canvas.parentNode.insertBefore(originalPhoto.cloneNode(true), canvas);
		}

		$("#form1").find("img").css("display", "none");

		drawImage(document.getElementById("userPhoto"));
	});

	resetBtn.on("click", function(event) {
		ctx.drawImage(originalPhoto, 0, 0);
	});

	//przycinanie obrazu

	// window.onload(function() {

	// 	ctx.beginPath();
	// 	ctx.rect(canvas.width / 2, canvas.height / 2, 187, 251);
	// 	ctx.clip();
	// 	ctx.scale(2, 2);
	// 	ctx.drawImage(userPhoto);

	// });

	//Zoom-in, Zoom-out
	var zoomIn = document.getElementById("zoom-in");
	var zoomOut = document.getElementById("zoom-out");

	zoomIn.addEventListener("click", function(event) {
		ctx.scale(0.99, 0.99);
		ctx.drawImage(originalPhoto, 0, 0);

	}, false);

	zoomOut.addEventListener("click", function(event) {
		ctx.scale(1.01, 1.01);
		ctx.drawImage(originalPhoto, 0, 0);
	});

	//Move
	var moveTop = document.getElementById("moveTop");
	var moveRight = document.getElementById("moveRight");
	var moveLeft = document.getElementById("moveLeft");
	var moveBottom = document.getElementById("moveBottom");
	var x = 0;
	var y = 0;

	moveTop.addEventListener("click", function(event) {
		ctx.drawImage(originalPhoto, x, y);
		y -= 2;
		console.log(x, y);
	});

	moveRight.addEventListener("click", function(event) {
		ctx.drawImage(originalPhoto, x, y);
		x -= 2;
		console.log(x, y);
	});

	moveLeft.addEventListener("click", function(event) {
		ctx.drawImage(originalPhoto, x, y);
		x += 2;
		console.log(x, y);
	});

	moveBottom.addEventListener("click", function(event) {
		ctx.drawImage(originalPhoto, x, y);
		y += 2;
		console.log(x, y);
	});

});<commit_msg>Corrected code, start working on rotation.<commit_after>$(document).ready(function() {

	// Upload a photo
	var uploadPhoto = $("#uploadPhotoBtn");

	function readURL(input) {
		if (input.files && input.files[0]) {
			var reader = new FileReader();

			reader.onload = function(event) {
				$("#userPhoto").attr("src", event.target.result);
			}

			reader.readAsDataURL(input.files[0]);
		}
	}

	uploadPhoto.on("change", function(event) {
		readURL(this);
	});

	//Filters - Grayscale

	var imageObj = new Image();

	var grayscaleBtn = document.getElementsByTagName("button")[0];
	var canvas = document.getElementById("imgCanvas");
	var originalPhoto = document.getElementById("userPhoto");
	var grayscaleRangeSlider = $("#grayscaleRange");
	var brightenRangeSlider = $("#brightenRange");
	var blurRangeSlider = $("#blurRange");
	var resetBtn = $("#resetBtn");
	var ctx = canvas.getContext("2d");

	function drawImage(imageObj) {

		var x = 0;
		var y = 0;
		var grayscaleVal = grayscaleRangeSlider.val() * 0.01;

		ctx.drawImage(imageObj, x, y); //namaluj mi nowy obraz na jakimś x i jakimś y

		var imageData = ctx.getImageData(x, y, imageObj.width, imageObj.height);
		//pobierz pozycję i wymiary z kontekstu
		var data = imageData.data;
		//zapisz te dane do zmiennej data, imageData.data przechowuje wartości poszczególnych pikseli (0-255)

		for (var i = 0; i < data.length; i += 4) {
			var brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
			// red
			data[i] = brightness / grayscaleVal;
			// green
			data[i + 1] = brightness / grayscaleVal;
			// blue
			data[i + 2] = brightness / grayscaleVal;
		}

		// overwrite original image
		ctx.putImageData(imageData, x, y); //przetworzone dane umieść z powrotem na danej pozycji x i y

	}

	grayscaleRangeSlider.on("input", function(event) {

		var imgList = $("#imgContainer").find("img");

		if (imgList.length == 1) {
			canvas.parentNode.insertBefore(originalPhoto.cloneNode(true), canvas);
		}

		$("#form1").find("img").css("display", "none");

		drawImage(document.getElementById("userPhoto"));
	});

	resetBtn.on("click", function(event) {
		ctx.drawImage(originalPhoto, 0, 0);
	});

	//przycinanie obrazu

	// window.onload(function() {

	// 	ctx.beginPath();
	// 	ctx.rect(canvas.width / 2, canvas.height / 2, 187, 251);
	// 	ctx.clip();
	// 	ctx.scale(2, 2);
	// 	ctx.drawImage(userPhoto);

	// });

	//Zoom-in, Zoom-out
	var zoomIn = document.getElementById("zoom-in");
	var zoomOut = document.getElementById("zoom-out");

	zoomIn.addEventListener("click", function(event) {
		ctx.scale(0.99, 0.99);
		ctx.drawImage(originalPhoto, 0, 0);

	}, false);

	zoomOut.addEventListener("click", function(event) {
		ctx.scale(1.01, 1.01);
		ctx.drawImage(originalPhoto, 0, 0);
	}, false);

	//Move
	var moveTop = document.getElementById("moveTop");
	var moveRight = document.getElementById("moveRight");
	var moveLeft = document.getElementById("moveLeft");
	var moveBottom = document.getElementById("moveBottom");
	var x = 0;
	var y = 0;

	moveTop.addEventListener("click", function(event) {
		ctx.drawImage(originalPhoto, x, y);
		y -= 2;
	}, false);

	moveRight.addEventListener("click", function(event) {
		ctx.drawImage(originalPhoto, x, y);
		x -= 2;
	}, false);

	moveLeft.addEventListener("click", function(event) {
		ctx.drawImage(originalPhoto, x, y);
		x += 2;
	}, false);

	moveBottom.addEventListener("click", function(event) {
		ctx.drawImage(originalPhoto, x, y);
		y += 2;
	}, false);

	//Rotation
	var rotateControl = document.querySelector(".rotation-circle");
	console.log(rotateControl);
	rotateControl.addEventListener("click", function(event) {
		ctx.rotate(20*Math.PI/180);
	}, false);

});<|endoftext|>


<commit_before>(function() {
    angular.module("BoxBlackBox").factory("algorithmService", algorithmService);
    function algorithmService() {
        var service = {
            getAlgorithms : getAlgorithms
        };
        var algorithms = [];

        algorithms.push({"name": "a", "run" : a });
        algorithms.push({"name": "b", "run" : b });
        algorithms.push({"name": "d", "run" : d });
        algorithms.push({"name": "e", "run" : e });
        algorithms.push({"name": "f", "run" : f });
        algorithms.push({"name": "g", "run" : g });
        algorithms.push({"name": "h", "run" : h });
        algorithms.push({"name": "i", "run" : i });
        algorithms.push({"name": "j", "run" : j });
        algorithms.push({"name": "k", "run" : k });

        return service;

        ////////////////////////////////////////
        function getAlgorithms() {
            return algorithms;
        }

        function doBothWays(box1, box2, func){
            if(!func(box1, box2)) {
                return func(box2, box1);
            }else {
                return true;
            }
        }

        //fine for everything except the plus sign
        function a(box1, box2) {
            return doBothWays(box1, box2, function(box1, box2) {
                if(((box1.y >= box2.y && box1.x >= box2.x) &&
                    (box1.y < (box2.y + box2.height) && box1.x < (box2.x + box2.width) )) ||
                    ((box1.y >= box2.y && box1.x + box1.width <= box2.x + box2.width) &&
                    (box1.y < (box2.y + box2.height) && box1.x + box1.width > box2.x))) {

                    return true;
                }
                return false;
            });

        }

        //correct answer without reversing
        function b(box2, box1) {
            if(((box1.y >= box2.y && box1.x >= box2.x) &&
                (box1.y < (box2.y + box2.height) && box1.x < (box2.x + box2.width) )) ||
                ((box1.y >= box2.y && box1.x + box1.width <= box2.x + box1.width) &&
                (box1.y < (box2.y + box2.height) && box1.x + box1.width < box2.x)) ||
                ((box1.y < box2.y && box1.x > box2.x ) &&
                ((box1.y + box1.height) > (box2.y + box2.height) &&
                (box1.x + box1.width) < (box2.x + box2.width)))) {

                return true;
            }
            return false;
        }

        //true unless rectangles fail to overlap in both planes (so we get too many ‘true’ answers).
        function d(box1, box2) {
            if((box1.x < (box2.x + box2.width) &&
                (box1.x + box1.width) > box2.x ) ||
                (box1.y < (box2.y + box2.height) &&
                (box1.y + box1.height) > box2.y )){

                return true;
            }
            return false;
        }

        //correct answer but also any touching [edge/vertex] is considered an overlap – incorrect according to spec
        function e(box1, box2) {
            if(box1.x <= (box2.x + box2.width) &&
                (box1.x + box1.width) >= box2.x  &&
                box1.y <= (box2.y + box2.height) &&
                (box1.y + box1.height) >= box2.y ){

                return true;
            }
            return false;
        }

        //correct answer but out by one errors?  Is there an ‘out-by-one’ error available without duplicating ‘e’?
        function f(box1, box2) {
            box2 = {
                "x" : box2.x,
                "y" : box2.y,
                "width" : box1.width -1,
                "height" : box1.height -1,
            }
            if(box1.x < (box2.x + box2.width) &&
                (box1.x + box1.width) > box2.x  &&
                box1.y < (box2.y + box2.height) &&
                (box1.y + box1.height) > box2.y ){

                return true;
            }
            return false;
        }

        //any vertex inside the area of the opposite rectangle is an overlap, and nothing else is
        //only plus sign and identical rectangles fail
        function g(box1, box2) {
            return doBothWays(box1, box2, function(box1, box2) {
                if((box1.x > box2.x && box1.x < (box2.x + box2.width)) ||
                    (box1.y > box2.y && box1.y < (box2.y + box2.height)) ||
                    ((box1.x + box1.width) > box2.x && (box1.x + box1.width) < (box2.x + box2.width)) ||
                    ((box1.y + box1.height) > box2.y && (box1.y + box1.height)< (box2.y + box2.height))) {
                    return true;
                }
                return false;

            });
        }

        // any vertex of B inside rectangle A
        //plus sign, identical rectangles and B bigger than A fail
        function h(box2, box1) {
            if((box1.x > box2.x && box1.x < (box2.x + box2.width)) ||
                    (box1.y > box2.y && box1.y < (box2.y + box2.height)) ||
                    ((box1.x + box1.width) > box2.x && (box1.x + box1.width) < (box2.x + box2.width)) ||
                    ((box1.y + box1.height) > box2.y && (box1.y + box1.height)< (box2.y + box2.height))) {
                    return true;
                }
                return false;
        }

        //My Way
        function i(box1, box2) {
            if(box1.x < (box2.x + box2.width) &&
                (box1.x + box1.width) > box2.x  &&
                box1.y < (box2.y + box2.height) &&
                (box1.y + box1.height) > box2.y ){

                return true;
            }
            return false;
        }

        //The highway
        function j(box1, box2) {
            return doBothWays(box1, box2, function(box1, box2) {
                if(((box1.y >= box2.y && box1.x >= box2.x) &&
                    (box1.y < (box2.y + box2.height) && box1.x < (box2.x + box2.width) )) ||
                    ((box1.y >= box2.y && box1.x + box1.width <= box2.x + box2.width) &&
                    (box1.y < (box2.y + box2.height) && box1.x + box1.width > box2.x)) ||
                    ((box1.y < box2.y && box1.x > box2.x ) &&
                    ((box1.y + box1.height) > (box2.y + box2.height) &&
                    (box1.x + box1.width) < (box2.x + box2.width)))) {

                    return true;
                }
                return false;
            })
        }

        //Mixed up x/y width/height
        function k(box1, box2) {
            if(box1.x < (box2.x + box2.height) &&
                (box1.x + box1.height) > box2.x  &&
                box1.y < (box2.y + box2.width) &&
                (box1.y + box1.width) > box2.y ){

                return true;
            }
            return false;
        }

    }
})();
<commit_msg>Removed algorithm d fixes #6<commit_after>(function() {
    angular.module("BoxBlackBox").factory("algorithmService", algorithmService);
    function algorithmService() {
        var service = {
            getAlgorithms : getAlgorithms
        };
        var algorithms = [];

        algorithms.push({"name": "a", "run" : a });
        algorithms.push({"name": "b", "run" : b });
        // algorithms.push({"name": "d", "run" : d });
        algorithms.push({"name": "e", "run" : e });
        algorithms.push({"name": "f", "run" : f });
        algorithms.push({"name": "g", "run" : g });
        algorithms.push({"name": "h", "run" : h });
        algorithms.push({"name": "i", "run" : i });
        algorithms.push({"name": "j", "run" : j });
        algorithms.push({"name": "k", "run" : k });

        return service;

        ////////////////////////////////////////
        function getAlgorithms() {
            return algorithms;
        }

        function doBothWays(box1, box2, func){
            if(!func(box1, box2)) {
                return func(box2, box1);
            }else {
                return true;
            }
        }

        //fine for everything except the plus sign
        function a(box1, box2) {
            return doBothWays(box1, box2, function(box1, box2) {
                if(((box1.y >= box2.y && box1.x >= box2.x) &&
                    (box1.y < (box2.y + box2.height) && box1.x < (box2.x + box2.width) )) ||
                    ((box1.y >= box2.y && box1.x + box1.width <= box2.x + box2.width) &&
                    (box1.y < (box2.y + box2.height) && box1.x + box1.width > box2.x))) {

                    return true;
                }
                return false;
            });

        }

        //correct answer without reversing
        function b(box2, box1) {
            if(((box1.y >= box2.y && box1.x >= box2.x) &&
                (box1.y < (box2.y + box2.height) && box1.x < (box2.x + box2.width) )) ||
                ((box1.y >= box2.y && box1.x + box1.width <= box2.x + box1.width) &&
                (box1.y < (box2.y + box2.height) && box1.x + box1.width < box2.x)) ||
                ((box1.y < box2.y && box1.x > box2.x ) &&
                ((box1.y + box1.height) > (box2.y + box2.height) &&
                (box1.x + box1.width) < (box2.x + box2.width)))) {

                return true;
            }
            return false;
        }

        // //true unless rectangles fail to overlap in both planes (so we get too many ‘true’ answers).
        // function d(box1, box2) {
        //     if((box1.x < (box2.x + box2.width) &&
        //         (box1.x + box1.width) > box2.x ) ||
        //         (box1.y < (box2.y + box2.height) &&
        //         (box1.y + box1.height) > box2.y )){

        //         return true;
        //     }
        //     return false;
        // }

        //correct answer but also any touching [edge/vertex] is considered an overlap – incorrect according to spec
        function e(box1, box2) {
            if(box1.x <= (box2.x + box2.width) &&
                (box1.x + box1.width) >= box2.x  &&
                box1.y <= (box2.y + box2.height) &&
                (box1.y + box1.height) >= box2.y ){

                return true;
            }
            return false;
        }

        //correct answer but out by one errors?  Is there an ‘out-by-one’ error available without duplicating ‘e’?
        function f(box1, box2) {
            box2 = {
                "x" : box2.x,
                "y" : box2.y,
                "width" : box1.width -1,
                "height" : box1.height -1,
            }
            if(box1.x < (box2.x + box2.width) &&
                (box1.x + box1.width) > box2.x  &&
                box1.y < (box2.y + box2.height) &&
                (box1.y + box1.height) > box2.y ){

                return true;
            }
            return false;
        }

        //any vertex inside the area of the opposite rectangle is an overlap, and nothing else is
        //only plus sign and identical rectangles fail
        function g(box1, box2) {
            return doBothWays(box1, box2, function(box1, box2) {
                if((box1.x > box2.x && box1.x < (box2.x + box2.width)) ||
                    (box1.y > box2.y && box1.y < (box2.y + box2.height)) ||
                    ((box1.x + box1.width) > box2.x && (box1.x + box1.width) < (box2.x + box2.width)) ||
                    ((box1.y + box1.height) > box2.y && (box1.y + box1.height)< (box2.y + box2.height))) {
                    return true;
                }
                return false;

            });
        }

        // any vertex of B inside rectangle A
        //plus sign, identical rectangles and B bigger than A fail
        function h(box2, box1) {
            if((box1.x > box2.x && box1.x < (box2.x + box2.width)) ||
                    (box1.y > box2.y && box1.y < (box2.y + box2.height)) ||
                    ((box1.x + box1.width) > box2.x && (box1.x + box1.width) < (box2.x + box2.width)) ||
                    ((box1.y + box1.height) > box2.y && (box1.y + box1.height)< (box2.y + box2.height))) {
                    return true;
                }
                return false;
        }

        //My Way
        function i(box1, box2) {
            if(box1.x < (box2.x + box2.width) &&
                (box1.x + box1.width) > box2.x  &&
                box1.y < (box2.y + box2.height) &&
                (box1.y + box1.height) > box2.y ){

                return true;
            }
            return false;
        }

        //The highway
        function j(box1, box2) {
            return doBothWays(box1, box2, function(box1, box2) {
                if(((box1.y >= box2.y && box1.x >= box2.x) &&
                    (box1.y < (box2.y + box2.height) && box1.x < (box2.x + box2.width) )) ||
                    ((box1.y >= box2.y && box1.x + box1.width <= box2.x + box2.width) &&
                    (box1.y < (box2.y + box2.height) && box1.x + box1.width > box2.x)) ||
                    ((box1.y < box2.y && box1.x > box2.x ) &&
                    ((box1.y + box1.height) > (box2.y + box2.height) &&
                    (box1.x + box1.width) < (box2.x + box2.width)))) {

                    return true;
                }
                return false;
            })
        }

        //Mixed up x/y width/height
        function k(box1, box2) {
            if(box1.x < (box2.x + box2.height) &&
                (box1.x + box1.height) > box2.x  &&
                box1.y < (box2.y + box2.width) &&
                (box1.y + box1.width) > box2.y ){

                return true;
            }
            return false;
        }

    }
})();
<|endoftext|>


<commit_before>'use strict';

window.addEventListener('DOMContentLoaded', function load() {
  window.removeEventListener('DOMContentLoaded', load);

  if ('serviceWorker' in navigator) {
    document.getElementById('check-controller').onclick = function() {
      if (!navigator.serviceWorker.controller) {
        dump('Client context: no navigator.serviceWorker.controller object!\n');
        return;
      }
      dump('Client context: navigator.serviceWorker.controller.state is ' +
           (navigator.serviceWorker.controller.state)+ '\n');
    };

    document.getElementById('check-registration').onclick = function() {
      navigator.serviceWorker.getRegistration().then(swr => {
        if (!swr) {
          return;
        }
        if (swr.installing) {
          dump('Client context: registration has an installing worker (' +
               swr.installing.state + ')!\n');
        }
        if (swr.waiting) {
          dump('Client context: registration has an waiting worker (' +
               swr.waiting.state + ')!\n');
        }
        if (swr.active) {
          dump('Client context: registration has an active worker (' +
               swr.active.state + ')!\n');
        }
      });
    };

    document.getElementById('unregister-registration').onclick = function() {
      navigator.serviceWorker.getRegistration().then(swr => {
        if (!swr) {
          return;
        }
        swr.unregister().then(result => {
          dump('Client context: unregister registration ' +
               (result ? 'succeed' : 'failed') + '!\n');
        });
      });
    };

    navigator.serviceWorker.register('js/service.js').then(
      swr => {
        if (swr.installing) {
          dump('Client context: registration has an installing worker (' +
               swr.installing.state + ')!\n');
        }
        if (swr.waiting) {
          dump('Client context: registration has an waiting worker (' +
               swr.waiting.state + ')!\n');
        }
        if (swr.active) {
          dump('Client context: registration has an active worker (' +
               swr.active.state + ')!\n');
        }
      },
      error => {
        dump('Client context: ' + error + '\n');
      });
  }
});
<commit_msg>Add some logging to the getRegistration() function<commit_after>'use strict';

window.addEventListener('DOMContentLoaded', function load() {
  window.removeEventListener('DOMContentLoaded', load);

  if ('serviceWorker' in navigator) {
    document.getElementById('check-controller').onclick = function() {
      if (!navigator.serviceWorker.controller) {
        dump('Client context: no navigator.serviceWorker.controller object!\n');
        return;
      }
      dump('Client context: navigator.serviceWorker.controller.state is ' +
           (navigator.serviceWorker.controller.state)+ '\n');
    };

    document.getElementById('check-registration').onclick = function() {
      navigator.serviceWorker.getRegistration().then(swr => {
        if (!swr) {
          dump('Client context: no navigator.serviceWorker.getRegistration() result!\n');
          return;
        }
        if (swr.installing) {
          dump('Client context: registration has an installing worker (' +
               swr.installing.state + ')!\n');
        }
        if (swr.waiting) {
          dump('Client context: registration has an waiting worker (' +
               swr.waiting.state + ')!\n');
        }
        if (swr.active) {
          dump('Client context: registration has an active worker (' +
               swr.active.state + ')!\n');
        }
      });
    };

    document.getElementById('unregister-registration').onclick = function() {
      navigator.serviceWorker.getRegistration().then(swr => {
        if (!swr) {
          dump('Client context: no navigator.serviceWorker.getRegistration() result!\n');
          return;
        }
        swr.unregister().then(result => {
          dump('Client context: unregister registration ' +
               (result ? 'succeed' : 'failed') + '!\n');
        });
      });
    };

    navigator.serviceWorker.register('js/service.js').then(
      swr => {
        if (swr.installing) {
          dump('Client context: registration has an installing worker (' +
               swr.installing.state + ')!\n');
        }
        if (swr.waiting) {
          dump('Client context: registration has an waiting worker (' +
               swr.waiting.state + ')!\n');
        }
        if (swr.active) {
          dump('Client context: registration has an active worker (' +
               swr.active.state + ')!\n');
        }
      },
      error => {
        dump('Client context: ' + error + '\n');
      });
  }
});
<|endoftext|>


<commit_before>/**
*	@module com.spinal.ui
*	@author Patricio Ferreira <3dimentionar@gmail.com>
**/
define(['core/spinal',
		'util/string',
		'util/exception/ui',
		'templates/spinal',
		'libs/bootstrap'], function(Spinal, StringUtil, UIException) {

	/**
	*	Define a generic view interface that extends classic Backbone.View
	*	@namespace com.spinal.ui
	*	@class com.spinal.ui.View
	*	@extends Spinal.Backbone.View
	*
	*	@requires com.spinal.core.Spinal
	*	@requires com.spinal.util.StringUtil
	*	@requires com.spinal.util.exception.UIException
	*	@requires templates.spinal
	*	@requires libs.bootstrap
	**/
	var View = Spinal.namespace('com.spinal.ui.View', Backbone.View.inherit({

		/**
		*	Identifier
		*	@public
		*	@property id
		*	@type String
		**/
		id: null,

		/**
		*	Events
		*	@public
		*	@property events
		*	@type Object
		**/
		events: {},

		/**
		*	Internal CSS className
		*	@public
		*	@property className
		*	@type String
		**/
		className: 'ui-view',

		/**
		*	Render Method
		*	@public
		*	@property method
		*	@type String
		**/
		method: 'append',

		/**
		*	Parent Reference
		*	@private
		*	@property _parent
		*	@type {com.spinal.ui.View}
		**/
		_parent: null,

		/**
		*	Theme Class name
		*	@private
		*	@property _theme
		*	@type String
		**/
		_theme: null,

		/**
		*	Internal Compiled template
		*	@private
		*	@property _tpl
		*	@type Function
		**/
		_tpl: null,

		/**
		*	Constructor
		*	@method constructor
		*	@param [options] {Object} View Options
		**/
		constructor: function(options) {
			options || (options = {});
			Backbone.View.apply(this, arguments);
			this.id = (options.id) ? options.id : (this.$el.attr('id')) ? this.$el.attr('id') : null;
			if(options.autoId) this.id = StringUtil.uuid();
			this.$el.attr('id', this.id);
		},

		/**
		*	Initialize
		*	@public
		*	@chainable
		*	@method initialize
		*	@param options {Object} view options
		*	@return {com.spinal.ui.View}
		**/
		initialize: function(options) {
			options || (options = {});
			this._valid(options);
			if(options.el) this.$el.addClass(this.className);
			if(options.theme) { this._theme = options.theme; this.$el.addClass(this._theme); }
			if(options.method) this.method = options.method;
			if(options.template) this._tpl = this._compile(options.template);
			return this;
		},

		/**
		*	Validates parameters passed to the contructor function of this class.
		*	@private
		*	@method _valid
		*	@param attrs {Object} attributes
		*	@return Boolean
		**/
		_valid: function(attrs) {
			attrs || (attrs = {});
			if(attrs.id && !_.isString(attrs.id)) throw new UIException('InvalidIDType');
			if(attrs.model && !(attrs.model instanceof Backbone.Model)) throw new UIException('InvalidModelType');
			if(attrs.method && !(View.RENDER[attrs.method])) throw new UIException('UnsupportedRenderMethod', { method: 'non-existent-method' });
			return true;
		},

		/**
		*	Default before render hook
		*	@private
		*	@method _beforeRender
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		_beforeRender: function(opts) {
			if(!this._parent) throw new UIException('SuccessorNotSpecified');
			if(!(this._parent instanceof Spinal.com.spinal.ui.Container)) throw new UIException('InvalidSuccessorType');
			if(this.id && !this._parent.findById(this.id)) throw new UIException('UIStackViolation', {
				viewId: 'view-error', succesorId: 'container-declared-inline'
			});
			return this;
		},

		/**
		*	Compiles and build the template function used by this view
		*	@private
		*	@method _compile
		*	@param tpl {Function} template to be included as child inside the original view root DOM element
		*	@return Function
		**/
		_compile: function(tpl) {
			if(!tpl || (!_.isString(tpl) && !_.isFunction(tpl))) return null;
			return (_.isString(tpl)) ? _.template(tpl) : tpl;
		},

		/**
		*	Default strategy to setup data for templating
		*	@public
		*	@method data
		*	@param [o] {Object} default data to pass to the template
		*	@return Object
		**/
		data: function(o) {
			o || (o = {});
			return (this.model) ? this.model.toJSON() :
				((this._parent && this._parent.model) ? this._parent.model.toJSON() : o);
		},

		/**
		*	Default strategy to project model's data onto the template to generates HTML content
		*	@public
		*	@method template
		*	@param [tpl] {String} HTML template
		*	@param [data] {Object} template data
		*	@return String
		**/
		template: function(tpl, data) {
			if(_.isObject(tpl)) { data = tpl; tpl = null; }
			tpl = (tpl) ? this._compile(tpl) : this._tpl;
			return (tpl) ? this.$el.html(tpl(this.data(data))) : this.$el;
		},

		/**
		*	Render View
		*	@public
		*	@chainable
		*	@method render
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		render: function(opts) {
			opts || (opts = {});
			this._beforeRender(arguments).detach();
			var m = (opts.method && (View.RENDER[opts.method])) ? opts.method : this.method;
			this._parent._targetEl()[m](this.template(this._tpl));
			if(!opts.silent) this.trigger(View.EVENTS.render, { view: this });
			return this.delegateEvents();
		},

		/**
		*	Update View
		*	@public
		*	@chainable
		*	@method update
		*	@param model {Backbone.Model}
		*	@param value {Object} value that has changed
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		update: function(model, value, opts) {
			if(!opts || !opts.silent) this.trigger(View.EVENTS.update, { view: this });
			return this;
		},

		/**
		*	Change Theme set in this view
		*	@public
		*	@method theme
		*	@param themeName {String} theme name
		*	@return {com.spinal.ui.View}
		**/
		theme: function(themeName) {
			if(!themeName || !_.isString(themeName)) return this;
			this.$el.removeClass(this._theme).addClass(themeName);
			this._theme = themeName;
			return this;
		},

		/**
		*	Perform a look up of the closest successor in the view hierarchery using the id passed as parameter.
		*	If the successor is not found, the method will give up returning null.
		*	@public
		*	@chainable
		*	@method lookup
		*	@param id {String} Successor id
		*	@return {com.spinal.ui.View}
		**/
		lookup: function(id) {
			if(!id) return null;
			return this._next(id);
		},

		/**
		*	Add CSS class to the $el element
		*	@public
		*	@chainable
		*	@method addClass
		*	@param className {String} CSS class name
		*	@return {com.spinal.ui.View}
		**/
		addClass: function(className) {
			if(!className) return this;
			this.$el.addClass(className);
			return this;
		},

		/**
		*	Removes CSS class from the $el element
		*	@public
		*	@chainable
		*	@method removeClass
		*	@param className {String} CSS class name
		*	@return {com.spinal.ui.View}
		**/
		removeClass: function(className) {
			if(!className) return this;
			this.$el.removeClass(className);
			return this;
		},

		/**
		*	Show View
		*	@public
		*	@chainable
		*	@method show
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		show: function(opts) {
			this.$el.show();
			if(!opts || !opts.silent) this.trigger(View.EVENTS.show, { view: this });
			return this;
		},

		/**
		*	Hide View
		*	@public
		*	@chainable
		*	@method hide
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		hide: function(opts) {
			this.$el.hide();
			if(!opts || !opts.silent) this.trigger(View.EVENTS.hide, { view: this });
			return this;
		},

		/**
		*	Enable View
		*	@public
		*	@chainable
		*	@method enable
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		enable: function(opts) {
			this.$el.removeAttr('disabled');
			if(!opts || !opts.silent) this.trigger(View.EVENTS.enable, { view: this });
			return this;
		},

		/**
		*	Disable View
		*	@public
		*	@chainable
		*	@method disable
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		disable: function(opts) {
			this.$el.attr('disabled', 'true');
			if(!opts || !opts.silent) this.trigger(View.EVENTS.disable, { view: this });
			return this;
		},

		/**
		*	Detach View
		*	@public
		*	@method detach
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		detach: function(opts) {
			View.__super__.remove.apply(this, arguments);
			if(!opts || !opts.silent) this.trigger(View.EVENTS.detach, { view: this });
			return this;
		},

		/**
		*	Try to Retrieve next parent if possible (Chain of Responsability)
		*	@private
		*	@method _next
		*	@param id {String} Successor id
		*	@return {com.spinal.ui.View}
		**/
		_next: function(id) {
			if(this.id && this.id === id) return this;
			if(this._parent) return this._parent.lookup(id);
			return null;
		},

		/**
		*	String representation of an instance of this class
		*	@public
		*	@method toString
		*	@return String
		**/
		toString: function() {
			return '[object View]';
		}

	}, {

		/**
		*	@static
		*	@property NAME
		*	@type String
		**/
		NAME: 'View',

		/**
		*	@static
		*	@property RENDER
		*	@type Object
		**/
		RENDER: {
			/**
			*	@property APPEND
			*	@type String
			**/
			append: 'append',
			/**
			*	@property PREPEND
			*	@type String
			**/
			prepend: 'prepend',
			/**
			*	@property APPENDTO
			*	@type String
			**/
			appendTo: 'appendTo',
			/**
			*	@property PREPENDTO
			*	@type String
			**/
			prependTo: 'prependTo',
			/**
			*	@property HTML
			*	@type String
			**/
			html: 'html',
		},

		/**
		*	@static
		*	@property EVENTS
		*	@type Object
		**/
		EVENTS: {
			/**
			*	@event click
			**/
			click: 'com:spinal:ui:view:click',
			/**
			*	@event show
			**/
			show: 'com:spinal:ui:view:show',
			/**
			*	@event hide
			**/
			hide: 'com:spinal:ui:view:hide',
			/**
			*	@event enable
			**/
			enable: 'com:spinal:ui:view:enable',
			/**
			*	@event disable
			**/
			disable: 'com:spinal:ui:view:disable',
			/**
			*	@event render
			**/
			render: 'com:spinal:ui:view:rendere',
			/**
			*	@event update
			**/
			update: 'com:spinal:ui:view:update',
			/**
			*	@event detach
			**/
			detach: 'com:spinal:ui:view:detach'
		}

	}));

	return View;

});
<commit_msg>Overriden listenTo method in the View Class to run automatic assingment of the model set to listen for changes (if defined).<commit_after>/**
*	@module com.spinal.ui
*	@author Patricio Ferreira <3dimentionar@gmail.com>
**/
define(['core/spinal',
		'util/string',
		'util/exception/ui',
		'templates/spinal',
		'libs/bootstrap'], function(Spinal, StringUtil, UIException) {

	/**
	*	Define a generic view interface that extends classic Backbone.View
	*	@namespace com.spinal.ui
	*	@class com.spinal.ui.View
	*	@extends Spinal.Backbone.View
	*
	*	@requires com.spinal.core.Spinal
	*	@requires com.spinal.util.StringUtil
	*	@requires com.spinal.util.exception.UIException
	*	@requires templates.spinal
	*	@requires libs.bootstrap
	**/
	var View = Spinal.namespace('com.spinal.ui.View', Backbone.View.inherit({

		/**
		*	Identifier
		*	@public
		*	@property id
		*	@type String
		**/
		id: null,

		/**
		*	Events
		*	@public
		*	@property events
		*	@type Object
		**/
		events: {},

		/**
		*	Internal CSS className
		*	@public
		*	@property className
		*	@type String
		**/
		className: 'ui-view',

		/**
		*	Render Method
		*	@public
		*	@property method
		*	@type String
		**/
		method: 'append',

		/**
		*	Parent Reference
		*	@private
		*	@property _parent
		*	@type {com.spinal.ui.View}
		**/
		_parent: null,

		/**
		*	Theme Class name
		*	@private
		*	@property _theme
		*	@type String
		**/
		_theme: null,

		/**
		*	Internal Compiled template
		*	@private
		*	@property _tpl
		*	@type Function
		**/
		_tpl: null,

		/**
		*	Constructor
		*	@method constructor
		*	@param [options] {Object} View Options
		**/
		constructor: function(options) {
			options || (options = {});
			Backbone.View.apply(this, arguments);
			this.id = (options.id) ? options.id : (this.$el.attr('id')) ? this.$el.attr('id') : null;
			if(options.autoId) this.id = StringUtil.uuid();
			this.$el.attr('id', this.id);
		},

		/**
		*	Initialize
		*	@public
		*	@chainable
		*	@method initialize
		*	@param options {Object} view options
		*	@return {com.spinal.ui.View}
		**/
		initialize: function(options) {
			options || (options = {});
			this._valid(options);
			if(options.el) this.$el.addClass(this.className);
			if(options.theme) { this._theme = options.theme; this.$el.addClass(this._theme); }
			if(options.method) this.method = options.method;
			if(options.template) this._tpl = this._compile(options.template);
			return this;
		},

		/**
		*	ListenTo strategy will override default functionality from backbone
		*	to automatically assing the current model as a target, only if parameter obj is omitted and model is defined.
		*	@public
		*	@method listenTo
		*	@param [obj] {Object} object to listen
		*	@param name {String} event name
		*	@param callback {Function} callback function
		*	@return {com.spinal.ui.View}
		**/
		listenTo: function(obj, name, callback) {
			if(arguments.length === 2 && this.model) { callback = name; name = obj; obj = this.model; }
			return View.__super__.listenTo.call(this, obj, name, callback);
		},

		/**
		*	Validates parameters passed to the contructor function of this class.
		*	@private
		*	@method _valid
		*	@param attrs {Object} attributes
		*	@return Boolean
		**/
		_valid: function(attrs) {
			attrs || (attrs = {});
			if(attrs.id && !_.isString(attrs.id)) throw new UIException('InvalidIDType');
			if(attrs.model && !(attrs.model instanceof Backbone.Model)) throw new UIException('InvalidModelType');
			if(attrs.method && !(View.RENDER[attrs.method])) throw new UIException('UnsupportedRenderMethod', { method: 'non-existent-method' });
			return true;
		},

		/**
		*	Default before render hook
		*	@private
		*	@method _beforeRender
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		_beforeRender: function(opts) {
			if(!this._parent) throw new UIException('SuccessorNotSpecified');
			if(!(this._parent instanceof Spinal.com.spinal.ui.Container)) throw new UIException('InvalidSuccessorType');
			if(this.id && !this._parent.findById(this.id)) throw new UIException('UIStackViolation', {
				viewId: 'view-error', succesorId: 'container-declared-inline'
			});
			return this;
		},

		/**
		*	Compiles and build the template function used by this view
		*	@private
		*	@method _compile
		*	@param tpl {Function} template to be included as child inside the original view root DOM element
		*	@return Function
		**/
		_compile: function(tpl) {
			if(!tpl || (!_.isString(tpl) && !_.isFunction(tpl))) return null;
			return (_.isString(tpl)) ? _.template(tpl) : tpl;
		},

		/**
		*	Default strategy to setup data for templating
		*	@public
		*	@method data
		*	@param [o] {Object} default data to pass to the template
		*	@return Object
		**/
		data: function(o) {
			o || (o = {});
			return (this.model) ? this.model.toJSON() :
				((this._parent && this._parent.model) ? this._parent.model.toJSON() : o);
		},

		/**
		*	Default strategy to project model's data onto the template to generates HTML content
		*	@public
		*	@method template
		*	@param [tpl] {String} HTML template
		*	@param [data] {Object} template data
		*	@return String
		**/
		template: function(tpl, data) {
			if(_.isObject(tpl)) { data = tpl; tpl = null; }
			tpl = (tpl) ? this._compile(tpl) : this._tpl;
			return (tpl) ? this.$el.html(tpl(this.data(data))) : this.$el;
		},

		/**
		*	Render View
		*	@public
		*	@chainable
		*	@method render
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		render: function(opts) {
			opts || (opts = {});
			this._beforeRender(arguments).detach();
			var m = (opts.method && (View.RENDER[opts.method])) ? opts.method : this.method;
			this._parent._targetEl()[m](this.template(this._tpl));
			if(!opts.silent) this.trigger(View.EVENTS.render, { view: this });
			return this.delegateEvents();
		},

		/**
		*	Update View
		*	@public
		*	@chainable
		*	@method update
		*	@param model {Backbone.Model}
		*	@param value {Object} value that has changed
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		update: function(model, value, opts) {
			if(!opts || !opts.silent) this.trigger(View.EVENTS.update, { view: this });
			return this;
		},

		/**
		*	Change Theme set in this view
		*	@public
		*	@method theme
		*	@param themeName {String} theme name
		*	@return {com.spinal.ui.View}
		**/
		theme: function(themeName) {
			if(!themeName || !_.isString(themeName)) return this;
			this.$el.removeClass(this._theme).addClass(themeName);
			this._theme = themeName;
			return this;
		},

		/**
		*	Perform a look up of the closest successor in the view hierarchery using the id passed as parameter.
		*	If the successor is not found, the method will give up returning null.
		*	@public
		*	@chainable
		*	@method lookup
		*	@param id {String} Successor id
		*	@return {com.spinal.ui.View}
		**/
		lookup: function(id) {
			if(!id) return null;
			return this._next(id);
		},

		/**
		*	Add CSS class to the $el element
		*	@public
		*	@chainable
		*	@method addClass
		*	@param className {String} CSS class name
		*	@return {com.spinal.ui.View}
		**/
		addClass: function(className) {
			if(!className) return this;
			this.$el.addClass(className);
			return this;
		},

		/**
		*	Removes CSS class from the $el element
		*	@public
		*	@chainable
		*	@method removeClass
		*	@param className {String} CSS class name
		*	@return {com.spinal.ui.View}
		**/
		removeClass: function(className) {
			if(!className) return this;
			this.$el.removeClass(className);
			return this;
		},

		/**
		*	Show View
		*	@public
		*	@chainable
		*	@method show
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		show: function(opts) {
			this.$el.show();
			if(!opts || !opts.silent) this.trigger(View.EVENTS.show, { view: this });
			return this;
		},

		/**
		*	Hide View
		*	@public
		*	@chainable
		*	@method hide
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		hide: function(opts) {
			this.$el.hide();
			if(!opts || !opts.silent) this.trigger(View.EVENTS.hide, { view: this });
			return this;
		},

		/**
		*	Enable View
		*	@public
		*	@chainable
		*	@method enable
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		enable: function(opts) {
			this.$el.removeAttr('disabled');
			if(!opts || !opts.silent) this.trigger(View.EVENTS.enable, { view: this });
			return this;
		},

		/**
		*	Disable View
		*	@public
		*	@chainable
		*	@method disable
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		disable: function(opts) {
			this.$el.attr('disabled', 'true');
			if(!opts || !opts.silent) this.trigger(View.EVENTS.disable, { view: this });
			return this;
		},

		/**
		*	Detach View
		*	@public
		*	@method detach
		*	@param [opts] {Object} additional options
		*	@return {com.spinal.ui.View}
		**/
		detach: function(opts) {
			View.__super__.remove.apply(this, arguments);
			if(!opts || !opts.silent) this.trigger(View.EVENTS.detach, { view: this });
			return this;
		},

		/**
		*	Try to Retrieve next parent if possible (Chain of Responsability)
		*	@private
		*	@method _next
		*	@param id {String} Successor id
		*	@return {com.spinal.ui.View}
		**/
		_next: function(id) {
			if(this.id && this.id === id) return this;
			if(this._parent) return this._parent.lookup(id);
			return null;
		},

		/**
		*	String representation of an instance of this class
		*	@public
		*	@method toString
		*	@return String
		**/
		toString: function() {
			return '[object View]';
		}

	}, {

		/**
		*	@static
		*	@property NAME
		*	@type String
		**/
		NAME: 'View',

		/**
		*	@static
		*	@property RENDER
		*	@type Object
		**/
		RENDER: {
			/**
			*	@property APPEND
			*	@type String
			**/
			append: 'append',
			/**
			*	@property PREPEND
			*	@type String
			**/
			prepend: 'prepend',
			/**
			*	@property APPENDTO
			*	@type String
			**/
			appendTo: 'appendTo',
			/**
			*	@property PREPENDTO
			*	@type String
			**/
			prependTo: 'prependTo',
			/**
			*	@property HTML
			*	@type String
			**/
			html: 'html',
		},

		/**
		*	@static
		*	@property EVENTS
		*	@type Object
		**/
		EVENTS: {
			/**
			*	@event click
			**/
			click: 'com:spinal:ui:view:click',
			/**
			*	@event show
			**/
			show: 'com:spinal:ui:view:show',
			/**
			*	@event hide
			**/
			hide: 'com:spinal:ui:view:hide',
			/**
			*	@event enable
			**/
			enable: 'com:spinal:ui:view:enable',
			/**
			*	@event disable
			**/
			disable: 'com:spinal:ui:view:disable',
			/**
			*	@event render
			**/
			render: 'com:spinal:ui:view:rendere',
			/**
			*	@event update
			**/
			update: 'com:spinal:ui:view:update',
			/**
			*	@event detach
			**/
			detach: 'com:spinal:ui:view:detach'
		}

	}));

	return View;

});
<|endoftext|>


<commit_before>(function(){
  var activePlayer = null,
      STROKE_WIDTH = 9,
      STROKE_CONTAINER_COLOR = '#ffffff',
      STROKE_PROGRESS_COLOR = '#f92835',
      CONTAINER_COLOR = '#ececec';

  function _audio_onClick(evt) {
    // If an instance is current playing, turn it off.
    // It does not matter which one it was and where it came from.
    if(activePlayer) {
      activePlayer.find(".progress-pct").hide().html("");
      activePlayer.find(".play-btn").show();
      activePlayer.find("canvas").hide();

      try {
        var audioRef = activePlayer.find("audio").get(0);
        audioRef.pause();
        audioRef.currentTime = 0;
      }
      catch(e) {
        console.log("The audio file was never loaded.");
      }

      if(activePlayer.is(this)) {
        activePlayer = null;
        return;
      }
    }

    var ref = $(this);

    activePlayer = ref;
    ref.find(".progress-pct").show().html("0");
    ref.find(".play-btn").hide();
    ref.find("audio").get(0).play();
    ref.find("canvas").show();
  }

  function _audio_onProgress(evt) {
    var ref = $(this),
      audioRef = ref.find("audio").get(0),
      pct = audioRef.currentTime / audioRef.duration * 100;

    if(audioRef.currentTime > 0) {
      ref.find(".progress-pct").html(parseInt(pct, 10));
      _canvas_onProgress(pct, ref.find("canvas").get(0));
    }

    // the following should be streamlined elsewhere, but when the end
    // is reached, reset the player
    if(pct === 100) {
      audioRef.pause();
      audioRef.currentTime = 0;
      activePlayer.find(".progress-pct").hide().html("");
      activePlayer.find("canvas").hide();
      activePlayer.find(".play-btn").show();
      activePlayer = null;
    }
  }

  function _canvas_onProgress(pct, canvas) {
      // Draw the canvas rings
      var context = canvas.getContext('2d');
      var centerX = canvas.width / 2;
      var centerY = canvas.height / 2;
      var radius = centerX - (STROKE_WIDTH / 2);

      // Fill container, including hollow bit
      context.beginPath();
      context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
      context.fillStyle = CONTAINER_COLOR;
      context.fill();
      context.lineWidth = STROKE_WIDTH;
      context.strokeStyle = STROKE_CONTAINER_COLOR;
      context.stroke();

      // Progress container, empty fill with a stroke
      context.beginPath();
      context.arc(centerX, centerY, radius, 0, (pct * 0.02) * Math.PI, false);
      context.lineWidth = 9;
      context.strokeStyle = STROKE_PROGRESS_COLOR;
      context.stroke();
  }

  window.SimpleRoundPlayer = {
    init : function(config) {
      if(config) {
        if(config.containerColor) {
          CONTAINER_COLOR = config.containerColor;
        }

        if(config.ringColor) {
          STROKE_CONTAINER_COLOR = config.ringColor;
        }

        if(config.ringProgressColor) {
          STROKE_PROGRESS_COLOR = config.ringProgressColor;
        }
      }

      $("audio[data-srp]").each(function(){
        var audio = $(this).find("audio"),
            wrap = null;

        // Ensure this only runs once.
        if(audio.data("simple-round-player") !== true) {
          audio.wrap(
           '
'
          +'       <canvas></canvas>'
          +'

'
          +'

'
          +'
');

          wrap = audio.parents(".simple-round-player");
          audio.bind('timeupdate', _audio_onProgress.bind(wrap));
          audio.data("simple-round-player", true);

          wrap.find(".play-btn, .progress-pct").bind('click', _audio_onClick.bind(wrap));

          var $canvas = wrap.find('canvas'),
              canvas = $canvas.get(0);
          canvas.height = $canvas.height();
          canvas.width = $canvas.width();
        }
      });
    }
  };

})();
<commit_msg>fixed previous commit<commit_after>(function(){
  var activePlayer = null,
      STROKE_WIDTH = 9,
      STROKE_CONTAINER_COLOR = '#ffffff',
      STROKE_PROGRESS_COLOR = '#f92835',
      CONTAINER_COLOR = '#ececec';

  function _audio_onClick(evt) {
    // If an instance is current playing, turn it off.
    // It does not matter which one it was and where it came from.
    if(activePlayer) {
      activePlayer.find(".progress-pct").hide().html("");
      activePlayer.find(".play-btn").show();
      activePlayer.find("canvas").hide();

      try {
        var audioRef = activePlayer.find("audio").get(0);
        audioRef.pause();
        audioRef.currentTime = 0;
      }
      catch(e) {
        console.log("The audio file was never loaded.");
      }

      if(activePlayer.is(this)) {
        activePlayer = null;
        return;
      }
    }

    var ref = $(this);

    activePlayer = ref;
    ref.find(".progress-pct").show().html("0");
    ref.find(".play-btn").hide();
    ref.find("audio").get(0).play();
    ref.find("canvas").show();
  }

  function _audio_onProgress(evt) {
    var ref = $(this),
      audioRef = ref.find("audio").get(0),
      pct = audioRef.currentTime / audioRef.duration * 100;

    if(audioRef.currentTime > 0) {
      ref.find(".progress-pct").html(parseInt(pct, 10));
      _canvas_onProgress(pct, ref.find("canvas").get(0));
    }

    // the following should be streamlined elsewhere, but when the end
    // is reached, reset the player
    if(pct === 100) {
      audioRef.pause();
      audioRef.currentTime = 0;
      activePlayer.find(".progress-pct").hide().html("");
      activePlayer.find("canvas").hide();
      activePlayer.find(".play-btn").show();
      activePlayer = null;
    }
  }

  function _canvas_onProgress(pct, canvas) {
      // Draw the canvas rings
      var context = canvas.getContext('2d');
      var centerX = canvas.width / 2;
      var centerY = canvas.height / 2;
      var radius = centerX - (STROKE_WIDTH / 2);

      // Fill container, including hollow bit
      context.beginPath();
      context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
      context.fillStyle = CONTAINER_COLOR;
      context.fill();
      context.lineWidth = STROKE_WIDTH;
      context.strokeStyle = STROKE_CONTAINER_COLOR;
      context.stroke();

      // Progress container, empty fill with a stroke
      context.beginPath();
      context.arc(centerX, centerY, radius, 0, (pct * 0.02) * Math.PI, false);
      context.lineWidth = 9;
      context.strokeStyle = STROKE_PROGRESS_COLOR;
      context.stroke();
  }

  window.SimpleRoundPlayer = {
    init : function(config) {
      if(config) {
        if(config.containerColor) {
          CONTAINER_COLOR = config.containerColor;
        }

        if(config.ringColor) {
          STROKE_CONTAINER_COLOR = config.ringColor;
        }

        if(config.ringProgressColor) {
          STROKE_PROGRESS_COLOR = config.ringProgressColor;
        }
      }

      $("audio[data-srp]").each(function(){
        // Ensure this only runs once.
        if($(this).data("simple-round-player") !== true) {
          $(this).wrap(
           '
'
          +'       <canvas></canvas>'
          +'

'
          +'

'
          +'
');
        }
      });

      $(".simple-round-player").each(function(){

        $(this).find("audio").bind('timeupdate', _audio_onProgress.bind(this));
        $(this).find("audio").data("simple-round-player", true);

        $(this).find(".play-btn, .progress-pct").bind('click', _audio_onClick.bind(this));

        var $canvas = $(this).find('canvas'),
            canvas = $canvas.get(0);

        canvas.height = $canvas.height();
        canvas.width = $canvas.width();
      });
    }
  };

})();
<|endoftext|>