<commit_before>import React from 'react';
import { translate } from 'react-i18next';
import { FastField, useFormikContext } from 'formik';
import { Box, Flex } from 'rebass/styled-components';
import bows from 'bows';
import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import map from 'lodash/map';
import InputMask from 'react-input-mask';

import { fieldsAreValid, getFieldError } from '../../core/forms';
import { useInitialFocusedInput } from '../../core/hooks';
import i18next from '../../core/language';
import RadioGroup from '../../components/elements/RadioGroup';
import Checkbox from '../../components/elements/Checkbox';
import TextInput from '../../components/elements/TextInput';
import { Caption, Headline } from '../../components/elements/FontStyles';

import {
  fieldsetStyles,
  condensedInputStyles,
  checkboxGroupStyles,
  checkboxStyles,
} from './prescriptionFormStyles';

import {
  sexOptions,
  cgmDeviceOptions,
  pumpDeviceOptions,
  stepValidationFields,
} from './prescriptionFormConstants';

const t = i18next.t.bind(i18next);
const log = bows('PrescriptionProfile');

export const PatientPhone = translate()(props => {
  const { t } = props;
  const formikContext = useFormikContext();

  const {
    setFieldValue,
    setFieldTouched,
    values,
  } = formikContext;

  const patientName = get(values, 'firstName');
  const initialFocusedInputRef = useInitialFocusedInput();

  return (
    <Box {...fieldsetStyles}>
      <Headline mb={4}>{t('What is the mobile phone number {{patientName}} will use with Tidepool Loop?', { patientName })}</Headline>
      <FastField
        as={({ innerRef }) => (
          <InputMask
            mask="(999) 999-9999"
            alwaysShowMask
            defaultValue={get(values, 'phoneNumber.number')}
            onBlur={e => {
              setFieldTouched('phoneNumber.number', true);
              setFieldValue('phoneNumber.number', e.target.value);
            }}
          >
            <TextInput
              name="phoneNumber.number"
              id="phoneNumber.number"
              label={t('Phone Number')}
              error={getFieldError('phoneNumber.number', formikContext)}
              innerRef={innerRef}
              {...condensedInputStyles}
            />
          </InputMask>
        )}
        tabIndex={-1}
        innerRef={initialFocusedInputRef}
      />

        {t('The patient\'s phone number may be used to provide direct assistance regarding their Tidepool account. Standard messaging rates may apply.')}

    </Box>
  );
});

export const PatientMRN = translate()(props => {
  const { t } = props;
  const formikContext = useFormikContext();
  const { values } = formikContext;
  const patientName = get(values, 'firstName');
  const initialFocusedInputRef = useInitialFocusedInput();

  return (
    <Box {...fieldsetStyles}>
      <Headline mb={4}>{t('What is {{patientName}}\'s Medical Record Number?', { patientName })}</Headline>
      <FastField
        as={TextInput}
        label={t('Medical Record Number')}
        id="mrn"
        name="mrn"
        error={getFieldError('mrn', formikContext)}
        innerRef={initialFocusedInputRef}
        {...condensedInputStyles}
      />
    </Box>
  );
});

export const PatientGender = translate()(props => {
  const { t } = props;
  const formikContext = useFormikContext();
  const { values } = formikContext;
  const patientName = get(values, 'firstName');
  const initialFocusedInputRef = useInitialFocusedInput();

  return (
    <Box {...fieldsetStyles}>
      <Headline mb={4}>{t('What is the {{patientName}}\'s gender?', { patientName })}</Headline>
      <FastField
        as={RadioGroup}
        variant="verticalBordered"
        id="sex"
        name="sex"
        options={sexOptions}
        error={getFieldError('sex', formikContext)}
        innerRef={initialFocusedInputRef}
      />
    </Box>
  );
});

export const PatientDevices = translate()(props => {
  const { t, devices } = props;
  const formikContext = useFormikContext();

  const {
    setFieldValue,
    values,
  } = formikContext;

  const patientName = get(values, 'firstName');
  const initialFocusedInputRef = useInitialFocusedInput();

  return (
    <Box {...fieldsetStyles}>
      <Headline mb={4}>{t('Does {{patientName}} have the necessary prescriptions for Tidepool Loop compatible devices?', { patientName })}</Headline>
      <Flex {...checkboxGroupStyles}>
        {map(pumpDeviceOptions(devices), device => (
          <React.Fragment key={device.value}>
            <FastField
              as={Checkbox}
              id="initialSettings.pumpId"
              name="initialSettings.pumpId"
              key={device.value}
              checked={!isEmpty(get(values, 'initialSettings.pumpId', ''))}
              label={device.label}
              onChange={e => {
                setFieldValue('initialSettings.pumpId', e.target.checked ? device.value : '')
              }}
              error={getFieldError('initialSettings.pumpId', formikContext)}
              innerRef={initialFocusedInputRef}
              {...checkboxStyles}
            />

{device.extraInfo}

          </React.Fragment>
        ))}
      </Flex>
      <Flex {...checkboxGroupStyles}>
        {map(cgmDeviceOptions(devices), device => (
          <React.Fragment key={device.value}>
            <FastField
              as={Checkbox}
              id="initialSettings.cgmId"
              name="initialSettings.cgmId"
              checked={!isEmpty(get(values, 'initialSettings.cgmId', ''))}
              label={device.label}
              onChange={e => {
                setFieldValue('initialSettings.cgmId', e.target.checked ? device.value : '')
              }}
              error={getFieldError('initialSettings.cgmId', formikContext)}
              {...checkboxStyles}
            />

{device.extraInfo}

          </React.Fragment>
        ))}
      </Flex>
    </Box>
  );
});

const profileFormSteps = (schema, devices, values) => ({
  label: t('Complete Patient Profile'),
  subSteps: [
    {
      disableComplete: !fieldsAreValid(stepValidationFields[1][0], schema, values),
      onComplete: () => log('Patient Phone Number Complete'),
      panelContent: <PatientPhone />
    },
    {
      disableComplete: !fieldsAreValid(stepValidationFields[1][1], schema, values),
      onComplete: () => log('Patient MRN Complete'),
      panelContent: <PatientMRN />,
    },
    {
      disableComplete: !fieldsAreValid(stepValidationFields[1][2], schema, values),
      onComplete: () => log('Patient Gender Complete'),
      panelContent: <PatientGender />,
    },
    {
      disableComplete: !fieldsAreValid(stepValidationFields[1][3], schema, values),
      onComplete: () => log('Patient Devices Complete'),
      panelContent: <PatientDevices devices={devices} />,
    },
  ],
});

export default profileFormSteps;
<commit_msg>[WEB-1073] Only set phone number value if field contains at least one numeric digit, otherwise set to empty string<commit_after>import React from 'react';
import { translate } from 'react-i18next';
import { FastField, useFormikContext } from 'formik';
import { Box, Flex } from 'rebass/styled-components';
import bows from 'bows';
import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty';
import map from 'lodash/map';
import InputMask from 'react-input-mask';

import { fieldsAreValid, getFieldError } from '../../core/forms';
import { useInitialFocusedInput } from '../../core/hooks';
import i18next from '../../core/language';
import RadioGroup from '../../components/elements/RadioGroup';
import Checkbox from '../../components/elements/Checkbox';
import TextInput from '../../components/elements/TextInput';
import { Caption, Headline } from '../../components/elements/FontStyles';

import {
  fieldsetStyles,
  condensedInputStyles,
  checkboxGroupStyles,
  checkboxStyles,
} from './prescriptionFormStyles';

import {
  sexOptions,
  cgmDeviceOptions,
  pumpDeviceOptions,
  stepValidationFields,
} from './prescriptionFormConstants';

const t = i18next.t.bind(i18next);
const log = bows('PrescriptionProfile');

export const PatientPhone = translate()(props => {
  const { t } = props;
  const formikContext = useFormikContext();

  const {
    setFieldValue,
    setFieldTouched,
    values,
  } = formikContext;

  const patientName = get(values, 'firstName');
  const initialFocusedInputRef = useInitialFocusedInput();

  return (
    <Box {...fieldsetStyles}>
      <Headline mb={4}>{t('What is the mobile phone number {{patientName}} will use with Tidepool Loop?', { patientName })}</Headline>
      <FastField
        as={({ innerRef }) => (
          <InputMask
            mask="(999) 999-9999"
            alwaysShowMask
            defaultValue={get(values, 'phoneNumber.number')}
            onBlur={e => {
              // Only set value if field contains at least one numeric digit
              const value = !!e.target.value.match(/(?=.*\d)/) ? e.target.value : '';
              setFieldTouched('phoneNumber.number', true);
              setFieldValue('phoneNumber.number', value);
            }}
          >
            <TextInput
              name="phoneNumber.number"
              id="phoneNumber.number"
              label={t('Phone Number')}
              error={getFieldError('phoneNumber.number', formikContext)}
              innerRef={innerRef}
              {...condensedInputStyles}
            />
          </InputMask>
        )}
        tabIndex={-1}
        innerRef={initialFocusedInputRef}
      />

        {t('The patient\'s phone number may be used to provide direct assistance regarding their Tidepool account. Standard messaging rates may apply.')}

    </Box>
  );
});

export const PatientMRN = translate()(props => {
  const { t } = props;
  const formikContext = useFormikContext();
  const { values } = formikContext;
  const patientName = get(values, 'firstName');
  const initialFocusedInputRef = useInitialFocusedInput();

  return (
    <Box {...fieldsetStyles}>
      <Headline mb={4}>{t('What is {{patientName}}\'s Medical Record Number?', { patientName })}</Headline>
      <FastField
        as={TextInput}
        label={t('Medical Record Number')}
        id="mrn"
        name="mrn"
        error={getFieldError('mrn', formikContext)}
        innerRef={initialFocusedInputRef}
        {...condensedInputStyles}
      />
    </Box>
  );
});

