<commit_before>// @flow
import React, { Component } from 'react';
import { Button, Divider, Form, Grid, Header, Input, Message, Modal, Segment, Table } from 'semantic-ui-react';
import InputRange from 'react-input-range';

import NumericLabel from '../../utils/NumericLabel';
import AccountName from '../global/AccountName';

export default class AccountsProxy extends Component {
  constructor(props) {
    super(props);
    this.state = {
      vests: 0,
      sp: 0,
      editDelegationFor: false
    };
    this.props.actions.resetState = this.resetState.bind(this);
  }
  state = {
    vests: 0,
    sp: 0,
    editDelegationFor: false
  }
  componentWillReceiveProps = (nextProps) => {
    if (nextProps.processing.account_delegate_vesting_shares_error) {
      this.setState({
        undelegateError: nextProps.processing.account_delegate_vesting_shares_error
      })
      nextProps.actions.setDelegateVestingSharesCompleted();
    }
    if (nextProps.processing.account_delegate_vesting_shares_resolved) {
      nextProps.actions.setDelegateVestingSharesCompleted();
      this.resetState();
    }
  }
  resetState() {
    this.setState({
      editDelegationFor: false,
      undelegateError: false,
    });
  }
  handleCancel = () => {
    this.resetState();
  }
  handleOnChange = (value) => {
    const vests = parseFloat(value).toFixed(6);
    const props = this.props.steem.props;
    const totalVestsSteem = parseFloat(props.total_vesting_fund_steem.split(" ")[0])
    const totalVests = parseFloat(props.total_vesting_shares.split(" ")[0])
    const sp = totalVestsSteem * vests / totalVests;
    this.setState({ vests, sp });
  }

  handleOnChangeComplete = (value) => {
    const vests = parseFloat(value).toFixed(6);
    const props = this.props.steem.props;
    const totalVestsSteem = parseFloat(props.total_vesting_fund_steem.split(" ")[0])
    const totalVests = parseFloat(props.total_vesting_shares.split(" ")[0])
    const sp = totalVestsSteem * vests / totalVests;
    this.setState({ vests, sp });
  }
  handleVestingSharesRemove = (e, props) => {
    let { delegator, delegatee, id } = props.value.delegatee;
    delegatee = delegatee.toLowerCase().replace('@', '');
    const permissions = this.props.keys.permissions;
    this.setState({undelegateError: false})
    this.props.actions.useKey('setDelegateVestingShares', { delegator, delegatee, vestingShares: 0.000000 }, permissions[delegator])
  }
  handleSetDelegateVesting = (e, props) => {
    this.setState({
      editDelegationFor: props.value
    })
  }
  handleSetDelegateVestingConfirm = (e, props) => {
    const { vests } = this.state;
    const { permissions } = this.props.keys;
    const delegator = this.state.editDelegationFor;
    const delegatee = this.state[delegator];
    this.props.actions.useKey('setDelegateVestingShares', { delegator, delegatee, vestingShares: vests }, permissions[delegator])
    e.preventDefault();
  }
  handleChangeVestingShares = (e, props) => {
    const editing = this.state.editDelegationFor;
    const newState = {};
    newState[editing] = props.value.trim();
    this.setState(newState);
  }
  render() {
    const t = this;
    let addVesting = false;
    let undelegateError = false;
    if (this.state.undelegateError) {
      undelegateError = (
        <Message
          error
          header='Operation Error'
          content={this.state.undelegateError}
        />
      )
    }
    const numberFormat = {
      shortFormat: true,
      shortFormatMinValue: 1000
    };
    const {
      account_delegate_vesting_shares_error,
      account_delegate_vesting_shares_pending,
      account_delegate_vesting_shares_resolved
    } = this.props.processing;
    if (this.state.editDelegationFor) {
      const name = this.state.editDelegationFor;
      const account = this.props.account.accounts[name];
      const delegated = parseFloat(account.delegated_vesting_shares.split(" ")[0]);
      const vests = parseFloat(account.vesting_shares.split(" ")[0]);
      const available = vests - delegated;
      const target = parseFloat(this.state.vests)
      const delegateWarning = (target > available - 100)
      addVesting = (
        <Modal
          size="small"
          open
          header="Delegate Vests to another Account"
          content={
            <Form
              error={account_delegate_vesting_shares_error || delegateWarning}
              loading={account_delegate_vesting_shares_pending}
            >
              <Segment
                padded
                basic
              >

                  Please enter the name of the target account that you wish to delegate
                  a portion of the {name} account's vested weight to.

                <Input
                  fluid
                  name="delegatee"
                  placeholder="Delegatee Account Name"
                  autoFocus
                  onChange={this.handleChangeVestingShares}
                />
                <Divider />

                  Use the slider to determine how much of your VESTS to delegate.

                <Grid>
                  <Grid.Row>
                    <Grid.Column width={12}>
                      <Segment padded="very" basic>
                        <InputRange
                          maxValue={available}
                          minValue={0.000001}
                          value={this.state.vests}
                          onChange={this.handleOnChange}
                          onChangeComplete={this.handleOnChangeComplete}
                        />
                      </Segment>
                    </Grid.Column>
                    <Grid.Column width={4}>

                        Steem Power
                        <NumericLabel params={numberFormat}>{this.state.sp}</NumericLabel>
                        {' SP'}

                          -<NumericLabel params={numberFormat}>{this.state.vests}</NumericLabel>
                          {' VESTS'}

                    </Grid.Column>
                  </Grid.Row>
                </Grid>
                <Message
                  error
                  header="Warning! Delegating too much SP."
                  content="Leaving so little SP in this account may cause it to stop functioning, meaning you may have to power up more Steem or Delegate to this account from another in order to even undo what you are about to do."
                />
                <Message
                  header="Caution! Delegation takes 7 days to revoke."
                  content="If you confirm this delegation, it will take effect immediately. When you are ready to revoke the delegation, it will take 7 days for that delegated balance to return to your account."
                />
                <Message
                  error
                  header='Operation Error'
                  content={account_delegate_vesting_shares_error}
                />
              </Segment>
            </Form>
          }
          actions={[
            {
              key: 'no',
              content: 'Cancel Operation',
              floated: 'left',
              color: 'red',
              onClick: this.handleCancel,
              disabled: account_delegate_vesting_shares_pending
            },
            {
              key: 'yes',
              type: 'submit',
              content: 'Confirm Delegation',
              color: 'blue',
              value: this.state.editDelegationFor,
              onClick: this.handleSetDelegateVestingConfirm,
              disabled: account_delegate_vesting_shares_pending
            }
          ]}
        />
      );
    }
    const names = this.props.keys.names;
    const accounts = names.map((name) => {
      const account = this.props.account.accounts[name];
      const delegatees = (this.props.account.vestingDelegations || {})[name];
      const delegated = account.delegated_vesting_shares;
      const hasDelegated = (delegated && delegated !== "0.000000 VESTS");
      const hasDelegatees = (delegatees && delegatees.length);
      const delegatedAmount = parseFloat(delegated.split(" ")[0]);
      const vests = parseFloat(account.vesting_shares.split(" ")[0]);
      const available = vests - delegatedAmount;
      return (

              <AccountName name={name} />

                  <NumericLabel params={numberFormat}>{vests}</NumericLabel>
                 VESTS

              <NumericLabel params={numberFormat}>{available}</NumericLabel>

                VESTS

              {(hasDelegated)
                ? (
                  <NumericLabel params={numberFormat}>{delegatedAmount}</NumericLabel>
                ) : (
                  0
                )
              }

                VESTS

            {(hasDelegatees)
              ? (

                        Delegatee

                        Amount

                        Date

                  {delegatees.map((delegatee) => {
                    const vests = parseFloat(delegatee.vesting_shares.split(" ")[0])
                    return (

                          <AccountName name={delegatee.delegatee} />

                          <NumericLabel params={numberFormat}>{vests}</NumericLabel>

{delegatee.min_delegation_time}

                          <Button
                            color="orange"
                            size="small"
                            icon="trash"
                            value={{ delegatee }}
                            onClick={this.handleVestingSharesRemove}
                          />

                    )
                  })}

              )
              : 'No active delegations'
            }

            <Button
              icon="plus"
              color="green"
              onClick={this.handleSetDelegateVesting}
              value={name}
            />

      );
    });
    return (
      <Segment basic padded>
        {addVesting}

            Each account may delegate a portion of it's voting power to other accounts.
            This process takes place immediately for the target account, and may be revoked
            on the date shown. Once you revoked, the vesting amount will remain locked for
            exactly 7 days before returning to the original account.

        {undelegateError}

                Name

                Available

                Delegating

                Delegated

                Controls

            {accounts}

      </Segment>
    );
  }
}
<commit_msg>Moved the errors to display independently<commit_after>// @flow
import React, { Component } from 'react';
import { Button, Divider, Form, Grid, Header, Input, Message, Modal, Segment, Table } from 'semantic-ui-react';
import InputRange from 'react-input-range';

import NumericLabel from '../../utils/NumericLabel';
import AccountName from '../global/AccountName';

export default class AccountsProxy extends Component {
  constructor(props) {
    super(props);
    this.state = {
      vests: 0,
      sp: 0,
      editDelegationFor: false
    };
    this.props.actions.resetState = this.resetState.bind(this);
  }
  state = {
    vests: 0,
    sp: 0,
    editDelegationFor: false
  }
  componentWillReceiveProps = (nextProps) => {
    if (nextProps.processing.account_delegate_vesting_shares_error) {
      this.setState({
        undelegateError: nextProps.processing.account_delegate_vesting_shares_error
      })
      nextProps.actions.setDelegateVestingSharesCompleted();
    }
    if (nextProps.processing.account_delegate_vesting_shares_resolved) {
      nextProps.actions.setDelegateVestingSharesCompleted();
      this.resetState();
    }
  }
  resetState() {
    this.setState({
      editDelegationFor: false,
      undelegateError: false,
    });
  }
  handleCancel = () => {
    this.resetState();
  }
  handleOnChange = (value) => {
    const vests = parseFloat(value).toFixed(6);
    const props = this.props.steem.props;
    const totalVestsSteem = parseFloat(props.total_vesting_fund_steem.split(" ")[0])
    const totalVests = parseFloat(props.total_vesting_shares.split(" ")[0])
    const sp = totalVestsSteem * vests / totalVests;
    this.setState({ vests, sp });
  }

  handleOnChangeComplete = (value) => {
    const vests = parseFloat(value).toFixed(6);
    const props = this.props.steem.props;
    const totalVestsSteem = parseFloat(props.total_vesting_fund_steem.split(" ")[0])
    const totalVests = parseFloat(props.total_vesting_shares.split(" ")[0])
    const sp = totalVestsSteem * vests / totalVests;
    this.setState({ vests, sp });
  }
  handleVestingSharesRemove = (e, props) => {
    let { delegator, delegatee, id } = props.value.delegatee;
    delegatee = delegatee.toLowerCase().replace('@', '');
    const permissions = this.props.keys.permissions;
    this.setState({undelegateError: false})
    this.props.actions.useKey('setDelegateVestingShares', { delegator, delegatee, vestingShares: 0.000000 }, permissions[delegator])
  }
  handleSetDelegateVesting = (e, props) => {
    this.setState({
      editDelegationFor: props.value
    })
  }
  handleSetDelegateVestingConfirm = (e, props) => {
    const { vests } = this.state;
    const { permissions } = this.props.keys;
    const delegator = this.state.editDelegationFor;
    const delegatee = this.state[delegator];
    this.props.actions.useKey('setDelegateVestingShares', { delegator, delegatee, vestingShares: vests }, permissions[delegator])
    e.preventDefault();
  }
  handleChangeVestingShares = (e, props) => {
    const editing = this.state.editDelegationFor;
    const newState = {};
    newState[editing] = props.value.trim();
    this.setState(newState);
  }
  render() {
    const t = this;
    let addVesting = false;
    let undelegateError = false;
    if (this.state.undelegateError) {
      undelegateError = (
        <Message
          error
          header='Operation Error'
          content={this.state.undelegateError}
        />
      )
    }
    const numberFormat = {
      shortFormat: true,
      shortFormatMinValue: 1000
    };
    const {
      account_delegate_vesting_shares_error,
      account_delegate_vesting_shares_pending,
      account_delegate_vesting_shares_resolved
    } = this.props.processing;
    if (this.state.editDelegationFor) {
      const name = this.state.editDelegationFor;
      const account = this.props.account.accounts[name];
      const delegated = parseFloat(account.delegated_vesting_shares.split(" ")[0]);
      const vests = parseFloat(account.vesting_shares.split(" ")[0]);
      const available = vests - delegated;
      const target = parseFloat(this.state.vests)
      const delegateWarning = (target > available - 100)
      addVesting = (
        <Modal
          size="small"
          open
          header="Delegate Vests to another Account"
          content={
            <Form
              loading={account_delegate_vesting_shares_pending}
            >
              <Segment
                padded
                basic
              >

                  Please enter the name of the target account that you wish to delegate
                  a portion of the {name} account's vested weight to.

                <Input
                  fluid
                  name="delegatee"
                  placeholder="Delegatee Account Name"
                  autoFocus
                  onChange={this.handleChangeVestingShares}
                />
                <Divider />

                  Use the slider to determine how much of your VESTS to delegate.

                <Grid>
                  <Grid.Row>
                    <Grid.Column width={12}>
                      <Segment padded="very" basic>
                        <InputRange
                          maxValue={available}
                          minValue={0.000001}
                          value={this.state.vests}
                          onChange={this.handleOnChange}
                          onChangeComplete={this.handleOnChangeComplete}
                        />
                      </Segment>
                    </Grid.Column>
                    <Grid.Column width={4}>

                        Steem Power
                        <NumericLabel params={numberFormat}>{this.state.sp}</NumericLabel>
                        {' SP'}

                          -<NumericLabel params={numberFormat}>{this.state.vests}</NumericLabel>
                          {' VESTS'}

                    </Grid.Column>
                  </Grid.Row>
                </Grid>
                <Message
                  error
                  visible={delegateWarning}
                  header="Warning! Delegating too much SP."
                  content="Leaving so little SP in this account may cause it to stop functioning, meaning you may have to power up more Steem or Delegate to this account from another in order to even undo what you are about to do."
                />
                <Message
                  header="Caution! Delegation takes 7 days to revoke."
                  content="If you confirm this delegation, it will take effect immediately. When you are ready to revoke the delegation, it will take 7 days for that delegated balance to return to your account."
                />
                <Message
                  error
                  visible={(typeof account_delegate_vesting_shares_error === 'undefined') ? false : true}
                  header='Operation Error'
                  content={account_delegate_vesting_shares_error}
                />
              </Segment>
            </Form>
          }
          actions={[
            {
              key: 'no',
              content: 'Cancel Operation',
              floated: 'left',
              color: 'red',
              onClick: this.handleCancel,
              disabled: account_delegate_vesting_shares_pending
            },
            {
              key: 'yes',
              type: 'submit',
              content: 'Confirm Delegation',
              color: 'blue',
              value: this.state.editDelegationFor,
              onClick: this.handleSetDelegateVestingConfirm,
              disabled: account_delegate_vesting_shares_pending
            }
          ]}
        />
      );
    }
    const names = this.props.keys.names;
    const accounts = names.map((name) => {
      const account = this.props.account.accounts[name];
      const delegatees = (this.props.account.vestingDelegations || {})[name];
      const delegated = account.delegated_vesting_shares;
      const hasDelegated = (delegated && delegated !== "0.000000 VESTS");
      const hasDelegatees = (delegatees && delegatees.length);
      const delegatedAmount = parseFloat(delegated.split(" ")[0]);
      const vests = parseFloat(account.vesting_shares.split(" ")[0]);
      const available = vests - delegatedAmount;
      return (

              <AccountName name={name} />

                  <NumericLabel params={numberFormat}>{vests}</NumericLabel>
                 VESTS

              <NumericLabel params={numberFormat}>{available}</NumericLabel>

                VESTS

              {(hasDelegated)
                ? (
                  <NumericLabel params={numberFormat}>{delegatedAmount}</NumericLabel>
                ) : (
                  0
                )
              }

                VESTS

            {(hasDelegatees)
              ? (

                        Delegatee

                        Amount

                        Date

                  {delegatees.map((delegatee) => {
                    const vests = parseFloat(delegatee.vesting_shares.split(" ")[0])
                    return (

                          <AccountName name={delegatee.delegatee} />

                          <NumericLabel params={numberFormat}>{vests}</NumericLabel>

{delegatee.min_delegation_time}

                          <Button
                            color="orange"
                            size="small"
                            icon="trash"
                            value={{ delegatee }}
                            onClick={this.handleVestingSharesRemove}
                          />

                    )
                  })}

              )
              : 'No active delegations'
            }

            <Button
              icon="plus"
              color="green"
              onClick={this.handleSetDelegateVesting}
              value={name}
            />

      );
    });
    return (
      <Segment basic padded>
        {addVesting}

            Each account may delegate a portion of it's voting power to other accounts.
            This process takes place immediately for the target account, and may be revoked
            on the date shown. Once you revoked, the vesting amount will remain locked for
            exactly 7 days before returning to the original account.

        {undelegateError}

                Name

                Available

                Delegating

                Delegated

                Controls

            {accounts}

      </Segment>
    );
  }
}
<|endoftext|>


<commit_before>var LABEL_REGEX = /^\d+-(\w+)/;

var Gira = function(username, repo, github,milestone){
	this.username = username;
	this.repo = repo;
	this.owner = username;
	this.milestone = milestone||'';
	this.last_label='';
	this.github = github;
	this.milestones = {};
	this.owners =  {};
};