export const PatientGender = translate()(props => {
  const { t } = props;
  const formikContext = useFormikContext();
  const { values } = formikContext;
  const patientName = get(values, 'firstName');
  const initialFocusedInputRef = useInitialFocusedInput();

  return (
    <Box {...fieldsetStyles}>
      <Headline mb={4}>{t('What is the {{patientName}}\'s gender?', { patientName })}</Headline>
      <FastField
        as={RadioGroup}
        variant="verticalBordered"
        id="sex"
        name="sex"
        options={sexOptions}
        error={getFieldError('sex', formikContext)}
        innerRef={initialFocusedInputRef}
      />
    </Box>
  );
});

export const PatientDevices = translate()(props => {
  const { t, devices } = props;
  const formikContext = useFormikContext();

  const {
    setFieldValue,
    values,
  } = formikContext;

  const patientName = get(values, 'firstName');
  const initialFocusedInputRef = useInitialFocusedInput();

  return (
    <Box {...fieldsetStyles}>
      <Headline mb={4}>{t('Does {{patientName}} have the necessary prescriptions for Tidepool Loop compatible devices?', { patientName })}</Headline>
      <Flex {...checkboxGroupStyles}>
        {map(pumpDeviceOptions(devices), device => (
          <React.Fragment key={device.value}>
            <FastField
              as={Checkbox}
              id="initialSettings.pumpId"
              name="initialSettings.pumpId"
              key={device.value}
              checked={!isEmpty(get(values, 'initialSettings.pumpId', ''))}
              label={device.label}
              onChange={e => {
                setFieldValue('initialSettings.pumpId', e.target.checked ? device.value : '')
              }}
              error={getFieldError('initialSettings.pumpId', formikContext)}
              innerRef={initialFocusedInputRef}
              {...checkboxStyles}
            />

{device.extraInfo}

          </React.Fragment>
        ))}
      </Flex>
      <Flex {...checkboxGroupStyles}>
        {map(cgmDeviceOptions(devices), device => (
          <React.Fragment key={device.value}>
            <FastField
              as={Checkbox}
              id="initialSettings.cgmId"
              name="initialSettings.cgmId"
              checked={!isEmpty(get(values, 'initialSettings.cgmId', ''))}
              label={device.label}
              onChange={e => {
                setFieldValue('initialSettings.cgmId', e.target.checked ? device.value : '')
              }}
              error={getFieldError('initialSettings.cgmId', formikContext)}
              {...checkboxStyles}
            />

{device.extraInfo}

          </React.Fragment>
        ))}
      </Flex>
    </Box>
  );
});

const profileFormSteps = (schema, devices, values) => ({
  label: t('Complete Patient Profile'),
  subSteps: [
    {
      disableComplete: !fieldsAreValid(stepValidationFields[1][0], schema, values),
      onComplete: () => log('Patient Phone Number Complete'),
      panelContent: <PatientPhone />
    },
    {
      disableComplete: !fieldsAreValid(stepValidationFields[1][1], schema, values),
      onComplete: () => log('Patient MRN Complete'),
      panelContent: <PatientMRN />,
    },
    {
      disableComplete: !fieldsAreValid(stepValidationFields[1][2], schema, values),
      onComplete: () => log('Patient Gender Complete'),
      panelContent: <PatientGender />,
    },
    {
      disableComplete: !fieldsAreValid(stepValidationFields[1][3], schema, values),
      onComplete: () => log('Patient Devices Complete'),
      panelContent: <PatientDevices devices={devices} />,
    },
  ],
});

export default profileFormSteps;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Header from './components/Header';
import Loader from './components/Loader';
import SearchForm from './components/SearchForm';
import DaysTable from './components/DaysTable';

import './App.css';