Gira.prototype = {
	renderError: function(message) {
		$('.flash-messages').html(nunjucks.render("src/templates/error.html",{message:message}));
	},
	groupIssuesByLabels: function() {
		var that = this;
		return Q.all([this.github.getIssues(this.owner,this.repo,this.milestone),this.github.getLabels(this.owner,this.repo)]).then(function(data){
			var issues = data[0];
			var labels = _(data[1]).filter(function(label){
				return LABEL_REGEX.test(label.name);
			});
			var groupIssue = _(issues).groupBy(function(issue){
				var column = _(issue.labels).find(function(label){
					return LABEL_REGEX.test(label.name);
				});
				if(column){
					return column.name;
				}
				return "0-Backlog";
			});
			return _.chain(labels.concat({name:"0-Backlog"}))
				.sortBy(function(label){
					return label.name;
				})
				.uniq(true,function(label){
					return label.name;
				})
				.tap(function(label){
					that.last_label = label[label.length-1].name;
				})
				.map(function(label){
				return [label.name, groupIssue[label.name]];
			}).value();
		}).catch(function(error){
			that.renderError(JSON.parse(error.responseText).message);
		});
	},
	draggablify: function(){
		var that = this;
		var $issues = $('#contributions-calendar .contrib-details.grid .col .lbl div[draggable=true]');
		$issues.on('dragstart', function (e) {
			e.originalEvent.dataTransfer.effectAllowed = 'move';
			e.originalEvent.dataTransfer.setData('text/plain', this.id);
		});
		$(".col").on('dragover', function (e) {
			if (e.preventDefault) e.preventDefault(); // allows us to drop
			$(this).removeClass("over").addClass('over');
			e.originalEvent.dataTransfer.dropEffect = 'move';
			return false;
		}).on('drop', function (e) {
			if (e.stopPropagation) e.stopPropagation();
			var $issue = $('#'+e.originalEvent.dataTransfer.getData('text/plain'));

			that.github.deleteLabel(that.owner,that.repo,$issue.attr('id'),$issue.data('label'));
			that.github.addLabel(that.owner,that.repo,$issue.attr('id'), this.id);

			$(this).removeClass("over")
				.find('span.lbl')
				.append($($issue));
			return false;
		});
	},

	changeOwner:function(event){
		this.owner=$(event.target).attr('name');
		this.renderRepoSelector();
	},
	changeRepo:function(event){
		this.repo=$(event.target).attr('name');
		this.renderKanban();
	},
	renderRepoSelector: function(repos){
		var that = this;
		if (this.github.checkLogin()){
			return this.github.getRepos().then(
				function(repos){
					var groupedRepo = _(repos).groupBy(function(repo){
						return repo.owner.login;
					});
					that.repo = that.repo || groupedRepo[that.owner][0].name;
					var res ={checked:that.owner, checkedRepo:that.repo, owners:_(groupedRepo).map(function(repos){return repos[0].owner;}), repos: groupedRepo[that.owner]};
					var compiled = nunjucks.render('src/templates/repo-selector.html',res);
					$(".pagehead.repohead h1").html(compiled);
					$(".select-menu.owner-select-menu input[type=radio]").on("change", that.changeOwner.bind(that));
					$(".target-repo-menu.select-menu input[type=radio]").on("change", that.changeRepo.bind(that));
				},
				function(error){
					console.log("get repo error",error);
					var compiled = nunjucks.render('src/templates/repo-selector.html',{username:that.username,repo:that.repo});
					$(".pagehead.repohead h1").html(compiled);
				});
		}else{
			var compiled = nunjucks.render('src/templates/repo-selector.html',{username:that.username,repo:that.repo});
			$(".pagehead.repohead h1").html(compiled);
		}
		return Q();
	},
	renderKanban: function() {
		var that = this;
		return this.groupIssuesByLabels().then(
			function(issues){
				var compiled = mynunjucks.render('src/templates/gira.html', {issuesWithLabel: issues, last_label:that.last_label});
				$('#contributions-calendar').html(compiled);
			})
			.then(function(){
				$('.close.close-issue').click(function(){
					var $close = $(this);
					that.github.getIssues(that.owner,that.repo, that.milestone, $close.data('issue'))
						.then(function(issue){
							issue.state = 'close';
							issue.assignee = issue.assignee && issue.assignee.login;
							issue.milestone = issue.milestone && issue.milestone.number;

							that.github.newIssue(that.owner,that.repo,issue,issue.number)
								.then(function(){
									$('#'+$close.data('issue')).remove();
								});
						});
				});
			});
	},
	renderHeader:function(){
		var that = this;
		if (this.github.checkLogin()){
			this.github.getUser().then(
				function(user){
					that.owner = that.owner || user.login;
					$(".header").html(nunjucks.render('src/templates/header.html', {user:user}));
					$(".octicon.octicon-log-out").click(that.github.logout);
				},
				function(error) {
					$(".header").html(nunjucks.render('src/templates/header.html'));
				}
			);
		}else{
					$(".header").html(nunjucks.render('src/templates/header.html'));
		}
	},
	renderMilestone: function(){
		var that = this;
		this.github.getMilestones(this.owner,this.repo).then(function(milestones){
			$(".pagehead.repohead div.sidebar-milestone-widget").html(
				mynunjucks.render('src/templates/milestones.html',{
					selected:that.milestone && _(milestones).find(function(milestone){
						return milestone.number===that.milestone;
					}),
					milestones:milestones
				})
			);
			$(".sidebar-milestone-widget .select-menu a.select-menu-item").click(function(e){
				e.preventDefault();
				that.milestone =$(this).data('milestone');
				that.render();
				return false;
			});

		});
	},
	createLabel: function() {
		var that = this;
		return function(){
			var form = $('form:visible');
			that.github.createLabel(that.owner,that.repo,{
				color:form.find('input[name=color]').val().replace('#',''),
				name: (parseInt(/^(\d+)-\w+/.exec(that.last_label).pop())+1) + '-' +form.find('input[name=label]').val()
			}).then(function(){
				that.render();
				$(".facebox-close").click();
			});
			return false;
		};
	},
	createIssue: function() {
		var that = this;
		return function(){
			var form = $('form:visible');
			that.github.newIssue(that.owner,that.repo,{
				title:form.find("input[name='issue[title]']").val(),
				body: form.find("textarea[name='issue[body]']").val(),
				assignee: form.find(".assignee input[type=radio]:checked").val(),
				milestone: form.find(".milestone input[type=radio]:checked").val(),
				labels:form.find("a.selected input").get().map(function(input){return input.value;})
			},form.data('issue-id')).then(function(){
				that.render();
				$(".facebox-close").click();
			});
			return false;
		};
	},
    bindEvent: function () {
        var that = this;
        $('#jk-preview').click(function(){
            var data = {text: $('#issue_body').val()};
            that.github.markdown(data).then(function(result){
                if(result){
                    $('.comment-body.markdown-body.js-comment-body p').html(result);
                }
            })
        });
        $('.sidebar .color-label').click(function (e) {
            e.preventDefault();
            $(this).toggleClass('selected');
        });
        $('.form-actions .primary.button').submit(function () {
            that.renderKanban();
        });
    },
	renderFaceBox: function() {
		var that = this;
		return function(e){
			e.preventDefault();
			if(this.id==='new-issue'){
				$('.facebox-content:visible').html(nunjucks.render('src/templates/create-issue.html'));
			}else if(this.id==='new-label'){
							$('.facebox-content:visible').html(nunjucks.render('src/templates/create-label.html'));
			}else{
                Q.all([that.github.getIssues(that.owner,that.repo,null,$(this).data("issue-id")), that.github.getAssignees(that.owner,that.repo)]).then(function(data) {
                    console.log(data);
                    var issue = data[0];
                    issue.assignees = data[1];
                    $('.facebox-content').html(nunjucks.render('src/templates/create-issue.html',issue));
                }).then(that.bindEvent).then(that.bindUploadImageEvent);
			}
			return false;
		};
	},
    bindEvent: function () {

    },
    bindUploadImageEvent: function() {
        $('#write_bucket_').bind("dragenter drop", image, function(){
            var dropbox = $('#write_bucket_'),
                message = $('.drag-and-drop', dropbox);

            dropbox.filedrop({
                paramname:'pic',

                maxfiles: 5,
                maxfilesize: 2, // in mb
                url: 'post_file.php',

                uploadFinished:function(i,file,response){
                    alert("finished");
                    //$.data(file).addClass('done');
                    // response is the JSON object that post_file.php returns
                },

                error: function(err, file) {
                    switch(err) {
                        case 'BrowserNotSupported':
                            showMessage('Your browser does not support HTML5 file uploads!');
                            break;
                        case 'TooManyFiles':
                            alert('Too many files! Please select 5 at most!');
                            break;
                        case 'FileTooLarge':
                            alert(file.name+' is too large! Please upload files up to 2mb.');
                            break;
                        default:
                            break;
                    }
                },

                // Called before each upload is started
                beforeEach: function(file){
                    alert("before...");
                },

                uploadStarted:function(i, file, len){
                    createImage(file);
                }

            });

            function createImage(file){

                var image = $('.comment-form-textarea');

                var reader = new FileReader();

                reader.onload = function(e){

                    // e.target.result holds the DataURL which
                    // can be used as a source of the image:

                    image.text(e.target.result);
                };

                // Reading the file as a DataURL. When finished,
                // this will trigger the onload function above:
                reader.readAsDataURL(file);

                // Associating a preview container
                // with the file, using jQuery's $.data():

                $.data(file,preview);
            }

            function showMessage(msg){
                message.html(msg);
            }
        });

    },
	render: function(){
		var that = this;
		that.renderHeader();
		return that.renderRepoSelector()
			.then(that.renderMilestone.bind(that))
			.then(that.renderKanban.bind(that))
			.then(that.draggablify.bind(that))
			.then(function() {
				$('a[rel=facebox]').click(that.renderFaceBox());
			})
			.catch(function(error){
				$('.flash-messages').html(nunjucks.render("src/templates/error.html",{message:message}));
			});
	}
};

<commit_msg>add file type constrains and error handler<commit_after>var LABEL_REGEX = /^\d+-(\w+)/;

var Gira = function(username, repo, github,milestone){
	this.username = username;
	this.repo = repo;
	this.owner = username;
	this.milestone = milestone||'';
	this.last_label='';
	this.github = github;
	this.milestones = {};
	this.owners =  {};
};

Gira.prototype = {
	renderError: function(message) {
		$('.flash-messages').html(nunjucks.render("src/templates/error.html",{message:message}));
	},
	groupIssuesByLabels: function() {
		var that = this;
		return Q.all([this.github.getIssues(this.owner,this.repo,this.milestone),this.github.getLabels(this.owner,this.repo)]).then(function(data){
			var issues = data[0];
			var labels = _(data[1]).filter(function(label){
				return LABEL_REGEX.test(label.name);
			});
			var groupIssue = _(issues).groupBy(function(issue){
				var column = _(issue.labels).find(function(label){
					return LABEL_REGEX.test(label.name);
				});
				if(column){
					return column.name;
				}
				return "0-Backlog";
			});
			return _.chain(labels.concat({name:"0-Backlog"}))
				.sortBy(function(label){
					return label.name;
				})
				.uniq(true,function(label){
					return label.name;
				})
				.tap(function(label){
					that.last_label = label[label.length-1].name;
				})
				.map(function(label){
				return [label.name, groupIssue[label.name]];
			}).value();
		}).catch(function(error){
			that.renderError(JSON.parse(error.responseText).message);
		});
	},
	draggablify: function(){
		var that = this;
		var $issues = $('#contributions-calendar .contrib-details.grid .col .lbl div[draggable=true]');
		$issues.on('dragstart', function (e) {
			e.originalEvent.dataTransfer.effectAllowed = 'move';
			e.originalEvent.dataTransfer.setData('text/plain', this.id);
		});
		$(".col").on('dragover', function (e) {
			if (e.preventDefault) e.preventDefault(); // allows us to drop
			$(this).removeClass("over").addClass('over');
			e.originalEvent.dataTransfer.dropEffect = 'move';
			return false;
		}).on('drop', function (e) {
			if (e.stopPropagation) e.stopPropagation();
			var $issue = $('#'+e.originalEvent.dataTransfer.getData('text/plain'));

			that.github.deleteLabel(that.owner,that.repo,$issue.attr('id'),$issue.data('label'));
			that.github.addLabel(that.owner,that.repo,$issue.attr('id'), this.id);

			$(this).removeClass("over")
				.find('span.lbl')
				.append($($issue));
			return false;
		});
	},

	changeOwner:function(event){
		this.owner=$(event.target).attr('name');
		this.renderRepoSelector();
	},
	changeRepo:function(event){
		this.repo=$(event.target).attr('name');
		this.renderKanban();
	},
	renderRepoSelector: function(repos){
		var that = this;
		if (this.github.checkLogin()){
			return this.github.getRepos().then(
				function(repos){
					var groupedRepo = _(repos).groupBy(function(repo){
						return repo.owner.login;
					});
					that.repo = that.repo || groupedRepo[that.owner][0].name;
					var res ={checked:that.owner, checkedRepo:that.repo, owners:_(groupedRepo).map(function(repos){return repos[0].owner;}), repos: groupedRepo[that.owner]};
					var compiled = nunjucks.render('src/templates/repo-selector.html',res);
					$(".pagehead.repohead h1").html(compiled);
					$(".select-menu.owner-select-menu input[type=radio]").on("change", that.changeOwner.bind(that));
					$(".target-repo-menu.select-menu input[type=radio]").on("change", that.changeRepo.bind(that));
				},
				function(error){
					console.log("get repo error",error);
					var compiled = nunjucks.render('src/templates/repo-selector.html',{username:that.username,repo:that.repo});
					$(".pagehead.repohead h1").html(compiled);
				});
		}else{
			var compiled = nunjucks.render('src/templates/repo-selector.html',{username:that.username,repo:that.repo});
			$(".pagehead.repohead h1").html(compiled);
		}
		return Q();
	},
	renderKanban: function() {
		var that = this;
		return this.groupIssuesByLabels().then(
			function(issues){
				var compiled = mynunjucks.render('src/templates/gira.html', {issuesWithLabel: issues, last_label:that.last_label});
				$('#contributions-calendar').html(compiled);
			})
			.then(function(){
				$('.close.close-issue').click(function(){
					var $close = $(this);
					that.github.getIssues(that.owner,that.repo, that.milestone, $close.data('issue'))
						.then(function(issue){
							issue.state = 'close';
							issue.assignee = issue.assignee && issue.assignee.login;
							issue.milestone = issue.milestone && issue.milestone.number;

							that.github.newIssue(that.owner,that.repo,issue,issue.number)
								.then(function(){
									$('#'+$close.data('issue')).remove();
								});
						});
				});
			});
	},
	renderHeader:function(){
		var that = this;
		if (this.github.checkLogin()){
			this.github.getUser().then(
				function(user){
					that.owner = that.owner || user.login;
					$(".header").html(nunjucks.render('src/templates/header.html', {user:user}));
					$(".octicon.octicon-log-out").click(that.github.logout);
				},
				function(error) {
					$(".header").html(nunjucks.render('src/templates/header.html'));
				}
			);
		}else{
					$(".header").html(nunjucks.render('src/templates/header.html'));
		}
	},
	renderMilestone: function(){
		var that = this;
		this.github.getMilestones(this.owner,this.repo).then(function(milestones){
			$(".pagehead.repohead div.sidebar-milestone-widget").html(
				mynunjucks.render('src/templates/milestones.html',{
					selected:that.milestone && _(milestones).find(function(milestone){
						return milestone.number===that.milestone;
					}),
					milestones:milestones
				})
			);
			$(".sidebar-milestone-widget .select-menu a.select-menu-item").click(function(e){
				e.preventDefault();
				that.milestone =$(this).data('milestone');
				that.render();
				return false;
			});

		});
	},
	createLabel: function() {
		var that = this;
		return function(){
			var form = $('form:visible');
			that.github.createLabel(that.owner,that.repo,{
				color:form.find('input[name=color]').val().replace('#',''),
				name: (parseInt(/^(\d+)-\w+/.exec(that.last_label).pop())+1) + '-' +form.find('input[name=label]').val()
			}).then(function(){
				that.render();
				$(".facebox-close").click();
			});
			return false;
		};
	},
	createIssue: function() {
		var that = this;
		return function(){
			var form = $('form:visible');
			that.github.newIssue(that.owner,that.repo,{
				title:form.find("input[name='issue[title]']").val(),
				body: form.find("textarea[name='issue[body]']").val(),
				assignee: form.find(".assignee input[type=radio]:checked").val(),
				milestone: form.find(".milestone input[type=radio]:checked").val(),
				labels:form.find("a.selected input").get().map(function(input){return input.value;})
			},form.data('issue-id')).then(function(){
				that.render();
				$(".facebox-close").click();
			});
			return false;
		};
	},
    bindEvent: function () {
        var that = this;
        $('#jk-preview').click(function(){
            var data = {text: $('#issue_body').val()};
            that.github.markdown(data).then(function(result){
                if(result){
                    $('.comment-body.markdown-body.js-comment-body p').html(result);
                }
            })
        });
        $('.sidebar .color-label').click(function (e) {
            e.preventDefault();
            $(this).toggleClass('selected');
        });
        $('.form-actions .primary.button').submit(function () {
            that.renderKanban();
        });
    },
	renderFaceBox: function() {
		var that = this;
		return function(e){
			e.preventDefault();
			if(this.id==='new-issue'){
				$('.facebox-content:visible').html(nunjucks.render('src/templates/create-issue.html'));
			}else if(this.id==='new-label'){
							$('.facebox-content:visible').html(nunjucks.render('src/templates/create-label.html'));
			}else{
                Q.all([that.github.getIssues(that.owner,that.repo,null,$(this).data("issue-id")), that.github.getAssignees(that.owner,that.repo)]).then(function(data) {
                    console.log(data);
                    var issue = data[0];
                    issue.assignees = data[1];
                    $('.facebox-content').html(nunjucks.render('src/templates/create-issue.html',issue));
                }).then(that.bindEvent).then(that.bindUploadImageEvent);
			}
			return false;
		};
	},
    bindEvent: function () {

    },
    bindUploadImageEvent: function() {
        $('#write_bucket_').bind("dragenter drop", function(){
            var dropbox = $('#write_bucket_'),
                message = $('.drag-and-drop', dropbox);
            dropbox.filedrop({
                paramname:'pic',

                maxfiles: 5,
                maxfilesize: 2, // in mb
                url: 'post_file.php',

                uploadFinished:function(i,file,response){
                    alert("finished");
                    //$.data(file).addClass('done');
                    // response is the JSON object that post_file.php returns
                },

                allowedfiletypes: ['image/jpeg','image/png','image/gif'],   // filetypes allowed by Content-Type.  Empty array means no restrictions
                allowedfileextensions: ['.jpg','.jpeg','.png','.gif'], // file extensions allowed. Empty array means no restrictions

                error: function(err, file) {
                    alert("error.................");
                    alert(err);
//                    switch(err) {
//                        case 'BrowserNotSupported':
//                            showMessage('Your browser does not support HTML5 file uploads!');
//                            break;
//                        case 'TooManyFiles':
//                            alert('Too many files! Please select 5 at most!');
//                            break;
//                        case 'FileTooLarge':
//                            alert(file.name+' is too large! Please upload files up to 2mb.');
//                            break;
//                        default:
//                            break;
//                    }
                },

                // Called before each upload is started
                beforeEach: function(file){
                    alert("before each...");
                },

                uploadStarted:function(i, file, len){
                    alert("started");
                    createImage(file);
                }

            });

            function createImage(file){

                var image = $('.comment-form-textarea');

                var reader = new FileReader();

                reader.onload = function(e){

                    // e.target.result holds the DataURL which
                    // can be used as a source of the image:

                    image.text(e.target.result);
                };

                // Reading the file as a DataURL. When finished,
                // this will trigger the onload function above:
                reader.readAsDataURL(file);

                // Associating a preview container
                // with the file, using jQuery's $.data():

                $.data(file,preview);
            }

            function showMessage(msg){
                message.html(msg);
            }
        });

    },
	render: function(){
		var that = this;
		that.renderHeader();
		return that.renderRepoSelector()
			.then(that.renderMilestone.bind(that))
			.then(that.renderKanban.bind(that))
			.then(that.draggablify.bind(that))
			.then(function() {
				$('a[rel=facebox]').click(that.renderFaceBox());
			})
			.catch(function(error){
				$('.flash-messages').html(nunjucks.render("src/templates/error.html",{message:message}));
			});
	}
};

<|endoftext|>