class App extends Component {
  constructor() {
    super();
    this.state = {
      loading: true,
      city: '',
      list: [],
    }

    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  componentDidMount() {
    setTimeout(() => this.setState({ loading: false }), 1000);
  }

  handleInputChange = (value) => {
    this.setState({
      city: value
    });
  }

  handleSubmit = (evt) => {
    this.setState({ loading: true });
    evt.preventDefault();
    //const URL = '/data.json';
    const URL = `http://api.openweathermap.org/data/2.5/forecast?q=${this.state.city},uk&units=metric&appid=cc9fafbcb2f3ff46890ef19abaa2fe87`;
    fetch(URL)
    .then( response => response.json() )
    .then( (data) => {
      const processedList = [];
      for(let item of data.list) {
        const aDate = item.dt_txt.split(' ');
        if(!processedList[aDate[0]]){
          processedList[aDate[0]] = [];
        }
        processedList[aDate[0]].push({
          hour: aDate[1].substr(0,5),
          temp: item.main.temp,
          icon: `http://openweathermap.org/img/w/${item.weather[0].icon}.png`,
          description: item.weather[0].description,
        })
      }
      this.setState({list: processedList});
      setTimeout(() => this.setState({ loading: false }), 500);
    });
  }

  render() {
    return (

        <SearchForm
          {...this.state}
          handleSubmit={this.handleSubmit}
          handleInputChange={this.handleInputChange}/>
        <Loader loading={this.state.loading}/>
        <DaysTable list={this.state.list}/>

    );
  }
}

export default App;
<commit_msg>Trying to use a cors proxy to make github pages work<commit_after>import React, { Component } from 'react';
import Header from './components/Header';
import Loader from './components/Loader';
import SearchForm from './components/SearchForm';
import DaysTable from './components/DaysTable';

import './App.css';

class App extends Component {
  constructor() {
    super();
    this.state = {
      loading: true,
      city: '',
      list: [],
    }

    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  componentDidMount() {
    setTimeout(() => this.setState({ loading: false }), 1000);
  }

  handleInputChange = (value) => {
    this.setState({
      city: value
    });
  }

  handleSubmit = (evt) => {
    this.setState({ loading: true });
    evt.preventDefault();
    //const URL = '/data.json';
    // Need to do that as github pages is on https and
    const URL = `https://crossorigin.me/http//api.openweathermap.org/data/2.5/forecast?q=${this.state.city},uk&units=metric&appid=cc9fafbcb2f3ff46890ef19abaa2fe87`;
    fetch(URL)
    .then( response => response.json() )
    .then( (data) => {
      const processedList = [];
      for(let item of data.list) {
        const aDate = item.dt_txt.split(' ');
        if(!processedList[aDate[0]]){
          processedList[aDate[0]] = [];
        }
        processedList[aDate[0]].push({
          hour: aDate[1].substr(0,5),
          temp: item.main.temp,
          icon: `https://crossorigin.me/http//openweathermap.org/img/w/${item.weather[0].icon}.png`,
          description: item.weather[0].description,
        })
      }
      this.setState({list: processedList});
      setTimeout(() => this.setState({ loading: false }), 500);
    });
  }

  render() {
    return (

        <SearchForm
          {...this.state}
          handleSubmit={this.handleSubmit}
          handleInputChange={this.handleInputChange}/>
        <Loader loading={this.state.loading}/>
        <DaysTable list={this.state.list}/>

    );
  }
}

export default App;
<|endoftext|>


<commit_before>
/*jslint indent:2*/
'use strict';

// this will be dictionary containing
// - key: a string
// - all possible words with the characters of the key
var memory = {},
  callsToFunction = 0;

// find all posible strings that can be formed with
// n characters, without repeating characters
// @param string {String} The initial String to use to generate all combinations
// @memoization {bool} Whether or not you want to use memoization
function findAllWords(string, memoization) {
  var allWords = [],
    i,
    firstChar = '',
    wordsWithSubstring,
    remainingChars,
    j;

  // count the number calls to this function
  callsToFunction = callsToFunction + 1;
  // if we've already seen this word and have
  // calculated it's combinations, then just
  // return it
  if ('true' === memoization // only use memoization when set to true
      && memory.hasOwnProperty(string)) {
    // return the array of all the possible words
    // formed with the chars of `string`
    return memory[string];
  }

  // if there's only one char in the string
  // there's only one word tha can be formed
  if (1 === string.length) {
    return [string];
  }

  // the string has at least 2 characters
  // chose one char and put that in the first position
  for (i = 0; i < string.length; i = i + 1) {
    // fix the first character
    firstChar = string.charAt(i);
    // then recursively find all posible words with the
    // remaining characters
    remainingChars = string.substr(0, i) + string.substr(i + 1);
    wordsWithSubstring = findAllWords(remainingChars, memoization);

    // add all words that begin with the `firstChar`
    for (j = 0; j < wordsWithSubstring.length; j = j + 1) {
      allWords.push(firstChar + wordsWithSubstring[j]);
    }
  }

  if ('true' === memoization) {
    // add all the words to our dictionary
    memory[string] = allWords;
  }
  return allWords;
}

function printWords(stringArray) {
  var i,
    words = '';
  for (i = 0; i < stringArray.length; i = i + 1) {
    words += stringArray[i];
    if (i < stringArray.length - 1) {
      words += ',';
    }
  }
  console.log(words);
}

var myWord = 'a',
  prompt = require('prompt'),
  sizeof = require('../gists/sizeof/sizeof');

console.log('Setup:');
prompt.get(['string', 'memoization'], function (err, result) {
  var found;
  if (err) {
    console.log(err);
  } else {
    found = findAllWords(result.string, result.memoization);
    console.log(found);
    console.log(found.length + ' words found.');
    console.log('Calls to `findAllWords`:' + callsToFunction);
    console.log('Memory used: ' + sizeof(memory));
    callsToFunction = 0;
  }
});<commit_msg>remove unused function<commit_after>
/*jslint indent:2*/
'use strict';

// this will be dictionary containing
// - key: a string
// - all possible words with the characters of the key
var memory = {},
  callsToFunction = 0;

// find all posible strings that can be formed with
// n characters, without repeating characters
// @param string {String} The initial String to use to generate all combinations
// @memoization {bool} Whether or not you want to use memoization
function findAllWords(string, memoization) {
  var allWords = [],
    i,
    firstChar = '',
    wordsWithSubstring,
    remainingChars,
    j;

  // count the number calls to this function
  callsToFunction = callsToFunction + 1;
  // if we've already seen this word and have
  // calculated it's combinations, then just
  // return it
  if ('true' === memoization // only use memoization when set to true
      && memory.hasOwnProperty(string)) {
    // return the array of all the possible words
    // formed with the chars of `string`
    return memory[string];
  }

  // if there's only one char in the string
  // there's only one word tha can be formed
  if (1 === string.length) {
    return [string];
  }

  // the string has at least 2 characters
  // chose one char and put that in the first position
  for (i = 0; i < string.length; i = i + 1) {
    // fix the first character
    firstChar = string.charAt(i);
    // then recursively find all posible words with the
    // remaining characters
    remainingChars = string.substr(0, i) + string.substr(i + 1);
    wordsWithSubstring = findAllWords(remainingChars, memoization);

    // add all words that begin with the `firstChar`
    for (j = 0; j < wordsWithSubstring.length; j = j + 1) {
      allWords.push(firstChar + wordsWithSubstring[j]);
    }
  }

  if ('true' === memoization) {
    // add all the words to our dictionary
    memory[string] = allWords;
  }
  return allWords;
}

var myWord = 'a',
  prompt = require('prompt'),
  sizeof = require('../gists/sizeof/sizeof');

console.log('Setup:');
prompt.get(['string', 'memoization'], function (err, result) {
  var found;
  if (err) {
    console.log(err);
  } else {
    found = findAllWords(result.string, result.memoization);
    console.log(found);
    console.log(found.length + ' words found.');
    console.log('Calls to `findAllWords`:' + callsToFunction);
    console.log('Memory used: ' + sizeof(memory));
    callsToFunction = 0;
  }
});<|endoftext|>


<commit_before>//Jquery to give the final touches to Portus layout

//search form in header
$(document).on('ready', function() {
  openSearchForm();
});

function openSearchForm () {
  $('.header-open-search').on('click', function () {
    $(this).fadeOut('300', function() {
      $(this).remove();
    });
    $('.header-search-form .btn-default').show('slow');
    $('.search-field').show('slow');
  });
}
<commit_msg>Fix: autofocus in firefox needs to be fired from javascript<commit_after>//Jquery to give the final touches to Portus layout

//search form in header
$(document).on('ready', function() {
  openSearchForm();
});

function openSearchForm () {
  $('.header-open-search').on('click', function () {
    $(this).fadeOut('300', function() {
      $(this).remove();
    });
    $('.header-search-form .btn-default').show('slow');
    $('.search-field').show('slow').focus();
  });
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import uuid from 'uuid';

import './store/reducers';
import CARD_TEXTS from './store/values.json';

import ShufflingCardGrid from './components/ShufflingCardGrid';

const CARDS = CARD_TEXTS.map(text => ({
  key: uuid.v4(),
  text,
  accepted: false,
  rejected: false
}));

class App extends Component {

  constructor(props, context) {
    super(props, context);
    this.state = {
      windowWidth: window.innerWidth
    };
  }

  handleResize = () => {
    this.setState({ windowWidth: window.innerWidth });
  }

  componentDidMount() {
    window.addEventListener('resize', this.handleResize);
  }

  render() {
    const totalWidth = Math.min(this.state.windowWidth, 900);
    const cardWidth = 200;
    return (

        <ShufflingCardGrid
          width={totalWidth}
          cardWidth={cardWidth}
          cards={CARDS}
        />

    );
  }
}

export default App;
<commit_msg>Use correct props on ShufflingCardGrid<commit_after>import React, { Component } from 'react';
import uuid from 'uuid';

import './store/reducers';
import CARD_TEXTS from './store/values.json';

import ShufflingCardGrid from './components/ShufflingCardGrid';

const CARDS = CARD_TEXTS.map(text => ({
  key: uuid.v4(),
  text,
  accepted: false,
  rejected: false
}));

class App extends Component {

  constructor(props, context) {
    super(props, context);
    this.state = {
      windowWidth: window.innerWidth
    };
  }

  handleResize = () => {
    this.setState({ windowWidth: window.innerWidth });
  }

  componentDidMount() {
    window.addEventListener('resize', this.handleResize);
  }

  render() {
    const totalWidth = Math.min(this.state.windowWidth, 900);
    const cardWidth = 200;
    return (

        <ShufflingCardGrid
          width={totalWidth}
          itemWidth={cardWidth}
          itemHeight={160}
          cards={CARDS}
        />

    );
  }
}

export default App;
<|endoftext|>


<commit_before>import React, { Component } from 'react';

// Components
import Button from "./components/button";

// Functions
import Addition from "./functions/addition";
import Subtract from "./functions/subtract";
import Multiply from "./functions/multiply";
import Divide from "./functions/divide";
import Rotation from 'react-rotation'

import './App.css';
import './Color.css';

class App extends Component {

  constructor(props) {
    super(props);

    this.state = {
      input: "",
      math: null,
      sum: null,
      resetNext: false,
      firstEntry: true,
      theme: "red",
    };

    this.buttons = ["C", "(-)", "<", "/", 1, 2, 3, "*", 4, 5, 6, "-", 7 ,8, 9, "+", 0, ".", "="];
  }

  // Run when app is loaded
  componentWillMount() {
    // this.getLocalStorage();
  }

  handleInputClick(input) {
        this.setState({whatevz:false});

    if (typeof input === "number") {

      if (this.state.resetNext) {
        // reset input if resetNext = true
        this.setState({input: input.toString(), resetNext: false});
      } else {

        // Concatenate input string
        this.setState({input : this.state.input + input.toString()});
      }

    } else if (input === "(-)") {
      // If user input negative (-)
      this.handelNegative();

    } else if (input === ".") {
      // If user input negative (-)
      this.handelComma();

    } else if (input === "C" || input.toUpperCase() === "C") {
      // If user input C
      this.handelClear();

    } else if (input === "=") {
      // If user input =
      this.handelEqual();

    } else if (input === "<") {
      // If user input < (backspace)
      this.handelBackspace();

    } else {
      // If user input +, -, *, /...
      this.setState({resetNext: true});

      if (input !== this.state.math && this.state.math && this.state.math !== "=") {
        // If the user switch between +, -, *, /
        this.handelMathSwitch(input);

      } else {
        this.handelMath(input);
      }

    }
  }

  // ---------------------
  // Handle negative input, only allow one minus key
  // ---------------------
  handelNegative() {
    if (this.state.resetNext) {
      // reset input if resetNext = true
      this.setState({input: "-", resetNext: false});
    } else if (this.state.input.includes("-")) {
      return;
    } else {
        this.setState({input: "-" + this.state.input});
    }
  }

  // ---------------------
  // Handel comma input, only allow one comma key
  // ---------------------
  handelComma() {
    if (this.state.resetNext || this.state.input === "") {
      // reset input if resetNext = true
      this.setState({input: "0.", resetNext: false});
    } else {
      this.setState({input: this.state.input + "."});
    }
  }

  // ---------------------
  // Reset state to original
  // ---------------------
  handelClear() {
    this.setState({
      input: "",
      math: null,
      sum: null,
      resetNext: false,
      firstEntry: true,
    });
  }

  // ---------------------
  // Delete the last number in string, backspace
  // ---------------------
  handelBackspace() {
    this.setState({input: this.state.input.slice(0, -1)});
  }

  // ---------------------
  // Handel equal: handel math, set new state
  // ---------------------
  handelEqual() {
    this.handelMath(this.state.math);
    this.setState({
      firstEntry: true,
      math: "=",
      resetNext: true,
      sum: null,
      whatevz: true
    });
  }

  // ---------------------
  // Handel math switch: handel math and set new state
  // ---------------------
  handelMathSwitch(input) {
    this.handelMath(this.state.math);
    this.setState({
      firstEntry: false,
      math: input,
      resetNext: true
    });
  }

  // ---------------------
  // Save state to localStorage
  // ---------------------
  postLocalStorage() {
    const jsonString = JSON.stringify(this.state);
    localStorage.setItem('calc', jsonString);
  }

  // ---------------------
  // Load state from localStorage
  // ---------------------
  getLocalStorage() {
    const savedState = JSON.parse(localStorage.getItem('calc'));
    this.setState(savedState);
  }

  // ---------------------
  // Handle all math, set new state
  // ---------------------
  handelMath(input) {
    if (this.state.firstEntry) {
      // This only moves the input to state.sum
      this.setState({
        sum: this.state.input,
        math: input,
        firstEntry: false,
      });
    } else {
      switch(input) {
        case "+":
          this.setState({
            input: Addition(this.state.sum, this.state.input).toString(),
            sum: Addition(this.state.sum, this.state.input),
            math: "+",
          });
          break;
        case "-":
          this.setState({
            input: Subtract(this.state.sum, this.state.input).toString(),
            sum: Subtract(this.state.sum, this.state.input),
            math: "-"
          });
          break;
        case "*":
          this.setState({
            input: Multiply(this.state.sum, this.state.input).toString(),
            sum: Multiply(this.state.sum, this.state.input),
            math: "*"
          });
          break;
        case "/":
          this.setState({
            input: Divide(this.state.sum, this.state.input).toString(),
            sum: Divide(this.state.sum, this.state.input),
            math: "/"
          });
          break;
        default:
          break;
      }
    }
  }

  handelChangeTheme() {
    const newTheme = this.state.theme === "red" ? "blue" : "red";
    this.setState({theme: newTheme});
  }

  // React, render to DOM
  render() {
    // this.postLocalStorage();
    return (

        <div className={`calculator ${this.state.theme}`}>

            <button className="themes" onClick={() => this.handelChangeTheme()}>∞</button>

calc

          <div className={`input ${this.state.whatevz ? "animationz" : ""}`}>
            {this.state.input ? this.state.input : 0}

          {/*

            {this.handelHistory()}

 */}

            {this.buttons.map((int) => <Button key={int} onClick={this.handleInputClick.bind(this)} math={this.state.math}>{int}</Button>)}

    );
  }
}
export default App;
<commit_msg>remove rotation in app.js<commit_after>import React, { Component } from 'react';

// Components
import Button from "./components/button";

// Functions
import Addition from "./functions/addition";
import Subtract from "./functions/subtract";
import Multiply from "./functions/multiply";
import Divide from "./functions/divide";

import './App.css';
import './Color.css';

class App extends Component {

  constructor(props) {
    super(props);

    this.state = {
      input: "",
      math: null,
      sum: null,
      resetNext: false,
      firstEntry: true,
      theme: "red",
    };

    this.buttons = ["C", "(-)", "<", "/", 1, 2, 3, "*", 4, 5, 6, "-", 7 ,8, 9, "+", 0, ".", "="];
  }

  // Run when app is loaded
  componentWillMount() {
    // this.getLocalStorage();
  }

  handleInputClick(input) {
        this.setState({whatevz:false});

    if (typeof input === "number") {

      if (this.state.resetNext) {
        // reset input if resetNext = true
        this.setState({input: input.toString(), resetNext: false});
      } else {

        // Concatenate input string
        this.setState({input : this.state.input + input.toString()});
      }

    } else if (input === "(-)") {
      // If user input negative (-)
      this.handelNegative();

    } else if (input === ".") {
      // If user input negative (-)
      this.handelComma();

    } else if (input === "C" || input.toUpperCase() === "C") {
      // If user input C
      this.handelClear();

    } else if (input === "=") {
      // If user input =
      this.handelEqual();

    } else if (input === "<") {
      // If user input < (backspace)
      this.handelBackspace();

    } else {
      // If user input +, -, *, /...
      this.setState({resetNext: true});

      if (input !== this.state.math && this.state.math && this.state.math !== "=") {
        // If the user switch between +, -, *, /
        this.handelMathSwitch(input);

      } else {
        this.handelMath(input);
      }

    }
  }

  // ---------------------
  // Handle negative input, only allow one minus key
  // ---------------------
  handelNegative() {
    if (this.state.resetNext) {
      // reset input if resetNext = true
      this.setState({input: "-", resetNext: false});
    } else if (this.state.input.includes("-")) {
      return;
    } else {
        this.setState({input: "-" + this.state.input});
    }
  }

  // ---------------------
  // Handel comma input, only allow one comma key
  // ---------------------
  handelComma() {
    if (this.state.resetNext || this.state.input === "") {
      // reset input if resetNext = true
      this.setState({input: "0.", resetNext: false});
    } else {
      this.setState({input: this.state.input + "."});
    }
  }

  // ---------------------
  // Reset state to original
  // ---------------------
  handelClear() {
    this.setState({
      input: "",
      math: null,
      sum: null,
      resetNext: false,
      firstEntry: true,
    });
  }

  // ---------------------
  // Delete the last number in string, backspace
  // ---------------------
  handelBackspace() {
    this.setState({input: this.state.input.slice(0, -1)});
  }

  // ---------------------
  // Handel equal: handel math, set new state
  // ---------------------
  handelEqual() {
    this.handelMath(this.state.math);
    this.setState({
      firstEntry: true,
      math: "=",
      resetNext: true,
      sum: null,
      whatevz: true
    });
  }

  // ---------------------
  // Handel math switch: handel math and set new state
  // ---------------------
  handelMathSwitch(input) {
    this.handelMath(this.state.math);
    this.setState({
      firstEntry: false,
      math: input,
      resetNext: true
    });
  }

  // ---------------------
  // Save state to localStorage
  // ---------------------
  postLocalStorage() {
    const jsonString = JSON.stringify(this.state);
    localStorage.setItem('calc', jsonString);
  }

  // ---------------------
  // Load state from localStorage
  // ---------------------
  getLocalStorage() {
    const savedState = JSON.parse(localStorage.getItem('calc'));
    this.setState(savedState);
  }

  // ---------------------
  // Handle all math, set new state
  // ---------------------
  handelMath(input) {
    if (this.state.firstEntry) {
      // This only moves the input to state.sum
      this.setState({
        sum: this.state.input,
        math: input,
        firstEntry: false,
      });
    } else {
      switch(input) {
        case "+":
          this.setState({
            input: Addition(this.state.sum, this.state.input).toString(),
            sum: Addition(this.state.sum, this.state.input),
            math: "+",
          });
          break;
        case "-":
          this.setState({
            input: Subtract(this.state.sum, this.state.input).toString(),
            sum: Subtract(this.state.sum, this.state.input),
            math: "-"
          });
          break;
        case "*":
          this.setState({
            input: Multiply(this.state.sum, this.state.input).toString(),
            sum: Multiply(this.state.sum, this.state.input),
            math: "*"
          });
          break;
        case "/":
          this.setState({
            input: Divide(this.state.sum, this.state.input).toString(),
            sum: Divide(this.state.sum, this.state.input),
            math: "/"
          });
          break;
        default:
          break;
      }
    }
  }

  handelChangeTheme() {
    const newTheme = this.state.theme === "red" ? "blue" : "red";
    this.setState({theme: newTheme});
  }

  // React, render to DOM
  render() {
    // this.postLocalStorage();
    return (

        <div className={`calculator ${this.state.theme}`}>

            <button className="themes" onClick={() => this.handelChangeTheme()}>∞</button>

calc

          <div className={`input ${this.state.whatevz ? "animationz" : ""}`}>
            {this.state.input ? this.state.input : 0}

          {/*

            {this.handelHistory()}

 */}

            {this.buttons.map((int) => <Button key={int} onClick={this.handleInputClick.bind(this)} math={this.state.math}>{int}</Button>)}

    );
  }
}
export default App;
<|endoftext|>


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

  angular.module('dimApp')
    .controller('dimInfuseCtrl', dimInfuseCtrl);

  dimInfuseCtrl.$inject = ['$scope', 'dimStoreService', 'dimItemService', 'ngDialog', 'dimLoadoutService'];

  function dimInfuseCtrl($scope, dimStoreService, dimItemService, ngDialog, dimLoadoutService) {
    var vm = this;

    angular.extend(vm, {
      getAllItems: true,
      showLockedItems: false,
      onlyBlues: false,
      target: null,
      infused: 0,
      stats: [],
      exotic: false,
      infusable: [],
      transferInProgress: false,

      setSourceItem: function(item) {
        // Set the source and reset the targets
        vm.source = item;
        vm.infused = 0;
        vm.stats = null;
        vm.target = null;
        vm.statType =
          vm.source.primStat.statHash === 3897883278 ? 'Defense' : // armor item
          vm.source.primStat.statHash === 368428387 ?  'Attack' :  // weapon item
                                                       'Unknown'; // new item?
        vm.wildcardMaterialIcon = item.sort === 'General' ? '2e026fc67d445e5b2630277aa794b4b1' :
          vm.statType === 'Attack' ? 'f2572a4949fb16df87ba9760f713dac3' : '972ae2c6ccbf59cde293a2ed50a57a93';
        vm.wildcardMaterialIcon = '/common/destiny_content/icons/' + vm.wildcardMaterialIcon + '.jpg';
        // 2 motes, or 10 armor/weapon materials
        vm.wildcardMaterialCost = item.sort === 'General' ? 2 : 10;
      },

      selectItem: function(item, e) {
        if (e) {
          e.stopPropagation();
        }
        vm.target = item;
        vm.infused = vm.target.primStat.value;
        // The new stats of the item
        vm.stats = _.map(vm.source.stats, function(stat) {
          return {before: stat.base, after: (stat.base * vm.infused / vm.source.primStat.value).toFixed(0)};
        });
      },

      // get Items for infusion
      getItems: function() {
        var stores = dimStoreService.getStores();
        var allItems = [];

        // If we want ALL our weapons, including vault's one
        if (!vm.getAllItems) {
          stores = _.filter(stores, function(store) {
            return store.id === vm.source.owner;
          });
        }

        // all stores
        _.each(stores, function(store, id, list) {
          // all items in store
          var items = _.filter(store.items, function(item) {
            return item.primStat &&
              (!item.locked || vm.showLockedItems) &&
              item.type == vm.source.type &&
              item.primStat.value > vm.source.primStat.value &&
              (!vm.onlyBlues || item.tier === 'Rare');
          });

          allItems = allItems.concat(items);

        });

        allItems = _.sortBy(allItems, function(item) {
          return item.primStat.value + ((item.talentGrid.totalXP / item.talentGrid.totalXPRequired) * 0.5);
        });

        vm.infusable = allItems;
        if (allItems.length) {
          vm.selectItem(allItems[allItems.length - 1]);
        } else {
          vm.target = null;
          vm.infused = 0;
        }
      },

      closeDialog: function() {
        $scope.$parent.closeThisDialog();
      },

      transferItems: function() {
        var store = dimStoreService.getStore(vm.source.owner);
        var items = {};
        var key = vm.target.type.toLowerCase();
        items[key] = items[key] || [];
        var itemCopy = angular.copy(vm.target);
        itemCopy.equipped = false;
        items[key].push(itemCopy);
        // Include the source, since we wouldn't want it to get moved out of the way
        items[vm.source.type.toLowerCase()].push(vm.source);

        items['material'] = [];
        if (vm.sort === 'General') {
          // Mote of Light
          items['material'].push({
            id: '0',
            hash: 937555249,
            amount: 2,
            equipped: false
          });
        } else if (vm.statType === 'Attack') {
          // Weapon Parts
          items['material'].push({
            id: '0',
            hash: 1898539128,
            amount: 10,
            equipped: false
          });
        } else {
          // Armor Materials
          items['material'].push({
            id: '0',
            hash: 1542293174,
            amount: 10,
            equipped: false
          });
        }
        if (vm.exotic) {
          // Exotic shard
          items['material'].push({
            id: '0',
            hash: 452597397,
            amount: 1,
            equipped: false
          });
        }

        var loadout = {
          classType: -1,
          name: 'Infusion Materials',
          items: items
        };

        vm.transferInProgress = true;
        return dimLoadoutService.applyLoadout(store, loadout).then(function() {
          vm.transferInProgress = false;
        });
      }
    });

    vm.setSourceItem($scope.$parent.ngDialogData);
    vm.getItems();
  }
})();
<commit_msg>Remove unused Infuse modifications.<commit_after>(function() {
  'use strict';

  angular.module('dimApp')
    .controller('dimInfuseCtrl', dimInfuseCtrl);

  dimInfuseCtrl.$inject = ['$scope', 'dimStoreService', 'dimItemService', 'ngDialog', 'dimLoadoutService'];

  function dimInfuseCtrl($scope, dimStoreService, dimItemService, ngDialog, dimLoadoutService) {
    var vm = this;

    angular.extend(vm, {
      getAllItems: true,
      showLockedItems: false,
      onlyBlues: false,
      target: null,
      infused: 0,
      exotic: false,
      infusable: [],
      transferInProgress: false,

      setSourceItem: function(item) {
        // Set the source and reset the targets
        vm.source = item;
        vm.infused = 0;
        vm.target = null;
        vm.statType =
          vm.source.primStat.statHash === 3897883278 ? 'Defense' : // armor item
          vm.source.primStat.statHash === 368428387 ?  'Attack' :  // weapon item
                                                       'Unknown'; // new item?
        vm.wildcardMaterialIcon = item.sort === 'General' ? '2e026fc67d445e5b2630277aa794b4b1' :
          vm.statType === 'Attack' ? 'f2572a4949fb16df87ba9760f713dac3' : '972ae2c6ccbf59cde293a2ed50a57a93';
        vm.wildcardMaterialIcon = '/common/destiny_content/icons/' + vm.wildcardMaterialIcon + '.jpg';
        // 2 motes, or 10 armor/weapon materials
        vm.wildcardMaterialCost = item.sort === 'General' ? 2 : 10;
      },

      selectItem: function(item, e) {
        if (e) {
          e.stopPropagation();
        }
        vm.target = item;
        vm.infused = vm.target.primStat.value;
      },

      // get Items for infusion
      getItems: function() {
        var stores = dimStoreService.getStores();
        var allItems = [];

        // If we want ALL our weapons, including vault's one
        if (!vm.getAllItems) {
          stores = _.filter(stores, function(store) {
            return store.id === vm.source.owner;
          });
        }

        // all stores
        _.each(stores, function(store, id, list) {
          // all items in store
          var items = _.filter(store.items, function(item) {
            return item.primStat &&
              (!item.locked || vm.showLockedItems) &&
              item.type == vm.source.type &&
              item.primStat.value > vm.source.primStat.value &&
              (!vm.onlyBlues || item.tier === 'Rare');
          });

          allItems = allItems.concat(items);

        });

        allItems = _.sortBy(allItems, function(item) {
          return item.primStat.value + ((item.talentGrid.totalXP / item.talentGrid.totalXPRequired) * 0.5);
        });

        vm.infusable = allItems;
        if (allItems.length) {
          vm.selectItem(allItems[allItems.length - 1]);
        } else {
          vm.target = null;
          vm.infused = 0;
        }
      },

      closeDialog: function() {
        $scope.$parent.closeThisDialog();
      },

      transferItems: function() {
        var store = dimStoreService.getStore(vm.source.owner);
        var items = {};
        var key = vm.target.type.toLowerCase();
        items[key] = items[key] || [];
        var itemCopy = angular.copy(vm.target);
        itemCopy.equipped = false;
        items[key].push(itemCopy);
        // Include the source, since we wouldn't want it to get moved out of the way
        items[vm.source.type.toLowerCase()].push(vm.source);

        items['material'] = [];
        if (vm.sort === 'General') {
          // Mote of Light
          items['material'].push({
            id: '0',
            hash: 937555249,
            amount: 2,
            equipped: false
          });
        } else if (vm.statType === 'Attack') {
          // Weapon Parts
          items['material'].push({
            id: '0',
            hash: 1898539128,
            amount: 10,
            equipped: false
          });
        } else {
          // Armor Materials
          items['material'].push({
            id: '0',
            hash: 1542293174,
            amount: 10,
            equipped: false
          });
        }
        if (vm.exotic) {
          // Exotic shard
          items['material'].push({
            id: '0',
            hash: 452597397,
            amount: 1,
            equipped: false
          });
        }

        var loadout = {
          classType: -1,
          name: 'Infusion Materials',
          items: items
        };

        vm.transferInProgress = true;
        return dimLoadoutService.applyLoadout(store, loadout).then(function() {
          vm.transferInProgress = false;
        });
      }
    });

    vm.setSourceItem($scope.$parent.ngDialogData);
    vm.getItems();
  }
})();
<|endoftext|>


<commit_before>(function () {
	if ( isBrowserSupported() === false ) {
		patchConsole();
		console.warn( 'ConsoleFile.JS cannot run under this browser.' );

		return;
	}

	var requestQuotaBytes = 10 * 1024 * 1024; // 10MB

	navigator.webkitPersistentStorage.requestQuota(
		requestQuotaBytes,
		function( grantedBytes ) {
			window.webkitRequestFileSystem(
				window.PERSISTENT,
				grantedBytes,
				function ( fs ) {
					// create "log" folder, then initialize the console.file()
					fs.root.getDirectory(
						'log',
						{ create: true },
						function ( dirEntry ) {
							initConsoleFile( fs );
						},
						fsErrorHandler
					);
				},
				fsErrorHandler
			);
		},
		function ( e ) {
			patchConsole();
			console.warn( 'ConsoleFile.JS cannot run as it can\'t allocate enough persistent storage. Tried to allocate: ' + requestQuotaBytes );
		}
	);

	function initConsoleFile ( fs ) {
		var instances = {};

		/**
		 *
		 */
		console.file = function ( fileName ) {
			if ( !fileName ) {
				fileName = 'default';
			}

			if ( !instances[fileName] ) {
				instances[fileName] = new ConsoleFile( fs, fileName );
			}

			return instances[fileName];
		};

		ConsoleFile = function ( fs, fileName ) {
			this._fs = fs;
			this._fileName = fileName;

			this._fsIsReady = false;
			this._fsCache = [];

			fs.root.getFile(
				'log/' + this._fileName + '.log',
				{
					create: true,
					exclusive: false
				},
				function( fsFile ) {
					this._fsIsReady = true;
					this._fsFile = fsFile;
					this._flushCacheToFile();
				}.bind( this ),
				fsErrorHandler
			);
		};

		/**
		 * TODO
		 */
		ConsoleFile.prototype.log = function ( tmpString ) {
			// console.log( 'logging to file: ' + this._fileName + ' #### ' + tmpString );
			this._write( 'log ', tmpString );
		};

		/** @private */
		ConsoleFile.prototype._write = function ( prefix, str ) {
			var stringToWrite = prefix + str + "\n";

			if ( this._fsIsReady === false ) {
				// if we don't yet have a handle to a log file, we will write to this
				// cache, and then once the file handle has been obtained, the contents
				// of this cache will be written to disk
				this._fsCache.push ( stringToWrite );
				console.log( 'writing to cache ', str );
			} else {
				console.log( 'writing to file ', str );
				this._fsFile.createWriter(
					function( fileWriter ) {
						fileWriter.seek( fileWriter.length );

						var blob = new Blob( [stringToWrite], {type: 'text/plain'} );
						fileWriter.write( blob );
					}.bind( this ),
					fsErrorHandler
				);
			}
		};

		/** @private */
		ConsoleFile.prototype._flushCacheToFile = function () {
			// Create a FileWriter object for our FileEntry (log.txt).
			this._fsFile.createWriter(
				function( fileWriter ) {
					fileWriter.seek( fileWriter.length );

					// TODO for some reason this gets called but the thing isn't written into a file
					// maybe I can change this so that stuff is flushed into the file in a timeout, so
					// I can have control over file operations (only one at a time) as to avoid writing to the file
					// from two different locations
					// NEEDS INVESTIGATING
					var blob = new Blob( this._fsCache, {type: 'text/plain'} );
					fileWriter.write( blob );

					this._fsCache = [];
				}.bind( this ),
				fsErrorHandler
			);
		};

		// ConsoleFile.prototype.info = function () {};
		// ConsoleFile.prototype.warn = function () {};
		// ConsoleFile.prototype.error = function () {};
	};

	// private utility functions

	function isBrowserSupported () {
		if ( !navigator.webkitPersistentStorage ) {
			return false;
		}

		return true;
	};

	function patchConsole () {
		console.file = function () {
			var nopFunction = function () {};

			return {
				log: nopFunction,
				info: nopFunction,
				warn: nopFunction,
				error: nopFunction
			};
		};
	};

	function fsErrorHandler ( error ) {
		var msg = '';

		switch (e.code) {
			case FileError.QUOTA_EXCEEDED_ERR:
				msg = 'QUOTA_EXCEEDED_ERR';
			break;

			case FileError.NOT_FOUND_ERR:
				msg = 'NOT_FOUND_ERR';
			break;

			case FileError.SECURITY_ERR:
				msg = 'SECURITY_ERR';
			break;

			case FileError.INVALID_MODIFICATION_ERR:
				msg = 'INVALID_MODIFICATION_ERR';
			break;

			case FileError.INVALID_STATE_ERR:
				msg = 'INVALID_STATE_ERR';
			break;

			default:
				msg = 'Unknown Error';
			break;
		};

		console.log( 'ConsoleFile.JS FileSystem error: ' + msg, e) ;
	};

}() );<commit_msg>Fix accidental global<commit_after>(function () {
	if ( isBrowserSupported() === false ) {
		patchConsole();
		console.warn( 'ConsoleFile.JS cannot run under this browser.' );

		return;
	}

	var requestQuotaBytes = 10 * 1024 * 1024; // 10MB

	navigator.webkitPersistentStorage.requestQuota(
		requestQuotaBytes,
		function( grantedBytes ) {
			window.webkitRequestFileSystem(
				window.PERSISTENT,
				grantedBytes,
				function ( fs ) {
					// create "log" folder, then initialize the console.file()
					fs.root.getDirectory(
						'log',
						{ create: true },
						function ( dirEntry ) {
							initConsoleFile( fs );
						},
						fsErrorHandler
					);
				},
				fsErrorHandler
			);
		},
		function ( e ) {
			patchConsole();
			console.warn( 'ConsoleFile.JS cannot run as it can\'t allocate enough persistent storage. Tried to allocate: ' + requestQuotaBytes );
		}
	);

	function initConsoleFile ( fs ) {
		var instances = {};

		/**
		 *
		 */
		console.file = function ( fileName ) {
			if ( !fileName ) {
				fileName = 'default';
			}

			if ( !instances[fileName] ) {
				instances[fileName] = new ConsoleFile( fs, fileName );
			}

			return instances[fileName];
		};

		function ConsoleFile ( fs, fileName ) {
			this._fs = fs;
			this._fileName = fileName;

			this._fsIsReady = false;
			this._fsCache = [];

			fs.root.getFile(
				'log/' + this._fileName + '.log',
				{
					create: true,
					exclusive: false
				},
				function( fsFile ) {
					this._fsIsReady = true;
					this._fsFile = fsFile;
					this._flushCacheToFile();
				}.bind( this ),
				fsErrorHandler
			);
		};

		/**
		 * TODO
		 */
		ConsoleFile.prototype.log = function ( tmpString ) {
			// console.log( 'logging to file: ' + this._fileName + ' #### ' + tmpString );
			this._write( 'log ', tmpString );
		};

		/** @private */
		ConsoleFile.prototype._write = function ( prefix, str ) {
			var stringToWrite = prefix + str + "\n";

			if ( this._fsIsReady === false ) {
				// if we don't yet have a handle to a log file, we will write to this
				// cache, and then once the file handle has been obtained, the contents
				// of this cache will be written to disk
				this._fsCache.push ( stringToWrite );
				console.log( 'writing to cache ', str );
			} else {
				console.log( 'writing to file ', str );
				this._fsFile.createWriter(
					function( fileWriter ) {
						fileWriter.seek( fileWriter.length );

						var blob = new Blob( [stringToWrite], {type: 'text/plain'} );
						fileWriter.write( blob );
					}.bind( this ),
					fsErrorHandler
				);
			}
		};

		/** @private */
		ConsoleFile.prototype._flushCacheToFile = function () {
			// Create a FileWriter object for our FileEntry (log.txt).
			this._fsFile.createWriter(
				function( fileWriter ) {
					fileWriter.seek( fileWriter.length );

					// TODO for some reason this gets called but the thing isn't written into a file
					// maybe I can change this so that stuff is flushed into the file in a timeout, so
					// I can have control over file operations (only one at a time) as to avoid writing to the file
					// from two different locations
					// NEEDS INVESTIGATING
					var blob = new Blob( this._fsCache, {type: 'text/plain'} );
					fileWriter.write( blob );

					this._fsCache = [];
				}.bind( this ),
				fsErrorHandler
			);
		};

		// ConsoleFile.prototype.info = function () {};
		// ConsoleFile.prototype.warn = function () {};
		// ConsoleFile.prototype.error = function () {};
	};

	// private utility functions

	function isBrowserSupported () {
		if ( !navigator.webkitPersistentStorage ) {
			return false;
		}

		return true;
	};

	function patchConsole () {
		console.file = function () {
			var nopFunction = function () {};

			return {
				log: nopFunction,
				info: nopFunction,
				warn: nopFunction,
				error: nopFunction
			};
		};
	};

	function fsErrorHandler ( error ) {
		var msg = '';

		switch (e.code) {
			case FileError.QUOTA_EXCEEDED_ERR:
				msg = 'QUOTA_EXCEEDED_ERR';
			break;

			case FileError.NOT_FOUND_ERR:
				msg = 'NOT_FOUND_ERR';
			break;

			case FileError.SECURITY_ERR:
				msg = 'SECURITY_ERR';
			break;

			case FileError.INVALID_MODIFICATION_ERR:
				msg = 'INVALID_MODIFICATION_ERR';
			break;

			case FileError.INVALID_STATE_ERR:
				msg = 'INVALID_STATE_ERR';
			break;

			default:
				msg = 'Unknown Error';
			break;
		};

		console.log( 'ConsoleFile.JS FileSystem error: ' + msg, e) ;
	};

}() );<|endoftext|>


<commit_before>/**@
* #DOM
* @category Graphics
* Draws entities as DOM nodes, specifically `<DIV>`s.
*/
Crafty.c("DOM", {
    /**@
	* #._element
	* @comp DOM
	* The DOM element used to represent the entity.
	*/
	_element: null,

	init: function () {
		this._element = document.createElement("div");
		Crafty.stage.inner.appendChild(this._element);
		this._element.style.position = "absolute";
		this._element.id = "ent" + this[0];

		this.bind("Change", function () {
			if (!this._changed) {
				this._changed = true;
				Crafty.DrawManager.add(this);
			}
		});

		function updateClass() {
			var i = 0, c = this.__c, str = "";
			for (i in c) {
				str += ' ' + i;
			}
			str = str.substr(1);
			this._element.className = str;
		}

		this.bind("NewComponent", updateClass).bind("RemoveComponent", updateClass);

		if (Crafty.support.prefix === "ms" && Crafty.support.version < 9) {
			this._filters = {};

			this.bind("Rotate", function (e) {
				var m = e.matrix,
					elem = this._element.style,
					M11 = m.M11.toFixed(8),
					M12 = m.M12.toFixed(8),
					M21 = m.M21.toFixed(8),
					M22 = m.M22.toFixed(8);

				this._filters.rotation = "progid:DXImageTransform.Microsoft.Matrix(M11=" + M11 + ", M12=" + M12 + ", M21=" + M21 + ", M22=" + M22 + ",sizingMethod='auto expand')";
			});
		}

		this.bind("Remove", this.undraw);
		this.bind("RemoveComponent", function (compName) {
			if (compName === "DOM")
				this.undraw();
		});
	},

	/**@
	* #.getDomId
	* @comp DOM
	* @sign public this .getId()
	*
	* Get the Id of the DOM element used to represent the entity.
	*/
	getDomId: function() {
		return this._element.id;
	},

	/**@
	* #.DOM
	* @comp DOM
	* @trigger Draw - when the entity is ready to be drawn to the stage - { style:String, type:"DOM", co}
	* @sign public this .DOM(HTMLElement elem)
	* @param elem - HTML element that will replace the dynamically created one
	*
	* Pass a DOM element to use rather than one created. Will set `._element` to this value. Removes the old element.
	*/
	DOM: function (elem) {
		if (elem && elem.nodeType) {
			this.undraw();
			this._element = elem;
			this._element.style.position = 'absolute';
		}
		return this;
	},

	/**@
	* #.draw
	* @comp DOM
	* @sign public this .draw(void)
	*
	* Updates the CSS properties of the node to draw on the stage.
	*/
	draw: function () {
		var style = this._element.style,
			coord = this.__coord || [0, 0, 0, 0],
			co = { x: coord[0], y: coord[1] },
			prefix = Crafty.support.prefix,
			trans = [];

		if (!this._visible) style.visibility = "hidden";
		else style.visibility = "visible";

		//utilize CSS3 if supported
		if (Crafty.support.css3dtransform) {
			trans.push("translate3d(" + (~~this._x) + "px," + (~~this._y) + "px,0)");
		} else {
			style.left = ~~(this._x) + "px";
			style.top = ~~(this._y) + "px";
		}

		style.width = ~~(this._w) + "px";
		style.height = ~~(this._h) + "px";
		style.zIndex = this._z;

		style.opacity = this._alpha;
		style[prefix + "Opacity"] = this._alpha;

		//if not version 9 of IE
		if (prefix === "ms" && Crafty.support.version < 9) {
			//for IE version 8, use ImageTransform filter
			if (Crafty.support.version === 8) {
				this._filters.alpha = "progid:DXImageTransform.Microsoft.Alpha(Opacity=" + (this._alpha * 100) + ")"; // first!
				//all other versions use filter
			} else {
				this._filters.alpha = "alpha(opacity=" + (this._alpha * 100) + ")";
			}
		}

		if (this._mbr) {
			var origin = this._origin.x + "px " + this._origin.y + "px";
			style.transformOrigin = origin;
			style[prefix + "TransformOrigin"] = origin;
			if (Crafty.support.css3dtransform) trans.push("rotateZ(" + this._rotation + "deg)");
			else trans.push("rotate(" + this._rotation + "deg)");
		}

		if (this._flipX) {
			trans.push("scaleX(-1)");
			if (prefix === "ms" && Crafty.support.version < 9) {
				this._filters.flipX = "fliph";
			}
		}

		if (this._flipY) {
			trans.push("scaleY(-1)");
			if (prefix === "ms" && Crafty.support.version < 9) {
				this._filters.flipY = "flipv";
			}
		}

		//apply the filters if IE
		if (prefix === "ms" && Crafty.support.version < 9) {
			this.applyFilters();
		}

		style.transform = trans.join(" ");
		style[prefix + "Transform"] = trans.join(" ");

		this.trigger("Draw", { style: style, type: "DOM", co: co });

		return this;
	},

	applyFilters: function () {
		this._element.style.filter = "";
		var str = "";

		for (var filter in this._filters) {
			if (!this._filters.hasOwnProperty(filter)) continue;
			str += this._filters[filter] + " ";
		}

		this._element.style.filter = str;
	},

	/**@
	* #.undraw
	* @comp DOM
	* @sign public this .undraw(void)
	*
	* Removes the element from the stage.
	*/
	undraw: function () {
		if (this._element) {
			Crafty.stage.inner.removeChild(this._element);
		}
		return this;
	},

	/**@
	* #.css
	* @comp DOM
	* @sign public * css(String property, String value)
	* @param property - CSS property to modify
	* @param value - Value to give the CSS property
	* @sign public * css(Object map)
	* @param map - Object where the key is the CSS property and the value is CSS value
	*
	* Apply CSS styles to the element.
	*
	* Can pass an object where the key is the style property and the value is style value.
	*
	* For setting one style, simply pass the style as the first argument and the value as the second.
	*
	* The notation can be CSS or JS (e.g. `text-align` or `textAlign`).
	*
	* To return a value, pass the property.
	*
	* @example
	* ~~~
	* this.css({'text-align', 'center', font: 'Arial'});
	* this.css("textAlign", "center");
	* this.css("text-align"); //returns center
	* ~~~
	*/
	css: function (obj, value) {
		var key,
			elem = this._element,
			val,
			style = elem.style;

		//if an object passed
		if (typeof obj === "object") {
			for (key in obj) {
				if (!obj.hasOwnProperty(key)) continue;
				val = obj[key];
				if (typeof val === "number") val += 'px';

				style[Crafty.DOM.camelize(key)] = val;
			}
		} else {
			//if a value is passed, set the property
			if (value) {
				if (typeof value === "number") value += 'px';
				style[Crafty.DOM.camelize(obj)] = value;
			} else { //otherwise return the computed property
				return Crafty.DOM.getStyle(elem, obj);
			}
		}

		this.trigger("Change");

		return this;
	}
});

/**
* Fix IE6 background flickering
*/
try {
	document.execCommand("BackgroundImageCache", false, true);
} catch (e) { }

Crafty.extend({
    /**@
	* #Crafty.DOM
	* @category Graphics
	*
	* Collection of utilities for using the DOM.
	*/
	DOM: {
	/**@
		* #Crafty.DOM.window
		* @comp Crafty.DOM
		*
		* Object with `width` and `height` values representing the width
		* and height of the `window`.
		*/
		window: {
			init: function () {
				this.width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
				this.height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
			},

			width: 0,
			height: 0
		},

		/**@
		* #Crafty.DOM.inner
		* @comp Crafty.DOM
		* @sign public Object Crafty.DOM.inner(HTMLElement obj)
		* @param obj - HTML element to calculate the position
		* @returns Object with `x` key being the `x` position, `y` being the `y` position
		*
		* Find a DOM elements position including
		* padding and border.
		*/
		inner: function (obj) {
			var rect = obj.getBoundingClientRect(),
				x = rect.left + (window.pageXOffset ? window.pageXOffset : document.body.scrollLeft),
				y = rect.top + (window.pageYOffset ? window.pageYOffset : document.body.scrollTop),

			//border left
				borderX = parseInt(this.getStyle(obj, 'border-left-width') || 0, 10) || parseInt(this.getStyle(obj, 'borderLeftWidth') || 0, 10) || 0,
				borderY = parseInt(this.getStyle(obj, 'border-top-width') || 0, 10) || parseInt(this.getStyle(obj, 'borderTopWidth') || 0, 10) || 0;

			x += borderX;
			y += borderY;

			return { x: x, y: y };
		},

		/**@
		* #Crafty.DOM.getStyle
		* @comp Crafty.DOM
		* @sign public Object Crafty.DOM.getStyle(HTMLElement obj, String property)
		* @param obj - HTML element to find the style
		* @param property - Style to return
		*
		* Determine the value of a style on an HTML element. Notation can be
		* in either CSS or JS.
		*/
		getStyle: function (obj, prop) {
			var result;
			if (obj.currentStyle)
				result = obj.currentStyle[this.camelize(prop)];
			else if (window.getComputedStyle)
				result = document.defaultView.getComputedStyle(obj, null).getPropertyValue(this.csselize(prop));
			return result;
		},

		/**
		* Used in the Zepto framework
		*
		* Converts CSS notation to JS notation
		*/
		camelize: function (str) {
			return str.replace(/-+(.)?/g, function (match, chr){ return chr ? chr.toUpperCase() : '' });
		},

		/**
		* Converts JS notation to CSS notation
		*/
		csselize: function (str) {
			return str.replace(/[A-Z]/g, function (chr){ return chr ? '-' + chr.toLowerCase() : '' });
		},

		/**@
		* #Crafty.DOM.translate
		* @comp Crafty.DOM
		* @sign public Object Crafty.DOM.translate(Number x, Number y)
		* @param x - x position to translate
		* @param y - y position to translate
		* @return Object with x and y as keys and translated values
		*
		* Method will translate x and y positions to positions on the
		* stage. Useful for mouse events with `e.clientX` and `e.clientY`.
		*/
		translate: function (x, y) {
			return {
				x: (x - Crafty.stage.x + document.body.scrollLeft + document.documentElement.scrollLeft - Crafty.viewport._x)/Crafty.viewport._zoom,
				y: (y - Crafty.stage.y + document.body.scrollTop + document.documentElement.scrollTop - Crafty.viewport._y)/Crafty.viewport._zoom
			}
		}
	}
});
<commit_msg>only change css style attributes on DOM elements when they are changed. Some (not very well understood) combinations of browsers and servers causes the image to be reloaded when styles changes. This patch makes the problem less anoying, and hopefully improves performance in any case.<commit_after>/**@
* #DOM
* @category Graphics
* Draws entities as DOM nodes, specifically `<DIV>`s.
*/
Crafty.c("DOM", {
    /**@
	* #._element
	* @comp DOM
	* The DOM element used to represent the entity.
	*/
	_element: null,
	//holds current styles, so we can check if there are changes to be written to the DOM
	_cssStyles: null,

	init: function () {
		this._cssStyles = { visibility: '', left: '', top: '', width: '', height: '', zIndex: '', opacity: '', transformOrigin: '', transform: '' };
		this._element = document.createElement("div");
		Crafty.stage.inner.appendChild(this._element);
		this._element.style.position = "absolute";
		this._element.id = "ent" + this[0];

		this.bind("Change", function () {
			if (!this._changed) {
				this._changed = true;
				Crafty.DrawManager.add(this);
			}
		});

		function updateClass() {
			var i = 0, c = this.__c, str = "";
			for (i in c) {
				str += ' ' + i;
			}
			str = str.substr(1);
			this._element.className = str;
		}

		this.bind("NewComponent", updateClass).bind("RemoveComponent", updateClass);

		if (Crafty.support.prefix === "ms" && Crafty.support.version < 9) {
			this._filters = {};

			this.bind("Rotate", function (e) {
				var m = e.matrix,
					elem = this._element.style,
					M11 = m.M11.toFixed(8),
					M12 = m.M12.toFixed(8),
					M21 = m.M21.toFixed(8),
					M22 = m.M22.toFixed(8);

				this._filters.rotation = "progid:DXImageTransform.Microsoft.Matrix(M11=" + M11 + ", M12=" + M12 + ", M21=" + M21 + ", M22=" + M22 + ",sizingMethod='auto expand')";
			});
		}

		this.bind("Remove", this.undraw);
		this.bind("RemoveComponent", function (compName) {
			if (compName === "DOM")
				this.undraw();
		});
	},

	/**@
	* #.getDomId
	* @comp DOM
	* @sign public this .getId()
	*
	* Get the Id of the DOM element used to represent the entity.
	*/
	getDomId: function() {
		return this._element.id;
	},

	/**@
	* #.DOM
	* @comp DOM
	* @trigger Draw - when the entity is ready to be drawn to the stage - { style:String, type:"DOM", co}
	* @sign public this .DOM(HTMLElement elem)
	* @param elem - HTML element that will replace the dynamically created one
	*
	* Pass a DOM element to use rather than one created. Will set `._element` to this value. Removes the old element.
	*/
	DOM: function (elem) {
		if (elem && elem.nodeType) {
			this.undraw();
			this._element = elem;
			this._element.style.position = 'absolute';
		}
		return this;
	},

	/**@
	* #.draw
	* @comp DOM
	* @sign public this .draw(void)
	*
	* Updates the CSS properties of the node to draw on the stage.
	*/
	draw: function () {
		var style = this._element.style,
			coord = this.__coord || [0, 0, 0, 0],
			co = { x: coord[0], y: coord[1] },
			prefix = Crafty.support.prefix,
			trans = [];

		if (this._cssStyles.visibility != this._visible) {
			this._cssStyles.visibility = this._visible;
			if (!this._visible) {
				style.visibility = "hidden";
			} else {
				style.visibility = "visible";
			}
		}

		//utilize CSS3 if supported
		if (Crafty.support.css3dtransform) {
			trans.push("translate3d(" + (~~this._x) + "px," + (~~this._y) + "px,0)");
		} else {
			if (this._cssStyles.left != this._x) {
				this._cssStyles.left = this._x;
				style.left = ~~(this._x) + "px";
			}
			if (this._cssStyles.top != this._y) {
				this._cssStyles.top = this._y;
				style.top = ~~(this._y) + "px";
			}
		}

		if (this._cssStyles.width != this._w) {
			this._cssStyles.width = this._w;
			style.width = ~~(this._w) + "px";
		}
		if (this._cssStyles.height != this._h) {
			this._cssStyles.height = this._h;
			style.height = ~~(this._h) + "px";
		}
		if (this._cssStyles.zIndex != this._z) {
			this._cssStyles.zIndex = this._z;
			style.zIndex = this._z;
		}

		if (this._cssStyles.opacity != this._alpha) {
			this._cssStyles.opacity = this._alpha;
			style.opacity = this._alpha;
			style[prefix + "Opacity"] = this._alpha;
		}

		//if not version 9 of IE
		if (prefix === "ms" && Crafty.support.version < 9) {
			//for IE version 8, use ImageTransform filter
			if (Crafty.support.version === 8) {
				this._filters.alpha = "progid:DXImageTransform.Microsoft.Alpha(Opacity=" + (this._alpha * 100) + ")"; // first!
				//all other versions use filter
			} else {
				this._filters.alpha = "alpha(opacity=" + (this._alpha * 100) + ")";
			}
		}

		if (this._mbr) {
			var origin = this._origin.x + "px " + this._origin.y + "px";
			style.transformOrigin = origin;
			style[prefix + "TransformOrigin"] = origin;
			if (Crafty.support.css3dtransform) trans.push("rotateZ(" + this._rotation + "deg)");
			else trans.push("rotate(" + this._rotation + "deg)");
		}

		if (this._flipX) {
			trans.push("scaleX(-1)");
			if (prefix === "ms" && Crafty.support.version < 9) {
				this._filters.flipX = "fliph";
			}
		}

		if (this._flipY) {
			trans.push("scaleY(-1)");
			if (prefix === "ms" && Crafty.support.version < 9) {
				this._filters.flipY = "flipv";
			}
		}

		//apply the filters if IE
		if (prefix === "ms" && Crafty.support.version < 9) {
			this.applyFilters();
		}

		if (this._cssStyles.transform != trans.join(" ")) {
			this._cssStyles.transform = trans.join(" ");
			style.transform = this._cssStyles.transform;
			style[prefix + "Transform"] = this._cssStyles.transform;
		}

		this.trigger("Draw", { style: style, type: "DOM", co: co });

		return this;
	},

	applyFilters: function () {
		this._element.style.filter = "";
		var str = "";

		for (var filter in this._filters) {
			if (!this._filters.hasOwnProperty(filter)) continue;
			str += this._filters[filter] + " ";
		}

		this._element.style.filter = str;
	},

	/**@
	* #.undraw
	* @comp DOM
	* @sign public this .undraw(void)
	*
	* Removes the element from the stage.
	*/
	undraw: function () {
		if (this._element) {
			Crafty.stage.inner.removeChild(this._element);
		}
		return this;
	},

	/**@
	* #.css
	* @comp DOM
	* @sign public * css(String property, String value)
	* @param property - CSS property to modify
	* @param value - Value to give the CSS property
	* @sign public * css(Object map)
	* @param map - Object where the key is the CSS property and the value is CSS value
	*
	* Apply CSS styles to the element.
	*
	* Can pass an object where the key is the style property and the value is style value.
	*
	* For setting one style, simply pass the style as the first argument and the value as the second.
	*
	* The notation can be CSS or JS (e.g. `text-align` or `textAlign`).
	*
	* To return a value, pass the property.
	*
	* @example
	* ~~~
	* this.css({'text-align', 'center', font: 'Arial'});
	* this.css("textAlign", "center");
	* this.css("text-align"); //returns center
	* ~~~
	*/
	css: function (obj, value) {
		var key,
			elem = this._element,
			val,
			style = elem.style;

		//if an object passed
		if (typeof obj === "object") {
			for (key in obj) {
				if (!obj.hasOwnProperty(key)) continue;
				val = obj[key];
				if (typeof val === "number") val += 'px';

				style[Crafty.DOM.camelize(key)] = val;
			}
		} else {
			//if a value is passed, set the property
			if (value) {
				if (typeof value === "number") value += 'px';
				style[Crafty.DOM.camelize(obj)] = value;
			} else { //otherwise return the computed property
				return Crafty.DOM.getStyle(elem, obj);
			}
		}

		this.trigger("Change");

		return this;
	}
});

/**
* Fix IE6 background flickering
*/
try {
	document.execCommand("BackgroundImageCache", false, true);
} catch (e) { }

Crafty.extend({
    /**@
	* #Crafty.DOM
	* @category Graphics
	*
	* Collection of utilities for using the DOM.
	*/
	DOM: {
	/**@
		* #Crafty.DOM.window
		* @comp Crafty.DOM
		*
		* Object with `width` and `height` values representing the width
		* and height of the `window`.
		*/
		window: {
			init: function () {
				this.width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
				this.height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
			},

			width: 0,
			height: 0
		},

		/**@
		* #Crafty.DOM.inner
		* @comp Crafty.DOM
		* @sign public Object Crafty.DOM.inner(HTMLElement obj)
		* @param obj - HTML element to calculate the position
		* @returns Object with `x` key being the `x` position, `y` being the `y` position
		*
		* Find a DOM elements position including
		* padding and border.
		*/
		inner: function (obj) {
			var rect = obj.getBoundingClientRect(),
				x = rect.left + (window.pageXOffset ? window.pageXOffset : document.body.scrollLeft),
				y = rect.top + (window.pageYOffset ? window.pageYOffset : document.body.scrollTop),

			//border left
				borderX = parseInt(this.getStyle(obj, 'border-left-width') || 0, 10) || parseInt(this.getStyle(obj, 'borderLeftWidth') || 0, 10) || 0,
				borderY = parseInt(this.getStyle(obj, 'border-top-width') || 0, 10) || parseInt(this.getStyle(obj, 'borderTopWidth') || 0, 10) || 0;

			x += borderX;
			y += borderY;

			return { x: x, y: y };
		},

		/**@
		* #Crafty.DOM.getStyle
		* @comp Crafty.DOM
		* @sign public Object Crafty.DOM.getStyle(HTMLElement obj, String property)
		* @param obj - HTML element to find the style
		* @param property - Style to return
		*
		* Determine the value of a style on an HTML element. Notation can be
		* in either CSS or JS.
		*/
		getStyle: function (obj, prop) {
			var result;
			if (obj.currentStyle)
				result = obj.currentStyle[this.camelize(prop)];
			else if (window.getComputedStyle)
				result = document.defaultView.getComputedStyle(obj, null).getPropertyValue(this.csselize(prop));
			return result;
		},

		/**
		* Used in the Zepto framework
		*
		* Converts CSS notation to JS notation
		*/
		camelize: function (str) {
			return str.replace(/-+(.)?/g, function (match, chr){ return chr ? chr.toUpperCase() : '' });
		},

		/**
		* Converts JS notation to CSS notation
		*/
		csselize: function (str) {
			return str.replace(/[A-Z]/g, function (chr){ return chr ? '-' + chr.toLowerCase() : '' });
		},

		/**@
		* #Crafty.DOM.translate
		* @comp Crafty.DOM
		* @sign public Object Crafty.DOM.translate(Number x, Number y)
		* @param x - x position to translate
		* @param y - y position to translate
		* @return Object with x and y as keys and translated values
		*
		* Method will translate x and y positions to positions on the
		* stage. Useful for mouse events with `e.clientX` and `e.clientY`.
		*/
		translate: function (x, y) {
			return {
				x: (x - Crafty.stage.x + document.body.scrollLeft + document.documentElement.scrollLeft - Crafty.viewport._x)/Crafty.viewport._zoom,
				y: (y - Crafty.stage.y + document.body.scrollTop + document.documentElement.scrollTop - Crafty.viewport._y)/Crafty.viewport._zoom
			}
		}
	}
});
<|endoftext|>


<commit_before>// = require govuk_publishing_components/modules
// = require modules/global-bar
// = require modules/sticky-element-container
// = require modules/toggle
// = require modules/track-click
// = require modules/cross-domain-tracking

$(document).ready(function () {
  GOVUK.modules.start()
})
<commit_msg>Call cookie banner component JS<commit_after>// = require govuk_publishing_components/modules
// = require govuk_publishing_components/components/cookie-banner
// = require modules/global-bar
// = require modules/sticky-element-container
// = require modules/toggle
// = require modules/track-click
// = require modules/cross-domain-tracking

$(document).ready(function () {
  GOVUK.modules.start()
})
<|endoftext|>


<commit_before>Lizard.Views.GraphAndLegendView = Backbone.Marionette.Layout.extend({
    template: '#graph-and-legend-template',
    initialize: function (options) {
        this.listenTo(this.model, 'change', this.updateScatterPlotCheckbox, this);
    },
    events: {
        'dragover': function () {return false;},
        'dragenter': function () {return false;},
        'drop': 'onDrop'
    },
    regions: {
        legendItems: ".legend-items",
        graph: ".graph-region"
    },
    onDragover: function(e) {
    },
    onDragenter: function(e) {
    },
    onDrop: function(e) {
        e.preventDefault();
        $('#sidebar').css('-webkit-filter', 'blur(0px)'); // disable target div blur
        $('.graph').removeClass('stitched'); // remove stitch border
        // fetch and add the timeseries
        var self = this;
        var dataJson = e.originalEvent.dataTransfer.getData('Text');
        if (dataJson) {
            var data = JSON.parse(dataJson);
            var timeseries = new Lizard.Models.TimeseriesActual({url: data.url});
            timeseries.fetch()
                .done(function (model, response) {
                    var item = new Lizard.Models.GraphItem({
                        timeseries: model
                        // , color: colorbrewer.Set3[9][Math.floor((Math.random()*8)+1)]
                    });
                    self.model.get('graphItems').add(item);
                });
        }
    },
    updateScatterPlotCheckbox: function(e) {
        var $drawWhenToItems = this.$el.find('.draw-when-to-items');
        if (this.model.get('hasTwoItems') === true) {
            $drawWhenToItems.removeClass('hide');
        }
        else {
            $drawWhenToItems.addClass('hide');
        }
    },
    onShow: function(e) {
        // var plot = this.$el.find('.graph').initializePlot();
        // plot.observeCollection(this.model.get('graphItems'));
        // plot.observeInitialPeriod(account);

        var graphView = new Lizard.Views.Graph({
            model: this.model,
            account: account
        });

        var legendView = new Lizard.Views.GraphLegendCollection({
            collection: this.model.get('graphItems')
        });

        this.graph.show(graphView);
        this.legendItems.show(legendView);
    }
});
<commit_msg>Remove unused line<commit_after>Lizard.Views.GraphAndLegendView = Backbone.Marionette.Layout.extend({
    template: '#graph-and-legend-template',
    initialize: function (options) {
        this.listenTo(this.model, 'change', this.updateScatterPlotCheckbox, this);
    },
    events: {
        'dragover': function () {return false;},
        'dragenter': function () {return false;},
        'drop': 'onDrop'
    },
    regions: {
        legendItems: ".legend-items",
        graph: ".graph-region"
    },
    onDragover: function(e) {
    },
    onDragenter: function(e) {
    },
    onDrop: function(e) {
        e.preventDefault();
        $('#sidebar').css('-webkit-filter', 'blur(0px)'); // disable target div blur
        $('.graph').removeClass('stitched'); // remove stitch border
        // fetch and add the timeseries
        var self = this;
        var dataJson = e.originalEvent.dataTransfer.getData('Text');
        if (dataJson) {
            var data = JSON.parse(dataJson);
            var timeseries = new Lizard.Models.TimeseriesActual({url: data.url});
            timeseries.fetch()
                .done(function (model, response) {
                    var item = new Lizard.Models.GraphItem({
                        timeseries: model
                    });
                    self.model.get('graphItems').add(item);
                });
        }
    },
    updateScatterPlotCheckbox: function(e) {
        var $drawWhenToItems = this.$el.find('.draw-when-to-items');
        if (this.model.get('hasTwoItems') === true) {
            $drawWhenToItems.removeClass('hide');
        }
        else {
            $drawWhenToItems.addClass('hide');
        }
    },
    onShow: function(e) {
        // var plot = this.$el.find('.graph').initializePlot();
        // plot.observeCollection(this.model.get('graphItems'));
        // plot.observeInitialPeriod(account);

        var graphView = new Lizard.Views.Graph({
            model: this.model,
            account: account
        });

        var legendView = new Lizard.Views.GraphLegendCollection({
            collection: this.model.get('graphItems')
        });

        this.graph.show(graphView);
        this.legendItems.show(legendView);
    }
});
<|endoftext|>