<commit_before>(function() {
	var glowMap,
		defaultBase,
		document = window.document,
		thisScriptSrc = ( document.body || document.getElementsByTagName('head')[0] ).lastChild.src;

	// get default base from last script element
	defaultBase = thisScriptSrc.slice( 0, thisScriptSrc.lastIndexOf('/') ) + '/../';

	// track when document is ready, must run before the page is finished loading
	if (!document.readyState) {
		if (document.addEventListener) { // like Mozilla
			document.addEventListener('DOMContentLoaded',
				function () {
					document.removeEventListener('DOMContentLoaded', arguments.callee, false);
					document.readyState = 'complete';
				},
				false
			);
		}
	}

	/**
		@public
		@name Glow
		@function
		@description Creates an instance of the Glow JavaScript Library.
		@param {string} [version]
		@param {object} [opts]
		@param {string} [opts.base] The path to the base folder, in which the Glow versions are kept.
		@param {boolean} [opts.debug] Have all filenames modified to point to debug versions.
	*/
	window.Glow = function(version, opts) { /*debug*///log.info('new Glow("'+Array.prototype.join.call(arguments, '", "')+'")');
		opts = opts || {};

		var glowInstance,
			debug = (opts.debug)? '.debug' : '',
			base = opts.base || defaultBase;

		glowMap = {
			versions: ['2.0.0', '@'+'SRC@'],
			'2.0.0': {
				'core':    ['core'+debug+'.js'],
				'widgets': ['core', 'widgets'+debug+'.js', 'widgets'+debug+'.css']
			}
		};

		if (opts._map) { glowMap = opts._map; } // for testing purposes map can be overridden

		version = getVersion(version); /*debug*///log.info('Version is "'+version+'"');

		if (Glow._build.instances[version]) { /*debug*///log.info('instance for "'+version+'" already exists.');
			return Glow._build.instances[version];
		}

		// opts.base should be formatted like a directory
		if (base.slice(-1) !== '/') {
			base += '/';
		}

		glowInstance = createGlowInstance(version, base);
		Glow._build.instances[version] = glowInstance;

		glowInstance.debug = false; /*!debug*/ glowInstance.debug = true; /*gubed!*/
		glowInstance.UID = 'glow' + Math.floor(Math.random() * (1<<30));

 		glowInstance.load('core'); // core is always loaded;

		return glowInstance;
	}

	/**
		@private
		@name getVersion
		@function
		@param {string} version A (possibly imprecise) version identifier, like "2".
		@description Find the most recent, available version of glow that matches.
	 */
	var getVersion = function(version) { /*debug*///log.info('getVersion("'+version+'")');
		var versions = glowMap.versions,
			matchThis = version + '.';

		// TODO: an empty version means: the very latest version

		var i = versions.length;
		while (i--) {
			if ( ( versions[i] + '.').indexOf(matchThis) === 0 ) {
				return versions[i];
			}
		}

		throw new Error('Version "'+version+'" does not exist');
	}

	/**
		@private
		@name getMap
		@function
		@description Find the file map for a given version.
		@param {string} version Resolved identifier, like '2.0.0'.
		@returns {object} A map of package names to files list.
	 */
	var getMap = function(version, debug) { /*debug*///log.info('getMap("'+version+'")');
		var versions = glowMap.versions,
			map = null,
			versionFound = false;

		var i = versions.length;
		while (--i > -1) {
			if (glowMap[versions[i]]) { map = glowMap[versions[i]]; }
			if (versions[i] === version) { versionFound = true; }
			if (versionFound && map) { return map; }
		}

		throw new Error('No map available for version "' + version + '".');
	}

	/**
		@private
		@name injectJs
		@function
		@description Start asynchronously loading an external JavaScript file.
	 */
	var injectJs = function(src) { /*debug*///log.info('injectJs("'+src+'")');
		var head,
			script;

		head = document.getElementsByTagName('head')[0];
		script = document.createElement('script');
		script.src = src;
		script.type = 'text/javascript';

		head.insertBefore(script, head.firstChild); // rather than appendChild() to avoid IE bug when injecting SCRIPTs after BASE tag opens. see: http://shauninman.com/archive/2007/04/13/operation_aborted
	}

	/**
		@private
		@name injectCss
		@function
		@description Start asynchronously loading an external CSS file.
	 */
	var injectCss = function(src) { /*debug*///log.info('injectCss("'+src+'")');
		var head,
			link;

		head = document.getElementsByTagName('head')[0];
		link = document.createElement('link');
		link.href = src;
		link.type = 'text/css';
		link.rel = 'stylesheet';

		head.insertBefore(link, head.firstChild);
	}

	/** @private */
	Glow._build = {
		provided: [], // provided but not yet complete
		instances: {} // built
	}

	/**
		@private
		@name Glow.provide
		@function
		@param {function} builder A function to run, given an instance of glow, and will add a feature to glow.
		@description Provide a builder function to Glow as part of a package.
	 */
	Glow.provide = function(builder) { /*debug*///log.info('Glow.provide('+typeof builder+')');
		Glow._build.provided.push(builder);
	}

	/**
		@private
		@name Glow.complete
		@function
		@param {string} name The name of the completed package.
		@param {string} version The version of the completed package.
		@description Signals that no more builder functions will be provided by this package.
	 */
	Glow.complete = function(name, version) { /*debug*///log.info('complete('+name+', '+version+')');
		var glow,
			loading,
			builders;

		// now that we have the name and version we can move the builders out of provided cache
		glow = Glow._build.instances[version];
		if (!glow) { /*debug*///log.info('Cannot complete, unknown version of glow: '+version);
			throw new Error('Cannot complete, unknown version of glow: '+version);
		}
		glow._build.builders[name] = Glow._build.provided;
		Glow._build.provided = [];

		// shortcuts
		loading   = glow._build.loading;
		builders = glow._build.builders;

		// try to build packages, in the same order they were loaded
		for (var i = 0; i < loading.length; i++) { // loading.length may change during loop
			if (!builders[loading[i]]) { /*debug*///log.info(loading[i]+' has no builders.');
				break;
			}

			// run the builders for this package in the same order they were loaded
			for (var j = 0, jlen = builders[loading[i]].length; j < jlen; j++) { /*debug*///log.info('running builder '+j+ ' for '+loading[i]+' version '+glow.version);
				builders[loading[i]][j](glow); // builder will modify glow
			}

			// remove this package from the loaded and builders list, now that it's built
			if (glow._removeReadyBlock) { glow._removeReadyBlock('glow_loading_'+loading[i]); }
			builders[loading[i]] = undefined;
			loading.splice(i, 1);
			i--;

		}

		// try to run onLoaded callbacks
		glow._release();
	}

	/**
		@name createGlowInstance
		@private
		@function
		@description Creates an instance of the Glow library.
		@param {string} version
		@param {string} base
	 */
	var createGlowInstance = function(version, base) { /*debug*///log.info('new glow("'+Array.prototype.join.call(arguments, '", "')+'")');
		var glow = function(nodeListContents) {
			return new glow.NodeList(nodeListContents);
		};

		glow.version = version;
		glow.base = base;
		glow.map = getMap(version);
		glow._build = {
			loading: [],   // names of packages requested but not yet built, in same order as requested.
			builders: {},  // completed but not yet built (waiting on dependencies). Like _build.builders[packageName]: [function, function, ...].
			history: {},   // names of every package ever loaded for this instance
			callbacks: []
		};

		// copy properties from glowInstanceMembers
		for (var prop in glowInstanceMembers) {
			glow[prop] = glowInstanceMembers[prop];
		}

		return glow;
	}

	/**
		@name glowInstanceMembers
		@private
		@description All members of this object will be copied onto little-glow instances
		@type {Object}
	*/
	var glowInstanceMembers = {
		/**
			@public
			@name glow#load
			@function
			@description Add a package to this instance of the Glow library.
			@param {string[]} ... The names of 1 or more packages to add.
		 */
		load: function() { /*debug*///log.info('glow.load("'+Array.prototype.join.call(arguments, '", "')+'") for version '+this.version);
			var name = '',
				src,
				depends;

			for (var i = 0, len = arguments.length; i < len; i++) {
				name = arguments[i];

				if (this._build.history[name]) { /*debug*///log.info('already loaded package "'+name+'" for version '+this.version+', skipping.');
					continue;
				}

				this._build.history[name] = true;

				// packages have dependencies, listed in the map: a single js file, css files, or even other packages
				depends = this.map[name]; /*debug*///log.info('depends for '+name+' '+this.version+': "'+depends.join('", "')+'"');
				for (var j = 0, lenj = depends.length; j < lenj; j++) {

					if (depends[j].slice(-3) === '.js') { /*debug*///log.info('dependent js: "'+depends[j]+'"');
						src = this.base + this.version + '/' + depends[j];

						// readyBlocks are removed in _release()
						if (this._addReadyBlock) { this._addReadyBlock('glow_loading_'+name); } // provided by core
						this._build.loading.push(name);

						injectJs(src);
					}
					else if (depends[j].slice(-4) === '.css') { /*debug*///log.info('dependent css "'+depends[j]+'"');
						src = this.base + this.version + '/' + depends[j];
						injectCss(src);
					}
					else { /*debug*///log.info('dependent package: "'+depends[j]+'"');
						this.load(depends[j]); // recursively load dependency packages
					}
				}
			}

			return this;
		},
		/**
			@public
			@name glow#loaded
			@function
			@param {function} onLoadCallback Called when all the packages load.
			@description Do something when all the packages load.
		 */
		loaded: function(onLoadCallback) { /*debug*///log.info('glow.loaded('+typeof onLoadCallback+') for version '+this.version);
			this._build.callbacks.push(onLoadCallback);
			if (this._addReadyBlock) { this._addReadyBlock('glow_loading_loadedcallback'); }

			this._release();

			return this;
		},
		/**
			@private
			@name glow#_release
			@function
			@description If all loaded packages are now built, then run the onLoaded callbacks.
		 */
		_release: function() { /*debug*///log.info('glow._release("'+this.version+'")');
			var callback;

			if (this._build.loading.length !== 0) { /*debug*///log.info('waiting for '+this._build.loading.length+' to finish.');
				return;
			}
			/*debug*///log.info('running '+this._build.callbacks.length+' loaded callbacks for version "'+this.version+'"');

			// run and remove each available _onloaded callback
			while (callback = this._build.callbacks.shift()) {
				callback(this);
				if (this._removeReadyBlock) { this._removeReadyBlock('glow_loading_loadedcallback'); }
			}
		},
		/**
			@name glow#ready
			@function
			@param {function} onReadyCallback Called when all the packages load and the DOM is available.
			@description Do something when all the packages load and the DOM is ready.
		 */
		ready: function(onReadyCallback) { /*debug*///log.info('(ember) glow#ready('+typeof onReadyCallback+') for version '+this.version+'. There are '+this._build.loading.length+' loaded packages waiting to be built.');
			this.loaded(function(glow) {
				glow.ready( function() { onReadyCallback(glow); } );
			});

			return this;
		}
	}
})();<commit_msg>debug: Removing glow.debug bool, it gets overwritten anyway<commit_after>(function() {
	var glowMap,
		defaultBase,
		document = window.document,
		thisScriptSrc = ( document.body || document.getElementsByTagName('head')[0] ).lastChild.src;

	// get default base from last script element
	defaultBase = thisScriptSrc.slice( 0, thisScriptSrc.lastIndexOf('/') ) + '/../';

	// track when document is ready, must run before the page is finished loading
	if (!document.readyState) {
		if (document.addEventListener) { // like Mozilla
			document.addEventListener('DOMContentLoaded',
				function () {
					document.removeEventListener('DOMContentLoaded', arguments.callee, false);
					document.readyState = 'complete';
				},
				false
			);
		}
	}

	/**
		@public
		@name Glow
		@function
		@description Creates an instance of the Glow JavaScript Library.
		@param {string} [version]
		@param {object} [opts]
		@param {string} [opts.base] The path to the base folder, in which the Glow versions are kept.
		@param {boolean} [opts.debug] Have all filenames modified to point to debug versions.
	*/
	window.Glow = function(version, opts) { /*debug*///log.info('new Glow("'+Array.prototype.join.call(arguments, '", "')+'")');
		opts = opts || {};

		var glowInstance,
			debug = (opts.debug)? '.debug' : '',
			base = opts.base || defaultBase;

		glowMap = {
			versions: ['2.0.0', '@'+'SRC@'],
			'2.0.0': {
				'core':    ['core'+debug+'.js'],
				'widgets': ['core', 'widgets'+debug+'.js', 'widgets'+debug+'.css']
			}
		};

		if (opts._map) { glowMap = opts._map; } // for testing purposes map can be overridden

		version = getVersion(version); /*debug*///log.info('Version is "'+version+'"');

		if (Glow._build.instances[version]) { /*debug*///log.info('instance for "'+version+'" already exists.');
			return Glow._build.instances[version];
		}

		// opts.base should be formatted like a directory
		if (base.slice(-1) !== '/') {
			base += '/';
		}

		glowInstance = createGlowInstance(version, base);
		Glow._build.instances[version] = glowInstance;

		glowInstance.UID = 'glow' + Math.floor(Math.random() * (1<<30));

 		glowInstance.load('core'); // core is always loaded;

		return glowInstance;
	}

	/**
		@private
		@name getVersion
		@function
		@param {string} version A (possibly imprecise) version identifier, like "2".
		@description Find the most recent, available version of glow that matches.
	 */
	var getVersion = function(version) { /*debug*///log.info('getVersion("'+version+'")');
		var versions = glowMap.versions,
			matchThis = version + '.';

		// TODO: an empty version means: the very latest version

		var i = versions.length;
		while (i--) {
			if ( ( versions[i] + '.').indexOf(matchThis) === 0 ) {
				return versions[i];
			}
		}

		throw new Error('Version "'+version+'" does not exist');
	}

	/**
		@private
		@name getMap
		@function
		@description Find the file map for a given version.
		@param {string} version Resolved identifier, like '2.0.0'.
		@returns {object} A map of package names to files list.
	 */
	var getMap = function(version, debug) { /*debug*///log.info('getMap("'+version+'")');
		var versions = glowMap.versions,
			map = null,
			versionFound = false;

		var i = versions.length;
		while (--i > -1) {
			if (glowMap[versions[i]]) { map = glowMap[versions[i]]; }
			if (versions[i] === version) { versionFound = true; }
			if (versionFound && map) { return map; }
		}

		throw new Error('No map available for version "' + version + '".');
	}

	/**
		@private
		@name injectJs
		@function
		@description Start asynchronously loading an external JavaScript file.
	 */
	var injectJs = function(src) { /*debug*///log.info('injectJs("'+src+'")');
		var head,
			script;

		head = document.getElementsByTagName('head')[0];
		script = document.createElement('script');
		script.src = src;
		script.type = 'text/javascript';

		head.insertBefore(script, head.firstChild); // rather than appendChild() to avoid IE bug when injecting SCRIPTs after BASE tag opens. see: http://shauninman.com/archive/2007/04/13/operation_aborted
	}

	/**
		@private
		@name injectCss
		@function
		@description Start asynchronously loading an external CSS file.
	 */
	var injectCss = function(src) { /*debug*///log.info('injectCss("'+src+'")');
		var head,
			link;

		head = document.getElementsByTagName('head')[0];
		link = document.createElement('link');
		link.href = src;
		link.type = 'text/css';
		link.rel = 'stylesheet';

		head.insertBefore(link, head.firstChild);
	}

	/** @private */
	Glow._build = {
		provided: [], // provided but not yet complete
		instances: {} // built
	}

	/**
		@private
		@name Glow.provide
		@function
		@param {function} builder A function to run, given an instance of glow, and will add a feature to glow.
		@description Provide a builder function to Glow as part of a package.
	 */
	Glow.provide = function(builder) { /*debug*///log.info('Glow.provide('+typeof builder+')');
		Glow._build.provided.push(builder);
	}

	/**
		@private
		@name Glow.complete
		@function
		@param {string} name The name of the completed package.
		@param {string} version The version of the completed package.
		@description Signals that no more builder functions will be provided by this package.
	 */
	Glow.complete = function(name, version) { /*debug*///log.info('complete('+name+', '+version+')');
		var glow,
			loading,
			builders;

		// now that we have the name and version we can move the builders out of provided cache
		glow = Glow._build.instances[version];
		if (!glow) { /*debug*///log.info('Cannot complete, unknown version of glow: '+version);
			throw new Error('Cannot complete, unknown version of glow: '+version);
		}
		glow._build.builders[name] = Glow._build.provided;
		Glow._build.provided = [];

		// shortcuts
		loading   = glow._build.loading;
		builders = glow._build.builders;

		// try to build packages, in the same order they were loaded
		for (var i = 0; i < loading.length; i++) { // loading.length may change during loop
			if (!builders[loading[i]]) { /*debug*///log.info(loading[i]+' has no builders.');
				break;
			}

			// run the builders for this package in the same order they were loaded
			for (var j = 0, jlen = builders[loading[i]].length; j < jlen; j++) { /*debug*///log.info('running builder '+j+ ' for '+loading[i]+' version '+glow.version);
				builders[loading[i]][j](glow); // builder will modify glow
			}

			// remove this package from the loaded and builders list, now that it's built
			if (glow._removeReadyBlock) { glow._removeReadyBlock('glow_loading_'+loading[i]); }
			builders[loading[i]] = undefined;
			loading.splice(i, 1);
			i--;

		}

		// try to run onLoaded callbacks
		glow._release();
	}

	/**
		@name createGlowInstance
		@private
		@function
		@description Creates an instance of the Glow library.
		@param {string} version
		@param {string} base
	 */
	var createGlowInstance = function(version, base) { /*debug*///log.info('new glow("'+Array.prototype.join.call(arguments, '", "')+'")');
		var glow = function(nodeListContents) {
			return new glow.NodeList(nodeListContents);
		};

		glow.version = version;
		glow.base = base;
		glow.map = getMap(version);
		glow._build = {
			loading: [],   // names of packages requested but not yet built, in same order as requested.
			builders: {},  // completed but not yet built (waiting on dependencies). Like _build.builders[packageName]: [function, function, ...].
			history: {},   // names of every package ever loaded for this instance
			callbacks: []
		};

		// copy properties from glowInstanceMembers
		for (var prop in glowInstanceMembers) {
			glow[prop] = glowInstanceMembers[prop];
		}

		return glow;
	}

	/**
		@name glowInstanceMembers
		@private
		@description All members of this object will be copied onto little-glow instances
		@type {Object}
	*/
	var glowInstanceMembers = {
		/**
			@public
			@name glow#load
			@function
			@description Add a package to this instance of the Glow library.
			@param {string[]} ... The names of 1 or more packages to add.
		 */
		load: function() { /*debug*///log.info('glow.load("'+Array.prototype.join.call(arguments, '", "')+'") for version '+this.version);
			var name = '',
				src,
				depends;

			for (var i = 0, len = arguments.length; i < len; i++) {
				name = arguments[i];

				if (this._build.history[name]) { /*debug*///log.info('already loaded package "'+name+'" for version '+this.version+', skipping.');
					continue;
				}

				this._build.history[name] = true;

				// packages have dependencies, listed in the map: a single js file, css files, or even other packages
				depends = this.map[name]; /*debug*///log.info('depends for '+name+' '+this.version+': "'+depends.join('", "')+'"');
				for (var j = 0, lenj = depends.length; j < lenj; j++) {

					if (depends[j].slice(-3) === '.js') { /*debug*///log.info('dependent js: "'+depends[j]+'"');
						src = this.base + this.version + '/' + depends[j];

						// readyBlocks are removed in _release()
						if (this._addReadyBlock) { this._addReadyBlock('glow_loading_'+name); } // provided by core
						this._build.loading.push(name);

						injectJs(src);
					}
					else if (depends[j].slice(-4) === '.css') { /*debug*///log.info('dependent css "'+depends[j]+'"');
						src = this.base + this.version + '/' + depends[j];
						injectCss(src);
					}
					else { /*debug*///log.info('dependent package: "'+depends[j]+'"');
						this.load(depends[j]); // recursively load dependency packages
					}
				}
			}

			return this;
		},
		/**
			@public
			@name glow#loaded
			@function
			@param {function} onLoadCallback Called when all the packages load.
			@description Do something when all the packages load.
		 */
		loaded: function(onLoadCallback) { /*debug*///log.info('glow.loaded('+typeof onLoadCallback+') for version '+this.version);
			this._build.callbacks.push(onLoadCallback);
			if (this._addReadyBlock) { this._addReadyBlock('glow_loading_loadedcallback'); }

			this._release();

			return this;
		},
		/**
			@private
			@name glow#_release
			@function
			@description If all loaded packages are now built, then run the onLoaded callbacks.
		 */
		_release: function() { /*debug*///log.info('glow._release("'+this.version+'")');
			var callback;

			if (this._build.loading.length !== 0) { /*debug*///log.info('waiting for '+this._build.loading.length+' to finish.');
				return;
			}
			/*debug*///log.info('running '+this._build.callbacks.length+' loaded callbacks for version "'+this.version+'"');

			// run and remove each available _onloaded callback
			while (callback = this._build.callbacks.shift()) {
				callback(this);
				if (this._removeReadyBlock) { this._removeReadyBlock('glow_loading_loadedcallback'); }
			}
		},
		/**
			@name glow#ready
			@function
			@param {function} onReadyCallback Called when all the packages load and the DOM is available.
			@description Do something when all the packages load and the DOM is ready.
		 */
		ready: function(onReadyCallback) { /*debug*///log.info('(ember) glow#ready('+typeof onReadyCallback+') for version '+this.version+'. There are '+this._build.loading.length+' loaded packages waiting to be built.');
			this.loaded(function(glow) {
				glow.ready( function() { onReadyCallback(glow); } );
			});

			return this;
		}
	}
})();<|endoftext|>


<commit_before>/*
  Ported to JavaScript by Lazar Laszlo 2011

  lazarsoft@gmail.com, www.lazarsoft.info

*/

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

var GridSampler = {};

GridSampler.checkAndNudgePoints=function( image,  points)
		{
			var width = image.width;
			var height = image.height;
			// Check and nudge points from start until we see some that are OK:
			var nudged = true;
			for (var offset = 0; offset < points.length && nudged; offset += 2)
			{
				var x = Math.floor (points[offset]);
				var y = Math.floor( points[offset + 1]);
				if (x < - 1 || x > width || y < - 1 || y > height)
				{
					throw "Error.checkAndNudgePoints ";
				}
				nudged = false;
				if (x == - 1)
				{
					points[offset] = 0.0;
					nudged = true;
				}
				else if (x == width)
				{
					points[offset] = width - 1;
					nudged = true;
				}
				if (y == - 1)
				{
					points[offset + 1] = 0.0;
					nudged = true;
				}
				else if (y == height)
				{
					points[offset + 1] = height - 1;
					nudged = true;
				}
			}
			// Check and nudge points from end:
			nudged = true;
			for (var offset = points.length - 2; offset >= 0 && nudged; offset -= 2)
			{
				var x = Math.floor( points[offset]);
				var y = Math.floor( points[offset + 1]);
				if (x < - 1 || x > width || y < - 1 || y > height)
				{
					throw "Error.checkAndNudgePoints ";
				}
				nudged = false;
				if (x == - 1)
				{
					points[offset] = 0.0;
					nudged = true;
				}
				else if (x == width)
				{
					points[offset] = width - 1;
					nudged = true;
				}
				if (y == - 1)
				{
					points[offset + 1] = 0.0;
					nudged = true;
				}
				else if (y == height)
				{
					points[offset + 1] = height - 1;
					nudged = true;
				}
			}
		}

GridSampler.sampleGrid3=function( image,  dimension,  transform)
		{
			var bits = new BitMatrix(dimension);
			var points = new Array(dimension << 1);
			for (var y = 0; y < dimension; y++)
			{
				var max = points.length;
				var iValue =  y + 0.5;
				for (var x = 0; x < max; x += 2)
				{
					points[x] =  (x >> 1) + 0.5;
					points[x + 1] = iValue;
				}
				transform.transformPoints1(points);
				// Quick check to see if points transformed to something inside the image;
				// sufficient to check the endpoints
				GridSampler.checkAndNudgePoints(image, points);
				try
				{
					for (var x = 0; x < max; x += 2)
					{
						var xpoint = (Math.floor( points[x]) * 4) + (Math.floor( points[x + 1]) * image.width * 4);
						var bit = image.data[Math.floor( points[x])+ image.width* Math.floor( points[x + 1])];
						//bits[x >> 1][ y]=bit;
						if(bit)
							bits.set_Renamed(x >> 1, y);
					}
				}
				catch ( aioobe)
				{
					// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
					// transform gets "twisted" such that it maps a straight line of points to a set of points
					// whose endpoints are in bounds, but others are not. There is probably some mathematical
					// way to detect this about the transformation that I don't know yet.
					// This results in an ugly runtime exception despite our clever checks above -- can't have
					// that. We could check each point's coordinates but that feels duplicative. We settle for
					// catching and wrapping ArrayIndexOutOfBoundsException.
					throw "Error.checkAndNudgePoints";
				}
			}
			return bits;
		}
<commit_msg>grid: Remove unused variable<commit_after>/*
  Ported to JavaScript by Lazar Laszlo 2011

  lazarsoft@gmail.com, www.lazarsoft.info

*/

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

var GridSampler = {};

GridSampler.checkAndNudgePoints=function( image,  points)
		{
			var width = image.width;
			var height = image.height;
			// Check and nudge points from start until we see some that are OK:
			var nudged = true;
			for (var offset = 0; offset < points.length && nudged; offset += 2)
			{
				var x = Math.floor (points[offset]);
				var y = Math.floor( points[offset + 1]);
				if (x < - 1 || x > width || y < - 1 || y > height)
				{
					throw "Error.checkAndNudgePoints ";
				}
				nudged = false;
				if (x == - 1)
				{
					points[offset] = 0.0;
					nudged = true;
				}
				else if (x == width)
				{
					points[offset] = width - 1;
					nudged = true;
				}
				if (y == - 1)
				{
					points[offset + 1] = 0.0;
					nudged = true;
				}
				else if (y == height)
				{
					points[offset + 1] = height - 1;
					nudged = true;
				}
			}
			// Check and nudge points from end:
			nudged = true;
			for (var offset = points.length - 2; offset >= 0 && nudged; offset -= 2)
			{
				var x = Math.floor( points[offset]);
				var y = Math.floor( points[offset + 1]);
				if (x < - 1 || x > width || y < - 1 || y > height)
				{
					throw "Error.checkAndNudgePoints ";
				}
				nudged = false;
				if (x == - 1)
				{
					points[offset] = 0.0;
					nudged = true;
				}
				else if (x == width)
				{
					points[offset] = width - 1;
					nudged = true;
				}
				if (y == - 1)
				{
					points[offset + 1] = 0.0;
					nudged = true;
				}
				else if (y == height)
				{
					points[offset + 1] = height - 1;
					nudged = true;
				}
			}
		}

GridSampler.sampleGrid3=function( image,  dimension,  transform)
		{
			var bits = new BitMatrix(dimension);
			var points = new Array(dimension << 1);
			for (var y = 0; y < dimension; y++)
			{
				var max = points.length;
				var iValue =  y + 0.5;
				for (var x = 0; x < max; x += 2)
				{
					points[x] =  (x >> 1) + 0.5;
					points[x + 1] = iValue;
				}
				transform.transformPoints1(points);
				// Quick check to see if points transformed to something inside the image;
				// sufficient to check the endpoints
				GridSampler.checkAndNudgePoints(image, points);
				try
				{
					for (var x = 0; x < max; x += 2)
					{
						var bit = image.data[Math.floor( points[x])+ image.width* Math.floor( points[x + 1])];
						//bits[x >> 1][ y]=bit;
						if(bit)
							bits.set_Renamed(x >> 1, y);
					}
				}
				catch ( aioobe)
				{
					// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
					// transform gets "twisted" such that it maps a straight line of points to a set of points
					// whose endpoints are in bounds, but others are not. There is probably some mathematical
					// way to detect this about the transformation that I don't know yet.
					// This results in an ugly runtime exception despite our clever checks above -- can't have
					// that. We could check each point's coordinates but that feels duplicative. We settle for
					// catching and wrapping ArrayIndexOutOfBoundsException.
					throw "Error.checkAndNudgePoints";
				}
			}
			return bits;
		}
<|endoftext|>


<commit_before>(function ( window ) {
    'use strict';
    var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.oIndexedDB || window.msIndexedDB,
        IDBDatabase = window.IDBDatabase || window.webkitIDBDatabase,
        IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange,
        transactionModes = {
            readonly: 'readonly',
            readwrite: 'readwrite'
        };

    var hasOwn = Object.prototype.hasOwnProperty;

    var oldApi = !!IDBDatabase.prototype.setVersion;

    if ( !indexedDB ) {
        throw 'IndexedDB required';
    }

    var CallbackList = function () {
        var state,
            list = [];

        var exec = function ( context , args ) {
            if ( list ) {
                args = args || [];
                state = state || [ context , args ];

                for ( var i = 0 , il = list.length ; i < il ; i++ ) {
                    list[ i ].apply( state[ 0 ] , state[ 1 ] );
                }

                list = [];
            }
        };

        this.add = function () {
            for ( var i = 0 , il = arguments.length ; i < il ; i ++ ) {
                list.push( arguments[ i ] );
            }

            if ( state ) {
                exec();
            }

            return this;
        };

        this.execute = function () {
            exec( this , arguments );
            return this;
        };
    };

    var Promise = function () {
        var doneList = new CallbackList(),
            failedList = new CallbackList(),
            progressList = new CallbackList(),
            state = 'progress';

        this.done = doneList.add;
        this.fail = failedList.add;
        this.progress = progressList.add;
        this.resolve = doneList.execute;
        this.reject = failedList.execute;
        this.notify = progressList.execute;

        this.then = function ( doneHandler , failedHandler , progressHandler ) {
            return this.done( doneHandler ).fail( failedHandler ).progress( progressHandler );
        };

        this.done( function () {
            state = 'resolved';
        }).fail( function () {
            state = 'rejected';
        });
    };

    var Server = function ( db , name ) {
        var that = this,
            closed = false;

        this.add = function( table , records ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            if ( records.constructor !== Array ) {
                records = [ records ];
            }

            records.forEach( function ( record ) {
                var req = store.add( record );
                req.onsuccess = function ( e ) {
                    var target = e.target;
                    record[ target.source.keyPath ] = target.result;
                    promise.notify();
                };
            } );

            transaction.oncomplete = function () {
                promise.resolve( records , that );
            };
            transaction.onerror = function ( e ) {
                promise.reject( records , e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( records , e );
            };
            return promise;
        };

        this.remove = function ( table , key ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            var req = store.delete( key );
            req.onsuccess = function ( e ) {
                promise.resolve( key );
            };
            req.onerror = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.query = function ( table ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            return new Query( table , db );
        };

        this.close = function ( ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            db.close();
            closed = true;
            delete dbCache[ name ];
        };

        this.get = function ( table , id ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            var req = store.get( id );
            req.onsuccess = function ( e ) {
                promise.resolve( e.target.result );
            };
            req.onerror = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.index = function ( table , index ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            return new IndexQuery( table , index , db );
        };

        for ( var i = 0 , il = db.objectStoreNames.length ; i < il ; i++ ) {
            (function ( storeName ) {
                that[ storeName ] = { };
                for ( var i in that ) {
                    if ( !hasOwn.call( that , i ) || i === 'close' ) {
                        continue;
                    }
                    that[ storeName ][ i ] = (function ( i ) {
                        return function () {
                            var args = [ storeName ].concat( [].slice.call( arguments , 0 ) );
                            return that[ i ].apply( that , args );
                        };
                    })( i );
                }
            })( db.objectStoreNames[ i ] );
        }
    };

    var IndexQuery = function ( table , indexName , db ) {
        var runQuery = function ( type, args ) {
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                index = store.index( indexName ),
                keyRange = IDBKeyRange[type].apply( null, args ),
                results = [],
                promise = new Promise();

            index.openCursor( keyRange ).onsuccess = function ( e ) {
                var cursor = e.target.result;

                if ( cursor ) {
                    results.push( cursor.value );
                    cursor.continue();
                }
            };

            transaction.oncomplete = function () {
                promise.resolve( results );
            };
            transaction.onerror = function ( e ) {
                promise.reject( e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.only = function () {
            return runQuery( 'only', arguments );
        };

        this.bound = function () {
            return runQuery( 'bound', arguments );
        };

        this.upperBound = function () {
            return runQuery( 'upperBound', arguments );
        };

        this.lowerBound = function () {
            return runQuery( 'lowerBound', arguments );
        };
    };

    var Query = function ( table , db ) {
        var that = this,
            filters = [];

        this.filter = function ( field , value ) {
            filters.push( {
                field: field,
                value: value
            });
            return that;
        };

        this.execute = function () {
            var records = [],
                transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                req = store.openCursor(),
                promise = new Promise();

            req.onsuccess = function ( e ) {
                var value, f,
                    inc = true,
                    cursor = e.target.result;

                if ( cursor ) {
                    value = cursor.value;
                    for ( var i = 0 , il = filters.length ; i < il ; i++ ) {
                        f = filters[ i ];
                        if (typeof f.field === 'function') {
                            inc = f.field(value);
                        } else if (value[f.field] !== f.value) {
                            inc = false;
                        }
                    }

                    if ( inc ) {
                        records.push( value );
                    } else {
                        if ( ~records.indexOf( value ) ) {
                            records = records.slice( 0 , records.indexOf( value ) ).concat( records.indexOf( value ) );
                        }
                    }

                    cursor.continue();
                } else {
                    promise.resolve( records );
                }
            };

            req.onerror = function ( e ) {
                promise.reject( e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( e );
            };

            return promise;
        };
    };

    var createSchema = function ( e , schema , db ) {
        if ( typeof schema === 'function' ) {
            schema = schema();
        }

        for ( var tableName in schema ) {
            var table = schema[ tableName ];
            if ( !hasOwn.call( schema , tableName ) ) {
                continue;
            }

            var store = db.createObjectStore( tableName , table.key );

            for ( var indexKey in table.indexes ) {
                var index = table.indexes[ indexKey ];
                store.createIndex( indexKey , index.key || indexKey , index.options || { unique: false } );
            }
        }
    };

    var open = function ( e , server , version , schema ) {
        var db = e.target.result;
        var s = new Server( db , server );
        var upgrade;

        var promise = new Promise();

        if ( oldApi && window.parseInt( db.version ) !== version ) {
            upgrade = db.setVersion( version );

            upgrade.onsuccess = function ( e ) {
                createSchema( e , schema , db );

                promise.resolve( s );
            };
            upgrade.onerror = function ( e ) {
                promise.reject( e );
            };

            upgrade.onblocked = function () {
                promise.reject( e );
            };
        } else {
            promise.resolve( s );
        }
        dbCache[ server ] = db;

        return promise;
    };

    var dbCache = {};

    window.db = {
        open: function ( options ) {
            var request;

            var promise = new Promise();

            if ( dbCache[ options.server ] ) {
                open( {
                    target: {
                        result: dbCache[ options.server ]
                    }
                } , options.server , options.version , options.schema )
                .done(promise.resolve)
                .fail(promise.reject)
                .progress(promise.notify);
            } else {
                request = indexedDB.open( options.server , options.version );

                request.onsuccess = function ( e ) {
                    open( e , options.server , options.version , options.schema )
                        .done(promise.resolve)
                        .fail(promise.reject)
                        .progress(promise.notify);
                };

                request.onupgradeneeded = function ( e ) {
                    createSchema( e , options.schema , e.target.result );
                };
                request.onerror = function ( e ) {
                    promise.reject( e );
                };
            }

            return promise;
        }
    };
})( window );
<commit_msg>providing the type for the cursor we're opening<commit_after>(function ( window ) {
    'use strict';
    var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.oIndexedDB || window.msIndexedDB,
        IDBDatabase = window.IDBDatabase || window.webkitIDBDatabase,
        IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange,
        transactionModes = {
            readonly: 'readonly',
            readwrite: 'readwrite'
        };

    var hasOwn = Object.prototype.hasOwnProperty;

    var oldApi = !!IDBDatabase.prototype.setVersion;

    if ( !indexedDB ) {
        throw 'IndexedDB required';
    }

    var CallbackList = function () {
        var state,
            list = [];

        var exec = function ( context , args ) {
            if ( list ) {
                args = args || [];
                state = state || [ context , args ];

                for ( var i = 0 , il = list.length ; i < il ; i++ ) {
                    list[ i ].apply( state[ 0 ] , state[ 1 ] );
                }

                list = [];
            }
        };

        this.add = function () {
            for ( var i = 0 , il = arguments.length ; i < il ; i ++ ) {
                list.push( arguments[ i ] );
            }

            if ( state ) {
                exec();
            }

            return this;
        };

        this.execute = function () {
            exec( this , arguments );
            return this;
        };
    };

    var Promise = function () {
        var doneList = new CallbackList(),
            failedList = new CallbackList(),
            progressList = new CallbackList(),
            state = 'progress';

        this.done = doneList.add;
        this.fail = failedList.add;
        this.progress = progressList.add;
        this.resolve = doneList.execute;
        this.reject = failedList.execute;
        this.notify = progressList.execute;

        this.then = function ( doneHandler , failedHandler , progressHandler ) {
            return this.done( doneHandler ).fail( failedHandler ).progress( progressHandler );
        };

        this.done( function () {
            state = 'resolved';
        }).fail( function () {
            state = 'rejected';
        });
    };

    var Server = function ( db , name ) {
        var that = this,
            closed = false;

        this.add = function( table , records ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            if ( records.constructor !== Array ) {
                records = [ records ];
            }

            records.forEach( function ( record ) {
                var req = store.add( record );
                req.onsuccess = function ( e ) {
                    var target = e.target;
                    record[ target.source.keyPath ] = target.result;
                    promise.notify();
                };
            } );

            transaction.oncomplete = function () {
                promise.resolve( records , that );
            };
            transaction.onerror = function ( e ) {
                promise.reject( records , e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( records , e );
            };
            return promise;
        };

        this.remove = function ( table , key ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table , transactionModes.readwrite ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            var req = store.delete( key );
            req.onsuccess = function ( e ) {
                promise.resolve( key );
            };
            req.onerror = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.query = function ( table ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            return new Query( table , db );
        };

        this.close = function ( ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            db.close();
            closed = true;
            delete dbCache[ name ];
        };

        this.get = function ( table , id ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                promise = new Promise();

            var req = store.get( id );
            req.onsuccess = function ( e ) {
                promise.resolve( e.target.result );
            };
            req.onerror = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.index = function ( table , index ) {
            if ( closed ) {
                throw 'Database has been closed';
            }
            return new IndexQuery( table , index , db );
        };

        for ( var i = 0 , il = db.objectStoreNames.length ; i < il ; i++ ) {
            (function ( storeName ) {
                that[ storeName ] = { };
                for ( var i in that ) {
                    if ( !hasOwn.call( that , i ) || i === 'close' ) {
                        continue;
                    }
                    that[ storeName ][ i ] = (function ( i ) {
                        return function () {
                            var args = [ storeName ].concat( [].slice.call( arguments , 0 ) );
                            return that[ i ].apply( that , args );
                        };
                    })( i );
                }
            })( db.objectStoreNames[ i ] );
        }
    };

    var IndexQuery = function ( table , indexName , db ) {
        var runQuery = function ( type, args , cursorType ) {
            var transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                index = store.index( indexName ),
                keyRange = IDBKeyRange[type].apply( null, args ),
                results = [],
                promise = new Promise();

            index[cursorType]( keyRange ).onsuccess = function ( e ) {
                var cursor = e.target.result;

                if ( cursor ) {
                    results.push( cursor.value );
                    cursor.continue();
                }
            };

            transaction.oncomplete = function () {
                promise.resolve( results );
            };
            transaction.onerror = function ( e ) {
                promise.reject( e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( e );
            };
            return promise;
        };

        this.only = function () {
            return runQuery( 'only', arguments , 'openCursor' );
        };

        this.bound = function () {
            return runQuery( 'bound', arguments , 'openCursor' );
        };

        this.upperBound = function () {
            return runQuery( 'upperBound', arguments , 'openCursor' );
        };

        this.lowerBound = function () {
            return runQuery( 'lowerBound', arguments , 'openCursor' );
        };
    };

    var Query = function ( table , db ) {
        var that = this,
            filters = [];

        this.filter = function ( field , value ) {
            filters.push( {
                field: field,
                value: value
            });
            return that;
        };

        this.execute = function () {
            var records = [],
                transaction = db.transaction( table ),
                store = transaction.objectStore( table ),
                req = store.openCursor(),
                promise = new Promise();

            req.onsuccess = function ( e ) {
                var value, f,
                    inc = true,
                    cursor = e.target.result;

                if ( cursor ) {
                    value = cursor.value;
                    for ( var i = 0 , il = filters.length ; i < il ; i++ ) {
                        f = filters[ i ];
                        if (typeof f.field === 'function') {
                            inc = f.field(value);
                        } else if (value[f.field] !== f.value) {
                            inc = false;
                        }
                    }

                    if ( inc ) {
                        records.push( value );
                    } else {
                        if ( ~records.indexOf( value ) ) {
                            records = records.slice( 0 , records.indexOf( value ) ).concat( records.indexOf( value ) );
                        }
                    }

                    cursor.continue();
                } else {
                    promise.resolve( records );
                }
            };

            req.onerror = function ( e ) {
                promise.reject( e );
            };
            transaction.onabort = function ( e ) {
                promise.reject( e );
            };

            return promise;
        };
    };

    var createSchema = function ( e , schema , db ) {
        if ( typeof schema === 'function' ) {
            schema = schema();
        }

        for ( var tableName in schema ) {
            var table = schema[ tableName ];
            if ( !hasOwn.call( schema , tableName ) ) {
                continue;
            }

            var store = db.createObjectStore( tableName , table.key );

            for ( var indexKey in table.indexes ) {
                var index = table.indexes[ indexKey ];
                store.createIndex( indexKey , index.key || indexKey , index.options || { unique: false } );
            }
        }
    };

    var open = function ( e , server , version , schema ) {
        var db = e.target.result;
        var s = new Server( db , server );
        var upgrade;

        var promise = new Promise();

        if ( oldApi && window.parseInt( db.version ) !== version ) {
            upgrade = db.setVersion( version );

            upgrade.onsuccess = function ( e ) {
                createSchema( e , schema , db );

                promise.resolve( s );
            };
            upgrade.onerror = function ( e ) {
                promise.reject( e );
            };

            upgrade.onblocked = function () {
                promise.reject( e );
            };
        } else {
            promise.resolve( s );
        }
        dbCache[ server ] = db;

        return promise;
    };

    var dbCache = {};

    window.db = {
        open: function ( options ) {
            var request;

            var promise = new Promise();

            if ( dbCache[ options.server ] ) {
                open( {
                    target: {
                        result: dbCache[ options.server ]
                    }
                } , options.server , options.version , options.schema )
                .done(promise.resolve)
                .fail(promise.reject)
                .progress(promise.notify);
            } else {
                request = indexedDB.open( options.server , options.version );

                request.onsuccess = function ( e ) {
                    open( e , options.server , options.version , options.schema )
                        .done(promise.resolve)
                        .fail(promise.reject)
                        .progress(promise.notify);
                };

                request.onupgradeneeded = function ( e ) {
                    createSchema( e , options.schema , e.target.result );
                };
                request.onerror = function ( e ) {
                    promise.reject( e );
                };
            }

            return promise;
        }
    };
})( window );
<|endoftext|>


<commit_before>var Sequelize = require('sequelize');

var sequelize = new Sequelize('jsfinance', 'root', 'stingray', {
  host: '127.0.0.1',
  port : 3306,
  dialect: 'mysql',

  pool: {
    max: 5,
    min: 0,
    idle: 10000
  },

  logging : true
});

sequelize.DataTypes = Sequelize;

module.exports = sequelize;
<commit_msg>Disable DB Logging by Default<commit_after>var Sequelize = require('sequelize');

var sequelize = new Sequelize('jsfinance', 'root', 'stingray', {
  host: '127.0.0.1',
  port : 3306,
  dialect: 'mysql',

  pool: {
    max: 5,
    min: 0,
    idle: 10000
  },

  logging : false
});

sequelize.DataTypes = Sequelize;

module.exports = sequelize;
<|endoftext|>