<commit_before>// Import the page's CSS. Webpack will know what to do with it.
import "../stylesheets/app.css";

// Import libraries we need.
import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'

// Import our contract artifacts and turn them into usable abstractions.
import alice_token_artifacts from '../../build/contracts/AliceToken.json';
import wallet_artifacts from '../../build/contracts/DonationWallet.json';
import project_with_bonds_artifacts from '../../build/contracts/ProjectWithBonds.json';
import catalog_artifacts from '../../build/contracts/ProjectCatalog.json';
import impact_registry_artifacts from '../../build/contracts/ImpactRegistry.json';
import linker_artifacts from '../../build/contracts/FlexibleImpactLinker.json';
import investor_artifacts from '../../build/contracts/InvestmentWallet.json';
import coupon_artifacts from '../../build/contracts/Coupon.json';

// MetaCoin is our usable abstraction, which we'll use through the code below.
var AliceToken = contract(alice_token_artifacts);
var Wallet = contract(wallet_artifacts);
var ProjectWithBonds = contract(project_with_bonds_artifacts);
var Catalog = contract(catalog_artifacts);
var ImpactRegistry = contract(impact_registry_artifacts);
var Linker = contract(linker_artifacts);
var Investor = contract(investor_artifacts);
var Coupon = contract(coupon_artifacts);

const PROJECT_NAME = "DEMO_PROJECT";

var accounts;
var aliceAccount;
var donor1Account;
var donor2Account;
var beneficiaryAccount;
var judgeAccount;

var TokenContract;
var CharityContract;
var ImpactContract;
var CatalogContract;
var ProjectContract;
var InvestorContract;
var CouponContract;

var balances = {};
var wallets = {};

function refreshBalance() {
  showBalance(wallets[donor1Account].address,  "balance_donor_1");
  showBalance(wallets[donor2Account].address,  "balance_donor_2");
  showBalance(InvestorContract.address,  "balance_investor");
  showBalance(ProjectContract.address, "balance_charity");
  showBalance(beneficiaryAccount, "balance_beneficiary");
  showCoupons(InvestorContract.address, "coupons");
  showLiability("liability");
}

function showBalance(account, element) {
	TokenContract.balanceOf(account).then(function(value) {
    var balance_element = document.getElementById(element);
    balance_element.innerHTML = value.valueOf();
    balances[account] = value;
  });
}

function showCoupons(account, element) {
	CouponContract.balanceOf(account).then(function(value) {
		var balance_element = document.getElementById(element);
		balance_element.innerHTML = value.valueOf();
	});
}

function showLiability(element) {
	ProjectContract.getLiability().then(function(liability) {
		ProjectContract.getValidatedLiability().then(function(validated) {
			var balance_element = document.getElementById(element);
			balance_element.innerHTML = liability.valueOf() + " LHC ( " + validated.valueOf() + " validated )";
		});
	});
}

function showAllImpacts() {
  showImpact('Tenancy');
  showImpact('Employment');
}

function showImpact(name) {
  ImpactContract.getImpactCount.call(name).then(function(c) {
    var count = c.valueOf();
    console.log(name + ' impact: ' + count);
    for(var i=0; i < count; i++) {
      (function(index) {
        ImpactContract.getImpactDonor.call(name, i).then(function (address) {
          console.log(name + ' address[' + index + ']: ' + address);
          ImpactContract.getImpactValue.call(name, address).then(function (value) {
            console.log(name + ' value[' + index + ']: ' + value);
          });
        });
      })(i);
    }
  });
}

window.deposit = function(account, value) {
  TokenContract.mint(wallets[account].address, value, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		 refreshBalance();
		});
};

window.depositToInvestor = function(value) {
	TokenContract.mint(InvestorContract.address, value, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		refreshBalance();
	});
};

window.donate = async function(account, value) {
	wallets[account].donate(value, PROJECT_NAME, {from: aliceAccount, gas: 1000000}).then(function(tx) {
	 	refreshBalance();
	});
};

window.invest = async function(value) {
	InvestorContract.invest(value, PROJECT_NAME, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		refreshBalance();
	});
};

window.redeem = async function(value) {
	InvestorContract.redeemCoupons(value, PROJECT_NAME, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		refreshBalance();
	});
};

window.donateAll = async function(account) {
	var total = await TokenContract.balanceOf(wallets[account].address);
	donate(account, total.valueOf());
};

function reuseUnspent(account) {
  TokenContract.transfer(CharityContract.address, balances[account], {from: account, gas: 1000000})
    .then(function(tx) {
      return CharityContract.notify(account, balances[account], {from: aliceAccount, gas: 1000000})
    .then(function () {
      console.log("Donated remaining funds: " + balances[account]);
      refreshBalance();
      return null;
    });
  });
}

window.validateOutcome = async function(name, value) {
  await ProjectContract.unlockOutcome(name, value, {from: judgeAccount, gas: 500000});
  refreshBalance();
  return linkImpact(name);
}

window.payBack = async function(account) {
  var tx = await ProjectContract.payBack(wallets[account].address, {from: aliceAccount, gas: 1000000});
  refreshBalance();
}

window.payBackAll = function() {
	payBack(donor1Account);
	payBack(donor2Account);
}

function linkImpact(name) {
  return ImpactContract.getImpactUnmatchedValue.call(name, {from: aliceAccount}).then(function(val) {
    console.log("Unlinked: " + val);
    if (val > 0) {
      console.log("Linking impact");
      return ImpactContract.linkImpact(name, {from: aliceAccount, gas: 2000000}).then(function(tx) {
        return linkImpact(name);
      });
    }
  });
}

function mapAccounts(accounts) {
  aliceAccount = accounts[0];
  judgeAccount = accounts[1];
  beneficiaryAccount = accounts[2];
  donor1Account = accounts[3];
  donor2Account = accounts[4];

  window.donor1Account = donor1Account;
  window.donor2Account = donor2Account;
}

function printLog(text) {
	var logBox = document.getElementById("log");
	logBox.innerHTML += text + "
";
}

function printTx(tx) {
	printLog("Transaction hash: " + tx);
}

function printContract(name, contract) {
  printLog(name + " contract deployed to: " + contract.address);
}

function setupWeb3Filter() {
  var filter = web3.eth.filter({});

  filter.watch(function (error, log) {
    //console.log(log);
    printTx(log.transactionHash);
  });
}

async function deployToken() {
	AliceToken.setProvider(web3.currentProvider);

  TokenContract = await AliceToken.new({from: aliceAccount, gas: 2000000});
  printContract("Token", TokenContract);
}

async function deployProject() {
	ProjectWithBonds.setProvider(web3.currentProvider);
	Catalog.setProvider(web3.currentProvider);
	ImpactRegistry.setProvider(web3.currentProvider);
	Linker.setProvider(web3.currentProvider);
	Coupon.setProvider(web3.currentProvider);

	ProjectContract = await ProjectWithBonds.new(PROJECT_NAME, 100, 1000, {from: aliceAccount, gas: 5000000});
	printContract("Project", ProjectContract);
	CouponContract = Coupon.at(await ProjectContract.getCoupon({from: aliceAccount}));

	await ProjectContract.setJudge(judgeAccount, {from: aliceAccount, gas: 2000000});
	await ProjectContract.setBeneficiary(beneficiaryAccount, {from: aliceAccount, gas: 2000000});
	await ProjectContract.setToken(TokenContract.address, {from: aliceAccount, gas: 2000000});

	ImpactContract = await ImpactRegistry.new(ProjectContract.address, {from: aliceAccount, gas: 2000000});
	var linker = await Linker.new(ImpactContract.address, 10, {from: aliceAccount, gas: 2000000});
	await ImpactContract.setLinker(linker.address, {from: aliceAccount, gas: 2000000});

	await ProjectContract.setImpactRegistry(ImpactContract.address, {from: aliceAccount, gas: 2000000});

	CatalogContract = await Catalog.new({from: aliceAccount, gas: 2000000});
	printContract("Catalog", CatalogContract);

	await CatalogContract.addProject(PROJECT_NAME, ProjectContract.address, {from: aliceAccount, gas: 2000000});
}

async function deployWallet(donor) {
	Wallet.setProvider(web3.currentProvider);

	wallets[donor] = await Wallet.new(CatalogContract.address, {from: aliceAccount, gas: 2000000});
	printContract("Donor wallet", wallets[donor]);
}

async function deployInvestorWallet() {
	Investor.setProvider(web3.currentProvider);

	InvestorContract = await Investor.new(CatalogContract.address, {from: aliceAccount, gas: 2000000});
	printContract("Investor wallet", InvestorContract);
}

async function deploy() {
  await deployToken();
  await deployProject();
	await deployWallet(donor1Account);
	await deployWallet(donor2Account);
	await deployInvestorWallet();
	refreshBalance();
}

window.onload = function() {
	window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

	web3.eth.getAccounts(function(err, accs) {
      if (err != null) {
        alert("There was an error fetching your accounts.");
        return;
      }

      if (accs.length == 0) {
        alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.");
        return;
      }

		  setupWeb3Filter();

      mapAccounts(accs);

      deploy();

    });

};
<commit_msg>Correctly showing total value of the project contract.<commit_after>// Import the page's CSS. Webpack will know what to do with it.
import "../stylesheets/app.css";

// Import libraries we need.
import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'

// Import our contract artifacts and turn them into usable abstractions.
import alice_token_artifacts from '../../build/contracts/AliceToken.json';
import wallet_artifacts from '../../build/contracts/DonationWallet.json';
import project_with_bonds_artifacts from '../../build/contracts/ProjectWithBonds.json';
import catalog_artifacts from '../../build/contracts/ProjectCatalog.json';
import impact_registry_artifacts from '../../build/contracts/ImpactRegistry.json';
import linker_artifacts from '../../build/contracts/FlexibleImpactLinker.json';
import investor_artifacts from '../../build/contracts/InvestmentWallet.json';
import coupon_artifacts from '../../build/contracts/Coupon.json';

// MetaCoin is our usable abstraction, which we'll use through the code below.
var AliceToken = contract(alice_token_artifacts);
var Wallet = contract(wallet_artifacts);
var ProjectWithBonds = contract(project_with_bonds_artifacts);
var Catalog = contract(catalog_artifacts);
var ImpactRegistry = contract(impact_registry_artifacts);
var Linker = contract(linker_artifacts);
var Investor = contract(investor_artifacts);
var Coupon = contract(coupon_artifacts);

const PROJECT_NAME = "DEMO_PROJECT";

var accounts;
var aliceAccount;
var donor1Account;
var donor2Account;
var beneficiaryAccount;
var judgeAccount;

var TokenContract;
var CharityContract;
var ImpactContract;
var CatalogContract;
var ProjectContract;
var InvestorContract;
var CouponContract;

var balances = {};
var wallets = {};

function refreshBalance() {
  showBalance(wallets[donor1Account].address,  "balance_donor_1");
  showBalance(wallets[donor2Account].address,  "balance_donor_2");
  showBalance(InvestorContract.address,  "balance_investor");
	showProjectTotal("balance_charity");
  showBalance(beneficiaryAccount, "balance_beneficiary");
  showCoupons(InvestorContract.address, "coupons");
  showLiability("liability");
}

function showBalance(account, element) {
	TokenContract.balanceOf(account).then(function(value) {
    var balance_element = document.getElementById(element);
    balance_element.innerHTML = value.valueOf();
    balances[account] = value;
  });
}

function showCoupons(account, element) {
	CouponContract.balanceOf(account).then(function(value) {
		var balance_element = document.getElementById(element);
		balance_element.innerHTML = value.valueOf();
	});
}

function showProjectTotal(element) {
	ProjectContract.total().then(function(total) {
		var balance_element = document.getElementById(element);
			balance_element.innerHTML = total.valueOf()
	});
}

function showLiability(element) {
	ProjectContract.getLiability().then(function(liability) {
		ProjectContract.getValidatedLiability().then(function(validated) {
			var balance_element = document.getElementById(element);
			balance_element.innerHTML = liability.valueOf() + " LHC ( " + validated.valueOf() + " validated )";
		});
	});
}

function showAllImpacts() {
  showImpact('Tenancy');
  showImpact('Employment');
}

function showImpact(name) {
  ImpactContract.getImpactCount.call(name).then(function(c) {
    var count = c.valueOf();
    console.log(name + ' impact: ' + count);
    for(var i=0; i < count; i++) {
      (function(index) {
        ImpactContract.getImpactDonor.call(name, i).then(function (address) {
          console.log(name + ' address[' + index + ']: ' + address);
          ImpactContract.getImpactValue.call(name, address).then(function (value) {
            console.log(name + ' value[' + index + ']: ' + value);
          });
        });
      })(i);
    }
  });
}

window.deposit = function(account, value) {
  TokenContract.mint(wallets[account].address, value, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		 refreshBalance();
		});
};

window.depositToInvestor = function(value) {
	TokenContract.mint(InvestorContract.address, value, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		refreshBalance();
	});
};

window.donate = async function(account, value) {
	wallets[account].donate(value, PROJECT_NAME, {from: aliceAccount, gas: 1000000}).then(function(tx) {
	 	refreshBalance();
	});
};

window.invest = async function(value) {
	InvestorContract.invest(value, PROJECT_NAME, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		refreshBalance();
	});
};

window.redeem = async function(value) {
	InvestorContract.redeemCoupons(value, PROJECT_NAME, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		refreshBalance();
	});
};

window.donateAll = async function(account) {
	var total = await TokenContract.balanceOf(wallets[account].address);
	donate(account, total.valueOf());
};

function reuseUnspent(account) {
  TokenContract.transfer(CharityContract.address, balances[account], {from: account, gas: 1000000})
    .then(function(tx) {
      return CharityContract.notify(account, balances[account], {from: aliceAccount, gas: 1000000})
    .then(function () {
      console.log("Donated remaining funds: " + balances[account]);
      refreshBalance();
      return null;
    });
  });
}

window.validateOutcome = async function(name, value) {
  await ProjectContract.unlockOutcome(name, value, {from: judgeAccount, gas: 500000});
  refreshBalance();
  return linkImpact(name);
}

window.payBack = async function(account) {
  var tx = await ProjectContract.payBack(wallets[account].address, {from: aliceAccount, gas: 1000000});
  refreshBalance();
}

window.payBackAll = function() {
	payBack(donor1Account);
	payBack(donor2Account);
}

function linkImpact(name) {
  return ImpactContract.getImpactUnmatchedValue.call(name, {from: aliceAccount}).then(function(val) {
    console.log("Unlinked: " + val);
    if (val > 0) {
      console.log("Linking impact");
      return ImpactContract.linkImpact(name, {from: aliceAccount, gas: 2000000}).then(function(tx) {
        return linkImpact(name);
      });
    }
  });
}

function mapAccounts(accounts) {
  aliceAccount = accounts[0];
  judgeAccount = accounts[1];
  beneficiaryAccount = accounts[2];
  donor1Account = accounts[3];
  donor2Account = accounts[4];

  window.donor1Account = donor1Account;
  window.donor2Account = donor2Account;
}

function printLog(text) {
	var logBox = document.getElementById("log");
	logBox.innerHTML += text + "
";
}

function printTx(tx) {
	printLog("Transaction hash: " + tx);
}

function printContract(name, contract) {
  printLog(name + " contract deployed to: " + contract.address);
}

function setupWeb3Filter() {
  var filter = web3.eth.filter({});

  filter.watch(function (error, log) {
    //console.log(log);
    printTx(log.transactionHash);
  });
}

async function deployToken() {
	AliceToken.setProvider(web3.currentProvider);

  TokenContract = await AliceToken.new({from: aliceAccount, gas: 2000000});
  printContract("Token", TokenContract);
}

async function deployProject() {
	ProjectWithBonds.setProvider(web3.currentProvider);
	Catalog.setProvider(web3.currentProvider);
	ImpactRegistry.setProvider(web3.currentProvider);
	Linker.setProvider(web3.currentProvider);
	Coupon.setProvider(web3.currentProvider);

	ProjectContract = await ProjectWithBonds.new(PROJECT_NAME, 100, 1000, {from: aliceAccount, gas: 5000000});
	printContract("Project", ProjectContract);
	CouponContract = Coupon.at(await ProjectContract.getCoupon({from: aliceAccount}));

	await ProjectContract.setJudge(judgeAccount, {from: aliceAccount, gas: 2000000});
	await ProjectContract.setBeneficiary(beneficiaryAccount, {from: aliceAccount, gas: 2000000});
	await ProjectContract.setToken(TokenContract.address, {from: aliceAccount, gas: 2000000});

	ImpactContract = await ImpactRegistry.new(ProjectContract.address, {from: aliceAccount, gas: 2000000});
	var linker = await Linker.new(ImpactContract.address, 10, {from: aliceAccount, gas: 2000000});
	await ImpactContract.setLinker(linker.address, {from: aliceAccount, gas: 2000000});

	await ProjectContract.setImpactRegistry(ImpactContract.address, {from: aliceAccount, gas: 2000000});

	CatalogContract = await Catalog.new({from: aliceAccount, gas: 2000000});
	printContract("Catalog", CatalogContract);

	await CatalogContract.addProject(PROJECT_NAME, ProjectContract.address, {from: aliceAccount, gas: 2000000});
}

async function deployWallet(donor) {
	Wallet.setProvider(web3.currentProvider);

	wallets[donor] = await Wallet.new(CatalogContract.address, {from: aliceAccount, gas: 2000000});
	printContract("Donor wallet", wallets[donor]);
}

async function deployInvestorWallet() {
	Investor.setProvider(web3.currentProvider);

	InvestorContract = await Investor.new(CatalogContract.address, {from: aliceAccount, gas: 2000000});
	printContract("Investor wallet", InvestorContract);
}

async function deploy() {
  await deployToken();
  await deployProject();
	await deployWallet(donor1Account);
	await deployWallet(donor2Account);
	await deployInvestorWallet();
	refreshBalance();
}

window.onload = function() {
	window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

	web3.eth.getAccounts(function(err, accs) {
      if (err != null) {
        alert("There was an error fetching your accounts.");
        return;
      }

      if (accs.length == 0) {
        alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.");
        return;
      }

		  setupWeb3Filter();

      mapAccounts(accs);

      deploy();

    });

};
<|endoftext|>


<commit_before>var module = angular.module('scrollableCalendarModule', []);

module.controller('scrollableCalendarController', function($scope) {
    var scrollbarOffset = 20;
    $scope.setup = function(baseDate) {
        var day = moment(baseDate).utc();
        day.startOf('month');  // first day of the month
        day.startOf('week');   // first day of the week (the row)
        return day;
    }
    $scope.computeDimentions = function(element) {
        var parentWidth = jQuery(element).innerWidth() - scrollbarOffset;
        var width = Math.floor(parentWidth / 7);
        $scope.unitWidth = width;
    }
    $scope.dump = function() {
        console.log("A:" + $scope.rangeA + " B:" + $scope.rangeB);
    }
    $scope.selectRange = function(isSelecting) {
        var startDay = moment($scope.rangeA).utc();
        var endDay = moment($scope.rangeB).utc();
        var numDays = endDay.diff(startDay, 'days');
        $scope.dateFlipped = false;
        if (numDays < 0) {
            // flip
            var tmpDay = startDay;
            startDay = endDay;
            endDay = tmpDay;
            numDays = -1 * numDays;
            $scope.dateFlipped = true;
        }
        // Update model if isSelecting == true
        if (isSelecting) {
            $scope.startDate = startDay.format('YYYY-MM-DD');
            $scope.endDate = endDay.format('YYYY-MM-DD');
        }
        for (var i = 0; i <= numDays; ++i) {
            var id = startDay.format('YYYY-MM-DD');
            var div = $scope.body.find("#" + id);
            if (isSelecting) {
                div.css({'background-color': '#ddd'});
            } else {
                div.css({'background-color': ''});
            }
            startDay.add('days', 1);
        }
    }
    $scope.updateRange = function(rangeA, rangeB) {
        // Unselect previous selection
        $scope.selectRange(false);
        // Make a new selection
        $scope.rangeA = rangeA;
        $scope.rangeB = rangeB;
        $scope.selectRange(true);
    }
    $scope.generateRow = function(param) {
        var day = param.clone();
        var html = jQuery('

');
        html.css({'width': $scope.unitWidth * 7 + "px"});

        for (var i = 0; i < 7; ++i) {
            var dayDiv = jQuery('

');
            // dayDiv.text(day.utc().format('MMM D'));
            dayDiv.css({'width': $scope.unitWidth + "px"});
            dayDiv.css({'height': $scope.unitWidth + "px"});
            dayDiv.attr('id', day.utc().format('YYYY-MM-DD'));

            var dayMonth = jQuery('

');
            dayMonth.css({'height':  $scope.unitWidth / 3 + "px"});
            if (day.date() == 1) {
                dayMonth.text(day.utc().format('MMM'))
            }
            var dayNumber = jQuery('

');
            dayNumber.css({'height': 2 * $scope.unitWidth / 3 + "px"});
            dayNumber.css({'line-height': 2 * $scope.unitWidth / 3 + "px"});

            dayNumber.text(day.utc().format('D'))

            dayDiv.append(dayMonth);
            dayDiv.append(dayNumber);

            /*
            dayDiv.bind('mousedown', function(event_info) {
                // Select the day
                $scope.updateRange(event_info.currentTarget.id, event_info.currentTarget.id);
                $scope.selecting = true;
                $scope.$apply();
            });
            dayDiv.bind('mousemove', function(event_info) {
                var leftButtonPressed = false;
                if (event_info.buttons != undefined) {
                    // Firefox returns event_info.which == 1 even if no mouse keys are pressed.
                    // event_info.buttons is available on Firefox but not on Chrome.
                    if (event_info.buttons == 1) {
                        leftButtonPressed = true;
                    }
                } else {
                    if (event_info.which == 1) {
                        leftButtonPressed = true;
                    }
                }

                if (leftButtonPressed) {
                    if ($scope.rangeB != event_info.currentTarget.id) {
                        $scope.updateRange($scope.rangeA, event_info.currentTarget.id);
                        $scope.$apply();
                    }
                }
            });
            */
            $scope.firstClick = true;
            dayDiv.bind('mouseup', function(event_info) {
                if ($scope.firstClick) {
                    $scope.updateRange(event_info.currentTarget.id, event_info.currentTarget.id);
                    $scope.firstClick = false;
                } else {
                    $scope.updateRange($scope.rangeA, event_info.currentTarget.id);
                    $scope.firstClick = true;
                }
                $scope.selecting = false;
                $scope.$apply();
                if ($scope.callback) {
                    $scope.callback($scope.startDate, $scope.endDate);
                }
            });

            html.append(dayDiv);
            day.add('days', 1);
        }
        return html;
    }
    $scope.setupHeading = function() {
        var height = $scope.unitWidth * 1.5;
        var width = $scope.unitWidth * 7
        $scope.head.css({'height':height, 'width': width});
        $scope.headYear = jQuery('

');
        $scope.headYear.css({'height':$scope.unitWidth, 'width': width});

        $scope.headDayOfWeek = jQuery('

');
        $scope.headDayOfWeek.css({'height':$scope.unitWidth*0.5});

        var day = moment().utc().startOf('week');
        for (var i = 0; i < 7; ++i) {
            var dayDiv = jQuery('

');
            dayDiv.text(day.utc().format('ddd'));
            dayDiv.css({'width': $scope.unitWidth + "px"});
            $scope.headDayOfWeek.append(dayDiv);
            day.add('days', 1);
        }
        $scope.head.append($scope.headYear);
        $scope.head.append($scope.headDayOfWeek);
    }
    $scope.setupBody = function(parentElement) {
        var height = parentElement.innerHeight() - $scope.head.innerHeight();
        var width = parentElement.innerWidth();
        $scope.body.css({'height': height, 'width': width});

    }
    $scope.refreshHeading = function() {
        var top = $scope.body.scrollTop();
        var height = $scope.body[0].scrollHeight;
        var visibleHeight = $scope.body.innerHeight();
        var bottom = top + visibleHeight;

        var centerDay = $scope.beginDay.clone();
        centerDay.add('days', Math.floor((top + visibleHeight/2) / $scope.unitWidth) * 7);

        $scope.headYear.text(centerDay.format('YYYY MMMM'));
    }
    // Angular -> UI
    $scope.setDatesFromModel = function() {
        if (($scope.startDate == undefined) || ($scope.endDate == undefined)) {
            return;
        }
        // this is required as update happens during dragging as well.
        if (!$scope.dateFlipped) {
            $scope.updateRange($scope.startDate, $scope.endDate);
        } else {
            $scope.updateRange($scope.endDate, $scope.startDate);
        }
    }
    $scope.$watch('startDate', $scope.setDatesFromModel);
    $scope.$watch('endDate', $scope.setDatesFromModel);
});

module.directive('scrollableCalendar', function() {
   return {
       restrict: 'A',
       controller: 'scrollableCalendarController',
       scope: {
         'startDate': '=',
         'endDate': '=',
         'baseDate': '=',
         'callback': '='
       },
       template: '

',
       link: function($scope, $element, $attrs) {
           $scope.computeDimentions($element);
           $scope.body = jQuery($element).find(".cal-body");
           $scope.head = jQuery($element).find(".cal-head");
           $scope.dateFlipped = false;

           $scope.setupHeading();
           $scope.setupBody($element);

           $scope.addInitialCalendarDays = function() {
               // Run it only once
               if ($scope.initialized) {
                   return;
               }
               $scope.initialized = true;
               var day = $scope.setup($scope.baseDate);

               // going back 300px
               var hiddenNumRows = Math.floor(300 / $scope.unitWidth);
               day.subtract('days', 7 * hiddenNumRows);
               $scope.beginDay = day.clone();
               for (var i = 0; i < 50; ++i) {
                   var rowElement = $scope.generateRow(day);
                   $scope.body.append(rowElement);
                   day.add('days', 7);
               }
               var endDay = day.clone();
               $scope.body.scrollTop(hiddenNumRows * $scope.unitWidth);
               $scope.refreshHeading();
               $scope.setDatesFromModel();
           }

           $scope.body.bind('scroll', function(event_info) {
               var top = $scope.body.scrollTop();
               var height = $scope.body[0].scrollHeight;
               var visibleHeight = $scope.body.innerHeight();
               var bottom = top + visibleHeight;
               if (top < 100) {
                   // create rows
                   var hiddenNumRows = Math.floor(300 / $scope.unitWidth);
                   for (var i = 0; i < hiddenNumRows; ++i) {
                       $scope.beginDay.subtract('days', 7);
                       var rowElement = $scope.generateRow($scope.beginDay);
                       $scope.body.prepend(rowElement);
                   }
                   jQuery($scope.body).scrollTop(top + hiddenNumRows * $scope.unitWidth);
               } else if ((height - bottom) < 100) {
                   // create rows at the bottom
                   var hiddenNumRows = Math.floor(300 / $scope.unitWidth);
                   for (var i = 0; i < hiddenNumRows; ++i) {
                       var rowElement = $scope.generateRow($scope.endDate);
                       $scope.body.append(rowElement);
                       $scope.endDate.add('days', 7);
                   }
               }
               $scope.refreshHeading();
           });

           $scope.$watch('baseDate', function() {
               if ($scope.baseDate != undefined) {
                   $scope.addInitialCalendarDays();
               }
           })
       }
    };
});<commit_msg>Fixed a bug that depends on timezone, Angular ended up with nested digest/apply loop.<commit_after>var module = angular.module('scrollableCalendarModule', []);

module.controller('scrollableCalendarController', function($scope) {
    var scrollbarOffset = 20;
    $scope.setup = function(baseDate) {
        var day = moment.utc(baseDate);
        day.startOf('month');  // first day of the month
        day.startOf('week');   // first day of the week (the row)
        return day;
    }
    $scope.computeDimentions = function(element) {
        var parentWidth = jQuery(element).innerWidth() - scrollbarOffset;
        var width = Math.floor(parentWidth / 7);
        $scope.unitWidth = width;
    }
    $scope.dump = function() {
        console.log("A:" + $scope.rangeA + " B:" + $scope.rangeB);
    }
    $scope.selectRange = function(isSelecting) {
        var startDay = moment.utc($scope.rangeA);
        var endDay = moment.utc($scope.rangeB);
        var numDays = endDay.diff(startDay, 'days');
        $scope.dateFlipped = false;
        if (numDays < 0) {
            // flip
            var tmpDay = startDay;
            startDay = endDay;
            endDay = tmpDay;
            numDays = -1 * numDays;
            $scope.dateFlipped = true;
        }
        // Update model if isSelecting == true
        if (isSelecting) {
            $scope.startDate = startDay.format('YYYY-MM-DD');
            $scope.endDate = endDay.format('YYYY-MM-DD');
        }
        for (var i = 0; i <= numDays; ++i) {
            var id = startDay.format('YYYY-MM-DD');
            var div = $scope.body.find("#" + id);
            if (isSelecting) {
                div.css({'background-color': '#ddd'});
            } else {
                div.css({'background-color': ''});
            }
            startDay.add('days', 1);
        }
    }
    $scope.updateRange = function(rangeA, rangeB) {
        // Unselect previous selection
        $scope.selectRange(false);
        // Make a new selection
        $scope.rangeA = rangeA;
        $scope.rangeB = rangeB;
        $scope.selectRange(true);
    }
    $scope.generateRow = function(param) {
        var day = param.clone();
        var html = jQuery('

');
        html.css({'width': $scope.unitWidth * 7 + "px"});

        for (var i = 0; i < 7; ++i) {
            var dayDiv = jQuery('

');
            // dayDiv.text(day.utc().format('MMM D'));
            dayDiv.css({'width': $scope.unitWidth + "px"});
            dayDiv.css({'height': $scope.unitWidth + "px"});
            dayDiv.attr('id', day.utc().format('YYYY-MM-DD'));

            var dayMonth = jQuery('

');
            dayMonth.css({'height':  $scope.unitWidth / 3 + "px"});
            if (day.date() == 1) {
                dayMonth.text(day.utc().format('MMM'))
            }
            var dayNumber = jQuery('

');
            dayNumber.css({'height': 2 * $scope.unitWidth / 3 + "px"});
            dayNumber.css({'line-height': 2 * $scope.unitWidth / 3 + "px"});

            dayNumber.text(day.utc().format('D'))

            dayDiv.append(dayMonth);
            dayDiv.append(dayNumber);

            /*
            dayDiv.bind('mousedown', function(event_info) {
                // Select the day
                $scope.updateRange(event_info.currentTarget.id, event_info.currentTarget.id);
                $scope.selecting = true;
                $scope.$apply();
            });
            dayDiv.bind('mousemove', function(event_info) {
                var leftButtonPressed = false;
                if (event_info.buttons != undefined) {
                    // Firefox returns event_info.which == 1 even if no mouse keys are pressed.
                    // event_info.buttons is available on Firefox but not on Chrome.
                    if (event_info.buttons == 1) {
                        leftButtonPressed = true;
                    }
                } else {
                    if (event_info.which == 1) {
                        leftButtonPressed = true;
                    }
                }

                if (leftButtonPressed) {
                    if ($scope.rangeB != event_info.currentTarget.id) {
                        $scope.updateRange($scope.rangeA, event_info.currentTarget.id);
                        $scope.$apply();
                    }
                }
            });
            */
            $scope.firstClick = true;
            dayDiv.bind('mouseup', function(event_info) {
                if ($scope.firstClick) {
                    $scope.updateRange(event_info.currentTarget.id, event_info.currentTarget.id);
                    $scope.firstClick = false;
                } else {
                    $scope.updateRange($scope.rangeA, event_info.currentTarget.id);
                    $scope.firstClick = true;
                }
                $scope.selecting = false;
                $scope.$apply();
                if ($scope.callback) {
                    $scope.callback($scope.startDate, $scope.endDate);
                }
            });

            html.append(dayDiv);
            day.add('days', 1);
        }
        return html;
    }
    $scope.setupHeading = function() {
        var height = $scope.unitWidth * 1.5;
        var width = $scope.unitWidth * 7
        $scope.head.css({'height':height, 'width': width});
        $scope.headYear = jQuery('

');
        $scope.headYear.css({'height':$scope.unitWidth, 'width': width});

        $scope.headDayOfWeek = jQuery('

');
        $scope.headDayOfWeek.css({'height':$scope.unitWidth*0.5});

        var day = moment.utc().startOf('week');
        for (var i = 0; i < 7; ++i) {
            var dayDiv = jQuery('

');
            dayDiv.text(day.utc().format('ddd'));
            dayDiv.css({'width': $scope.unitWidth + "px"});
            $scope.headDayOfWeek.append(dayDiv);
            day.add('days', 1);
        }
        $scope.head.append($scope.headYear);
        $scope.head.append($scope.headDayOfWeek);
    }
    $scope.setupBody = function(parentElement) {
        var height = parentElement.innerHeight() - $scope.head.innerHeight();
        var width = parentElement.innerWidth();
        $scope.body.css({'height': height, 'width': width});

    }
    $scope.refreshHeading = function() {
        var top = $scope.body.scrollTop();
        var height = $scope.body[0].scrollHeight;
        var visibleHeight = $scope.body.innerHeight();
        var bottom = top + visibleHeight;

        var centerDay = $scope.beginDay.clone();
        centerDay.add('days', Math.floor((top + visibleHeight/2) / $scope.unitWidth) * 7);

        $scope.headYear.text(centerDay.format('YYYY MMMM'));
    }
    // Angular -> UI
    $scope.setDatesFromModel = function() {
        if (($scope.startDate == undefined) || ($scope.endDate == undefined)) {
            return;
        }
        // this is required as update happens during dragging as well.
        if (!$scope.dateFlipped) {
            $scope.updateRange($scope.startDate, $scope.endDate);
        } else {
            $scope.updateRange($scope.endDate, $scope.startDate);
        }
    }
    $scope.$watch('startDate', $scope.setDatesFromModel);
    $scope.$watch('endDate', $scope.setDatesFromModel);
});

module.directive('scrollableCalendar', function() {
   return {
       restrict: 'A',
       controller: 'scrollableCalendarController',
       scope: {
         'startDate': '=',
         'endDate': '=',
         'baseDate': '=',
         'callback': '='
       },
       template: '

',
       link: function($scope, $element, $attrs) {
           $scope.computeDimentions($element);
           $scope.body = jQuery($element).find(".cal-body");
           $scope.head = jQuery($element).find(".cal-head");
           $scope.dateFlipped = false;

           $scope.setupHeading();
           $scope.setupBody($element);

           $scope.addInitialCalendarDays = function() {
               // Run it only once
               if ($scope.initialized) {
                   return;
               }
               $scope.initialized = true;
               var day = $scope.setup($scope.baseDate);

               // going back 300px
               var hiddenNumRows = Math.floor(300 / $scope.unitWidth);
               day.subtract('days', 7 * hiddenNumRows);
               $scope.beginDay = day.clone();
               for (var i = 0; i < 50; ++i) {
                   var rowElement = $scope.generateRow(day);
                   $scope.body.append(rowElement);
                   day.add('days', 7);
               }
               var endDay = day.clone();
               $scope.body.scrollTop(hiddenNumRows * $scope.unitWidth);
               $scope.refreshHeading();
               $scope.setDatesFromModel();
           }

           $scope.body.bind('scroll', function(event_info) {
               var top = $scope.body.scrollTop();
               var height = $scope.body[0].scrollHeight;
               var visibleHeight = $scope.body.innerHeight();
               var bottom = top + visibleHeight;
               if (top < 100) {
                   // create rows
                   var hiddenNumRows = Math.floor(300 / $scope.unitWidth);
                   for (var i = 0; i < hiddenNumRows; ++i) {
                       $scope.beginDay.subtract('days', 7);
                       var rowElement = $scope.generateRow($scope.beginDay);
                       $scope.body.prepend(rowElement);
                   }
                   jQuery($scope.body).scrollTop(top + hiddenNumRows * $scope.unitWidth);
               } else if ((height - bottom) < 100) {
                   // create rows at the bottom
                   var hiddenNumRows = Math.floor(300 / $scope.unitWidth);
                   for (var i = 0; i < hiddenNumRows; ++i) {
                       var rowElement = $scope.generateRow($scope.endDate);
                       $scope.body.append(rowElement);
                       $scope.endDate.add('days', 7);
                   }
               }
               $scope.refreshHeading();
           });

           $scope.$watch('baseDate', function() {
               if ($scope.baseDate != undefined) {
                   $scope.addInitialCalendarDays();
               }
           })
       }
    };
});<|endoftext|>


<commit_before>/* global require, module, process, console, __dirname */
/* jshint -W097 */
'use strict';

var
  _              = require('underscore'),
  async          = require('async'),
  respFormatter  = require('src/lib/responseFormatter'),
  errors         = require('src/lib/errors'),
  RequestUtil    = require('src/lib/apiRequestUtil'),
  slugger        = require('src/lib/slugger'),
  Article        = require('../../models/blog/Article'),
  TagsController = require('./TagsController');

var ArticlesController = {

  getOne: function(req, res, next) {

    var
      r        = new RequestUtil(req),
      criteria = _.extend({ '_id': req.params.article_id }, r.query);

    Article
      .findOne(criteria)
      .populate(r.expands)
      .exec(function(err,model) {
        /* istanbul ignore next */
        if (err) {
          console.log(err);
          return next( new errors.App(err) );
        }
        if (!model) {
          return next( new errors.NotFound() );
        }

        var meta = r.getMeta();
        res.json(respFormatter(model, meta));
      });
  },

  getAll: function(req, res, next) {
    var r = new RequestUtil(req);

    Article.paginate(r.query, r.page, r.limit, function(err, pageCount, paginatedResults, itemCount) {
      /* istanbul ignore next */
      if (err) {
        next( new errors.App(err) );
        return;
      }

      var meta = r.getMeta(null, { itemCount: itemCount, pageCount: pageCount });

      res.json(respFormatter(paginatedResults, meta));

    }, r.options);

  },

  create: function(req, res, next) {

    var slug, tags, model, r = new RequestUtil(req);

    async.series([

      // get the slug (it's async because it ensures that the slug is not
      // already used and if so, it adds a numeric suffix)
      function(callback) {
        slugger(Article, req.body.title, req.body.slug, function(articleSlug) {
          slug = articleSlug;
          callback();
        });
      },

      // get the tags IDs (and create the tags if they don't exist)
      function(callback) {
        TagsController.retrieveAndCreate(req, function(articleTags) {
          tags = articleTags;
          callback();
        });
      },

      // create the Article
      function(callback) {
        model = new Article(); // create a new instance of the Article model

        // set the article attributes
        model.title        = req.body.title;
        model.slug         = slug;
        model.excerpt      = req.body.excerpt;
        model.body         = req.body.body;
        model.author       = req.body.author_id;
        model.owner        = req.user.userId;
        model.published    = req.body.published;
        model.published_at = req.body.publish_date;
        model.commentable  = req.body.commentable;
        model.tags         = tags;

        model.save(callback);
      },

      // expand the relations
      function(callback) {
        model.populate(r.expands, callback);
      }

    ], function(err) {

      /* istanbul ignore next */
      if (err) {
        return next( new errors.App(err) );
      }

      var meta = r.getMeta(model);
      res.json(respFormatter(model, meta));

    });

  },

  update: function(req, res, next) {

    var slug, tags, model, r = new RequestUtil(req);

    async.series([

      // retrieve the model
      function(callback) {
        Article.findById(req.params.article_id, function(err, articleModel) {
          /* istanbul ignore next */
          if (err) { return callback(err); }
          /* istanbul ignore next */
          if (!articleModel) { return callback( new errors.NotFound() ); }

          model = articleModel;
          callback();
        });
      },

      // get the slug (it's async because it ensures that the slug is not
      // already used and if so, it adds a numeric suffix)
      function(callback) {
        slugger(Article, req.body.title, req.body.slug, function(articleSlug) {
          slug = articleSlug;
          callback();
        });
      },

      // get the tags IDs (and create the tags if they don't exist)
      function(callback) {
        TagsController.retrieveAndCreate(req, function(articleTags) {
          tags = articleTags;
          callback();
        });
      },

      // update the Article
      function(callback) {

        // set the article attributes
        model.title        = req.body.title;
        model.slug         = slug;
        model.excerpt      = req.body.excerpt;
        model.body         = req.body.body;
        model.author       = req.body.author_id;
        model.owner        = req.user.userId;
        model.published    = req.body.published;
        model.published_at = req.body.publish_date;
        model.commentable  = req.body.commentable;
        model.tags         = tags;

        model.save(callback);
      },

      // expand the relations
      function(callback) {
        model.populate(r.expands, callback);
      }

    ], function(err) {

      /* istanbul ignore next */
      if (err) {
        var error = (err.name === 'HttpNotFoundError') ? err : new errors.App(err);
        return next(error);
      }

      var meta = r.getMeta();
      res.json(respFormatter(model, meta));

    });
  },

  delete: function(req, res, next) {

    var r = new RequestUtil(req);

    Article
      .findById(req.params.article_id)
      .populate(r.expands)
      .exec(function(err,model) {

        /* istanbul ignore next */
        if (err) {
          return next( new errors.App(err) );
        }
        if (!model) {
          return next( new errors.NotFound() );
        }

        model.remove(function() {
          res.json(respFormatter(model));
        });
    });

  }

};

module.exports = ArticlesController;
<commit_msg>feat: auto generate the slug when creating the article<commit_after>/* global require, module, process, console, __dirname */
/* jshint -W097 */
'use strict';

var
  _              = require('underscore'),
  async          = require('async'),
  respFormatter  = require('src/lib/responseFormatter'),
  errors         = require('src/lib/errors'),
  RequestUtil    = require('src/lib/apiRequestUtil'),
  slugger        = require('src/lib/slugger'),
  Article        = require('../../models/blog/Article'),
  TagsController = require('./TagsController');

var ArticlesController = {

  getOne: function(req, res, next) {

    var
      r        = new RequestUtil(req),
      criteria = _.extend({ '_id': req.params.article_id }, r.query);

    Article
      .findOne(criteria)
      .populate(r.expands)
      .exec(function(err,model) {
        /* istanbul ignore next */
        if (err) {
          console.log(err);
          return next( new errors.App(err) );
        }
        if (!model) {
          return next( new errors.NotFound() );
        }

        var meta = r.getMeta();
        res.json(respFormatter(model, meta));
      });
  },

  getAll: function(req, res, next) {
    var r = new RequestUtil(req);

    Article.paginate(r.query, r.page, r.limit, function(err, pageCount, paginatedResults, itemCount) {
      /* istanbul ignore next */
      if (err) {
        next( new errors.App(err) );
        return;
      }

      var meta = r.getMeta(null, { itemCount: itemCount, pageCount: pageCount });

      res.json(respFormatter(paginatedResults, meta));

    }, r.options);

  },

  create: function(req, res, next) {

    var slug, tags, model, r = new RequestUtil(req);

    async.series([

      // get the slug (it's async because it ensures that the slug is not
      // already used and if so, it adds a numeric suffix)
      function(callback) {
        slugger(Article, req.body.title, null, function(articleSlug) {
          slug = articleSlug;
          callback();
        });
      },

      // get the tags IDs (and create the tags if they don't exist)
      function(callback) {
        TagsController.retrieveAndCreate(req, function(articleTags) {
          tags = articleTags;
          callback();
        });
      },

      // create the Article
      function(callback) {
        model = new Article(); // create a new instance of the Article model

        // set the article attributes
        model.title        = req.body.title;
        model.slug         = slug;
        model.excerpt      = req.body.excerpt;
        model.body         = req.body.body;
        model.author       = req.body.author_id;
        model.owner        = req.user.userId;
        model.published    = req.body.published;
        model.published_at = req.body.publish_date;
        model.commentable  = req.body.commentable;
        model.tags         = tags;

        model.save(callback);
      },

      // expand the relations
      function(callback) {
        model.populate(r.expands, callback);
      }

    ], function(err) {

      /* istanbul ignore next */
      if (err) {
        return next( new errors.App(err) );
      }

      var meta = r.getMeta(model);
      res.json(respFormatter(model, meta));

    });

  },

  update: function(req, res, next) {

    var slug, tags, model, r = new RequestUtil(req);

    async.series([

      // retrieve the model
      function(callback) {
        Article.findById(req.params.article_id, function(err, articleModel) {
          /* istanbul ignore next */
          if (err) { return callback(err); }
          /* istanbul ignore next */
          if (!articleModel) { return callback( new errors.NotFound() ); }

          model = articleModel;
          callback();
        });
      },

      // get the slug (it's async because it ensures that the slug is not
      // already used and if so, it adds a numeric suffix)
      function(callback) {
        slugger(Article, req.body.title, req.body.slug, function(articleSlug) {
          slug = articleSlug;
          callback();
        });
      },

      // get the tags IDs (and create the tags if they don't exist)
      function(callback) {
        TagsController.retrieveAndCreate(req, function(articleTags) {
          tags = articleTags;
          callback();
        });
      },

      // update the Article
      function(callback) {

        // set the article attributes
        model.title        = req.body.title;
        model.slug         = slug;
        model.excerpt      = req.body.excerpt;
        model.body         = req.body.body;
        model.author       = req.body.author_id;
        model.owner        = req.user.userId;
        model.published    = req.body.published;
        model.published_at = req.body.publish_date;
        model.commentable  = req.body.commentable;
        model.tags         = tags;

        model.save(callback);
      },

      // expand the relations
      function(callback) {
        model.populate(r.expands, callback);
      }

    ], function(err) {

      /* istanbul ignore next */
      if (err) {
        var error = (err.name === 'HttpNotFoundError') ? err : new errors.App(err);
        return next(error);
      }

      var meta = r.getMeta();
      res.json(respFormatter(model, meta));

    });
  },

  delete: function(req, res, next) {

    var r = new RequestUtil(req);

    Article
      .findById(req.params.article_id)
      .populate(r.expands)
      .exec(function(err,model) {

        /* istanbul ignore next */
        if (err) {
          return next( new errors.App(err) );
        }
        if (!model) {
          return next( new errors.NotFound() );
        }

        model.remove(function() {
          res.json(respFormatter(model));
        });
    });

  }

};

module.exports = ArticlesController;
<|endoftext|>


<commit_before>// Import the page's CSS. Webpack will know what to do with it.
import "../stylesheets/app.css";

// Import libraries we need.
import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'

// Import our contract artifacts and turn them into usable abstractions.
import alice_token_artifacts from '../../build/contracts/AliceToken.json';
import wallet_artifacts from '../../build/contracts/DonationWallet.json';
import project_artifacts from '../../build/contracts/Project.json';
import catalog_artifacts from '../../build/contracts/ProjectCatalog.json';

// MetaCoin is our usable abstraction, which we'll use through the code below.
var AliceToken = contract(alice_token_artifacts);
var Wallet = contract(wallet_artifacts);
var Project = contract(project_artifacts);
var Catalog = contract(catalog_artifacts);

const PROJECT_NAME = "DEMO_PROJECT";

var accounts;
var aliceAccount;
var donor1Account;
var donor2Account;
var beneficiaryAccount;
var judgeAccount;

var TokenContract;
var CharityContract;
var ImpactContract;
var CatalogContract;
var ProjectContract

var balances = {};
var wallets = {};

function refreshBalance() {
  showBalance(wallets[donor1Account].address,  "balance_donor_1");
  showBalance(wallets[donor2Account].address,  "balance_donor_2");
  showBalance(ProjectContract.address, "balance_charity");
  showBalance(beneficiaryAccount, "balance_beneficiary");
}

function showBalance(account, element) {
  TokenContract.balanceOf(account).then(function(value) {
    var balance_element = document.getElementById(element);
    balance_element.innerHTML = value.valueOf();
    balances[account] = value;
  });
}

function showAllImpacts() {
  showImpact('Tenancy');
  showImpact('Employment');
}

function showImpact(name) {
  ImpactContract.getImpactCount.call(name).then(function(c) {
    var count = c.valueOf();
    console.log(name + ' impact: ' + count);
    for(var i=0; i < count; i++) {
      (function(index) {
        ImpactContract.getImpactDonor.call(name, i).then(function (address) {
          console.log(name + ' address[' + index + ']: ' + address);
          ImpactContract.getImpactValue.call(name, address).then(function (value) {
            console.log(name + ' value[' + index + ']: ' + value);
          });
        });
      })(i);
    }
  });
}

window.deposit = function(account, value) {
  TokenContract.mint(wallets[account].address, value, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		 refreshBalance();
		});
};

window.donate = function(account, value) {
	TokenContract.mint(wallets[account].address, value, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		refreshBalance();
	});
};

function reuseUnspent(account) {
  TokenContract.transfer(CharityContract.address, balances[account], {from: account, gas: 1000000})
    .then(function(tx) {
      return CharityContract.notify(account, balances[account], {from: aliceAccount, gas: 1000000})
    .then(function () {
      console.log("Donated remaining funds: " + balances[account]);
      refreshBalance();
      return null;
    });
  });
}

function validateOutcome(name, value) {
  return CharityContract.unlockOutcome(name, value, {from: judgeAccount, gas: 500000}).then(function() {
    console.log("Validating outcome: " + name + " valued at: " + value);
    refreshBalance();
    showAllImpacts();
    return linkImpact(name, value);
  });
}

function payBackAll() {
  payBack(donor1Account);
  payBack(donor2Account);
}

function payBack(account) {
  CharityContract.payBack(account, {from: aliceAccount, gas: 1000000}).then(function() {
    console.log("Payback done");
    refreshBalance();
    return null;
  });
}

function linkImpact(name, outcomeValue) {
  return ImpactContract.getImpactLinked.call(name, {from: aliceAccount}).then(function(val) {
    console.log("Linked: " + val + " of: " + outcomeValue);
    if (val < outcomeValue) {
      console.log("Linking impact: " + val + " of: " + outcomeValue);
      return ImpactContract.linkImpact(name, {from: aliceAccount, gas: 2000000}).then(function(tx) {
        return linkImpact(name, outcomeValue);
      });
    }
  });
}

function mapAccounts(accounts) {
  aliceAccount = accounts[0];
  judgeAccount = accounts[1];
  beneficiaryAccount = accounts[2];
  donor1Account = accounts[3];
  donor2Account = accounts[4];

  window.donor1Account = donor1Account;
  window.donor2Account = donor2Account;
}

function printLog(text) {
	var logBox = document.getElementById("log");
	logBox.innerHTML += text + "
";
}

function printTx(tx) {
	printLog("Transaction hash: " + tx);
}

function printContract(contract) {
  printLog("Contract " + " deployed to: " + contract.address);
}

function setupWeb3Filter() {
  var filter = web3.eth.filter({});

  filter.watch(function (error, log) {
    console.log(log);
    printTx(log.transactionHash);
  });
}

async function deployToken() {
	AliceToken.setProvider(web3.currentProvider);

  TokenContract = await AliceToken.new({from: aliceAccount, gas: 2000000});
  printContract(TokenContract);
}

async function deployProject() {
	Project.setProvider(web3.currentProvider);
	Catalog.setProvider(web3.currentProvider);

	ProjectContract = await Project.new(PROJECT_NAME, {from: aliceAccount, gas: 2000000});
	printContract(ProjectContract);

	CatalogContract = await Catalog.new({from: aliceAccount, gas: 2000000});
	printContract(CatalogContract);

	await CatalogContract.addProject(PROJECT_NAME, ProjectContract.address, {from: aliceAccount, gas: 2000000});
}

async function deployWallet(donor) {
	Wallet.setProvider(web3.currentProvider);

	wallets[donor] = await Wallet.new(aliceAccount, {from: aliceAccount, gas: 2000000});
	printContract(wallets[donor]);
}

async function deploy() {
  await deployToken();
  await deployProject();
  await deployWallet(donor1Account);
  await deployWallet(donor2Account);
	refreshBalance();
}

window.onload = function() {
	window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

	web3.eth.getAccounts(function(err, accs) {
      if (err != null) {
        alert("There was an error fetching your accounts.");
        return;
      }

      if (accs.length == 0) {
        alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.");
        return;
      }

		  setupWeb3Filter();

      mapAccounts(accs);

      deploy();

    });

};
<commit_msg>Donation UI<commit_after>// Import the page's CSS. Webpack will know what to do with it.
import "../stylesheets/app.css";

// Import libraries we need.
import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'

// Import our contract artifacts and turn them into usable abstractions.
import alice_token_artifacts from '../../build/contracts/AliceToken.json';
import wallet_artifacts from '../../build/contracts/DonationWallet.json';
import project_artifacts from '../../build/contracts/Project.json';
import catalog_artifacts from '../../build/contracts/ProjectCatalog.json';
import impact_registry_artifacts from '../../build/contracts/ImpactRegistry.json';

// MetaCoin is our usable abstraction, which we'll use through the code below.
var AliceToken = contract(alice_token_artifacts);
var Wallet = contract(wallet_artifacts);
var Project = contract(project_artifacts);
var Catalog = contract(catalog_artifacts);
var ImpactRegistry = contract(impact_registry_artifacts);

const PROJECT_NAME = "DEMO_PROJECT";

var accounts;
var aliceAccount;
var donor1Account;
var donor2Account;
var beneficiaryAccount;
var judgeAccount;

var TokenContract;
var CharityContract;
var ImpactContract;
var CatalogContract;
var ProjectContract;

var balances = {};
var wallets = {};

function refreshBalance() {
  showBalance(wallets[donor1Account].address,  "balance_donor_1");
  showBalance(wallets[donor2Account].address,  "balance_donor_2");
  showBalance(ProjectContract.address, "balance_charity");
  showBalance(beneficiaryAccount, "balance_beneficiary");
}

function showBalance(account, element) {
  TokenContract.balanceOf(account).then(function(value) {
    var balance_element = document.getElementById(element);
    balance_element.innerHTML = value.valueOf();
    balances[account] = value;
  });
}

function showAllImpacts() {
  showImpact('Tenancy');
  showImpact('Employment');
}

function showImpact(name) {
  ImpactContract.getImpactCount.call(name).then(function(c) {
    var count = c.valueOf();
    console.log(name + ' impact: ' + count);
    for(var i=0; i < count; i++) {
      (function(index) {
        ImpactContract.getImpactDonor.call(name, i).then(function (address) {
          console.log(name + ' address[' + index + ']: ' + address);
          ImpactContract.getImpactValue.call(name, address).then(function (value) {
            console.log(name + ' value[' + index + ']: ' + value);
          });
        });
      })(i);
    }
  });
}

window.deposit = function(account, value) {
  TokenContract.mint(wallets[account].address, value, {from: aliceAccount, gas: 1000000}).then(function(tx) {
		 refreshBalance();
		});
};

window.donate = async function(account, value) {
	//var a = await wallets[account].getPC({from: aliceAccount, gas: 1000000});
	//console.log(a);
	wallets[account].donate(TokenContract.address, value, PROJECT_NAME, {from: aliceAccount, gas: 1000000}).then(function(tx) {
	 	refreshBalance();
	});
};

function reuseUnspent(account) {
  TokenContract.transfer(CharityContract.address, balances[account], {from: account, gas: 1000000})
    .then(function(tx) {
      return CharityContract.notify(account, balances[account], {from: aliceAccount, gas: 1000000})
    .then(function () {
      console.log("Donated remaining funds: " + balances[account]);
      refreshBalance();
      return null;
    });
  });
}

function validateOutcome(name, value) {
  return CharityContract.unlockOutcome(name, value, {from: judgeAccount, gas: 500000}).then(function() {
    console.log("Validating outcome: " + name + " valued at: " + value);
    refreshBalance();
    showAllImpacts();
    return linkImpact(name, value);
  });
}

function payBackAll() {
  payBack(donor1Account);
  payBack(donor2Account);
}

function payBack(account) {
  CharityContract.payBack(account, {from: aliceAccount, gas: 1000000}).then(function() {
    console.log("Payback done");
    refreshBalance();
    return null;
  });
}

function linkImpact(name, outcomeValue) {
  return ImpactContract.getImpactLinked.call(name, {from: aliceAccount}).then(function(val) {
    console.log("Linked: " + val + " of: " + outcomeValue);
    if (val < outcomeValue) {
      console.log("Linking impact: " + val + " of: " + outcomeValue);
      return ImpactContract.linkImpact(name, {from: aliceAccount, gas: 2000000}).then(function(tx) {
        return linkImpact(name, outcomeValue);
      });
    }
  });
}

function mapAccounts(accounts) {
  aliceAccount = accounts[0];
  judgeAccount = accounts[1];
  beneficiaryAccount = accounts[2];
  donor1Account = accounts[3];
  donor2Account = accounts[4];

  window.donor1Account = donor1Account;
  window.donor2Account = donor2Account;
}

function printLog(text) {
	var logBox = document.getElementById("log");
	logBox.innerHTML += text + "
";
}

function printTx(tx) {
	printLog("Transaction hash: " + tx);
}

function printContract(contract) {
  printLog("Contract " + " deployed to: " + contract.address);
}

function setupWeb3Filter() {
  var filter = web3.eth.filter({});

  filter.watch(function (error, log) {
    console.log(log);
    printTx(log.transactionHash);
  });
}

async function deployToken() {
	AliceToken.setProvider(web3.currentProvider);

  TokenContract = await AliceToken.new({from: aliceAccount, gas: 2000000});
  printContract(TokenContract);
}

async function deployProject() {
	Project.setProvider(web3.currentProvider);
	Catalog.setProvider(web3.currentProvider);
	ImpactRegistry.setProvider(web3.currentProvider);

	ProjectContract = await Project.new(PROJECT_NAME, {from: aliceAccount, gas: 2000000});
	printContract(ProjectContract);

	var registry = await ImpactRegistry.new(ProjectContract.address, {from: aliceAccount, gas: 2000000});
	await ProjectContract.setImpactRegistry(registry.address, {from: aliceAccount, gas: 2000000});

	CatalogContract = await Catalog.new({from: aliceAccount, gas: 2000000});
	printContract(CatalogContract);

	await CatalogContract.addProject(PROJECT_NAME, ProjectContract.address, {from: aliceAccount, gas: 2000000});
}

async function deployWallet(donor) {
	Wallet.setProvider(web3.currentProvider);

	wallets[donor] = await Wallet.new(CatalogContract.address, {from: aliceAccount, gas: 2000000});
	printContract(wallets[donor]);
}

async function deploy() {
  await deployToken();
  await deployProject();
  await deployWallet(donor1Account);
  await deployWallet(donor2Account);
	refreshBalance();
}

window.onload = function() {
	window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

	web3.eth.getAccounts(function(err, accs) {
      if (err != null) {
        alert("There was an error fetching your accounts.");
        return;
      }

      if (accs.length == 0) {
        alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.");
        return;
      }

		  setupWeb3Filter();

      mapAccounts(accs);

      deploy();

    });

};
<|endoftext|>


<commit_before>function TranscriptionCtrl($scope, $log, Restangular, BinarySearch) {

  //Init some sane defaults
  $scope.displayWordStart = 0;
  $scope.currentHighlightedIndex = 0;
  $scope.fullTranscription = [];
  var step = 50;
  var nextTimeToDisplay = 0;

  $scope.transcription = [];

  //Get the transcription from the server
  Restangular.one('audiofiles.json', 6).getList('transcriptions').then(function(transcriptions) {
    $scope.fullTranscription = transcriptions;
    $scope.transcription = $scope.getNextWords($scope.fullTranscription);

  });

  $scope.moveVideo = function(eventObject) {
    var time = eventObject.currentTarget.attributes["data-start"].value;
    $('#mediafile')["0"].player.setCurrentTime(time);
  }

  //Get the next list of words to display on the screen
  $scope.getNextWords = function(transcriptions) {
    var displayWordEnd = $scope.displayWordStart + step;

    // Try to avoid out of bounds exception
    if ($scope.displayWordStart > transcriptions[0].length -1) {
      return [];
    }

    // Same here
    if (displayWordEnd > transcriptions[0].length -1) {
      displayWordEnd = transcriptions[0].length -1;
    }

    //Get the words
    var words = transcriptions[0].content.slice($scope.displayWordStart, displayWordEnd);

    //Reset the counters
    $scope.displayWordStart = displayWordEnd;
    displayWordEnd = $scope.displayWordStart + step;
    if(transcriptions[0].content.length >= $scope.displayWordStart) {
      nextTimeToDisplay = transcriptions[0].content[$scope.displayWordStart].start;
    }

    return words;
  }

  //Non angular events
  $("#mediafile").on("timeupdate", function (e) {
    $scope.$apply( function() {

      //Seach the word through the words that are displayed
      var currentDisplayedWordIndex = BinarySearch.search($scope.transcription, e.target.currentTime, function(item) { return item.start; })

      //Check boundaries
      if(currentDisplayedWordIndex >= 0 && currentDisplayedWordIndex < $scope.transcription.length) {
        if (currentDisplayedWordIndex == $scope.transcription.length - 1) {
          $('#content span').addClass('current');
        } else {
          var currentWord = $scope.transcription[currentDisplayedWordIndex + 1];
          $('#content span[data-start="' + currentWord.start + '"]').prevAll().addClass('current');
        }
      }

      if(nextTimeToDisplay != 0 && e.target.currentTime > nextTimeToDisplay) {
        $scope.transcription = $scope.getNextWords($scope.fullTranscription);

      }
    });

  });

  $("#mediafile").on("seeking", function (e) {
    $scope.$apply( function() {
      if(typeof $scope.fullTranscription[0] !== 'undefined') {
        $scope.displayWordStart = BinarySearch.search($scope.fullTranscription[0].content, e.target.currentTime, function(item) { return item.start; })
        $scope.transcription = $scope.getNextWords($scope.fullTranscription);
      }
    });

  });

}

<commit_msg>Synchonize video when clicking on words<commit_after>function TranscriptionCtrl($scope, $log, Restangular, BinarySearch) {

  //Init some sane defaults
  $scope.nextWordToDisplay = 0;
  $scope.currentHighlightedIndex = 0;
  $scope.currentWordStart = 0;
  $scope.currentWordEnd = 0;
  $scope.fullTranscription = [];
  $scope.step = 50;
  var nextTimeToDisplay = 0;

  $scope.transcription = [];

  //Get the transcription from the server
  Restangular.one('audiofiles.json', 6).getList('transcriptions').then(function(transcriptions) {
    $scope.fullTranscription = transcriptions;
    $scope.transcription = $scope.getNextWords($scope.fullTranscription);

  });

  $scope.moveVideo = function(eventObject) {
    var time = eventObject.currentTarget.attributes["data-start"].value;
    $('#mediafile')["0"].player.setCurrentTime(time);
  }

  //Get the next list of words to display on the screen
  $scope.getNextWords = function(transcriptions) {
    $scope.currentWordEnd = $scope.nextWordToDisplay + $scope.step;
    $scope.currentWordStart = $scope.nextWordToDisplay;

    // Try to avoid out of bounds exception
    if ($scope.currentWordStart > transcriptions[0].length -1) {
      return [];
    }

    // Same here
    if ($scope.currentWordEnd > transcriptions[0].length -1) {
      $scope.currentWordEnd = transcriptions[0].length -1;
    }

    //Get the words
    var words = transcriptions[0].content.slice($scope.currentWordStart, $scope.currentWordEnd);

    //Reset the counters
    $scope.nextWordToDisplay = $scope.currentWordEnd;
    if(transcriptions[0].content.length >= $scope.nextWordToDisplay) {
      nextTimeToDisplay = transcriptions[0].content[$scope.nextWordToDisplay].start;
    }

    return words;
  }

  //Non angular events
  $("#mediafile").on("timeupdate", function (e) {
    $scope.$apply( function() {

      //Seach the word through the words that are displayed
      var currentDisplayedWordIndex = BinarySearch.search($scope.transcription, e.target.currentTime, function(item) { return item.start; })

      //Check boundaries
      if(currentDisplayedWordIndex >= 0 && currentDisplayedWordIndex < $scope.transcription.length) {
        if (currentDisplayedWordIndex == $scope.transcription.length - 1) {
          $('#content span').addClass('current');
        } else {
          var currentWord = $scope.transcription[currentDisplayedWordIndex + 1];
          $('#content span').removeClass('current');
          $('#content span[data-start="' + currentWord.start + '"]').prevAll().addClass('current');
        }
      }

      //Next page
      if(nextTimeToDisplay != 0 && e.target.currentTime > nextTimeToDisplay) {
        $scope.transcription = $scope.getNextWords($scope.fullTranscription);

      }
    });

  });

  $("#mediafile").on("seeking", function (e) {
    $scope.$apply( function() {
      if(typeof $scope.fullTranscription[0] !== 'undefined') {
        var nextWordPosition = BinarySearch.search($scope.fullTranscription[0].content, e.target.currentTime, function(item) { return item.start; });

        //Change page only if the next word is not currently displayed
        if(nextWordPosition < $scope.currentWordStart || nextWordPosition >= $scope.currentWordStart + $scope.step) {
            $scope.nextWordToDisplay = BinarySearch.search($scope.fullTranscription[0].content, e.target.currentTime, function(item) { return item.start; })
            $scope.transcription = $scope.getNextWords($scope.fullTranscription);
        }
      }
    });

  });

}

<|endoftext|>


<commit_before>'use strict';

describe('Testing provider: ParseBackend', function () {
    var $q, ParseBackend;
    ParseBackend = null;
    $q = null;

    beforeEach(module('module.ParseBackend', function (ParseBackendProvider) {
        ParseBackendProvider.setApplicationId('__test_app_id');
        ParseBackendProvider.setJavascriptKey('__test_js_key');
    }));

    beforeEach(inject(function (_ParseBackend_, _$q_) {
        ParseBackend = _ParseBackend_;
        $q = _$q_;
    }));

    it('should create a parse object', function () {
        var Account, account;
        Account = ParseBackend.Object.extend("Account");

        account = new Account();
        account.set("access_token", "test_token");

        //var test = account.save();
        var test = account.save().then(function (rec) {
            var test = "test";
        }).catch(function (err) {
            var err = 'error';
        });

    });
});<commit_msg>Remove $q<commit_after>'use strict';

describe('Testing provider: ParseBackend', function () {
    var ParseBackend;
    ParseBackend = null;

    beforeEach(module('module.ParseBackend', function (ParseBackendProvider) {
        ParseBackendProvider.setApplicationId('__test_app_id');
        ParseBackendProvider.setJavascriptKey('__test_js_key');
    }));

    beforeEach(inject(function (_ParseBackend_) {
        ParseBackend = _ParseBackend_;
    }));

    it('should create a parse object', function () {
        var Account, account;
        Account = ParseBackend.Object.extend("Account");

        account = new Account();
        account.set("access_token", "test_token");

        account.save().then(function (account) {
            var test = "ts";
        }).catch(function (err) {
            var err = 'error';
        });

    });
});<|endoftext|>


<commit_before>'use strict';

angular.module('movieApp.details', [
	'ngRoute',
	'movieApp.details.controllers'
])
.config(['$routeProvider', function($routeProvider) {
	$routeProvider.when('/details/:movieId', {
      templateUrl: 'partials/movieDetail.html',
      controller: 'DetailCtrl'
    });
}]);

angular.module('movieApp.details.controllers', [
	'moiveApp.details.services',
	'ngAnimate',
	'iso.directives'
])
.controller('DetailCtrl', ['$rootScope', '$scope', '$sce', '$timeout', 'detailsService',
	function($rootScope, $scope, $sce, $timeout, detailsService) {
		detailsService.getMovieDetails().success(function(data) {
			$scope.movie = data;
			$scope.setTrailer(0);
			$rootScope.movieId = data.id;

			<!-- Fix to delay isotop until images are loaded -->
			$timeout(function() {
				console.log('Re-initiating isotope');
				$scope.$broadcast('iso-init', {name: null, params: null});
			}, 700);
		});
	$scope.setTrailer = function(value) {
		var trailer = data.trailers.youtube[value];
		if(null != data.trailers.youtube[value] || null) {
			console.log("Setting trailer to index " + value);
			$scope.yturl = $sce.trustAsResourceUrl("http://www.youtube.com/embed/" + data.trailers.youtube[value].source + "?enablejsapi=0");
			$scope.trailer = data.trailers.youtube[value];
		}
	};
}]);

angular.module('moiveApp.details.services', [
])
.factory('detailsService', ['$http', '$routeParams', function($http, $routeParams) {
	return {
		getMovieDetails : function() {
			return $http.get("https://api.themoviedb.org/3/movie/" + $routeParams.movieId + "?api_key=013eff1b8075d646416de6ec45620619&append_to_response=credits,trailers");
		}
	};
}]);<commit_msg>Fix for trailer not showing that was introducded with refactoring<commit_after>'use strict';

angular.module('movieApp.details', [
	'ngRoute',
	'movieApp.details.controllers'
])
.config(['$routeProvider', function($routeProvider) {
	$routeProvider.when('/details/:movieId', {
      templateUrl: 'partials/movieDetail.html',
      controller: 'DetailCtrl'
    });
}]);

angular.module('movieApp.details.controllers', [
	'moiveApp.details.services',
	'ngAnimate',
	'iso.directives'
])
.controller('DetailCtrl', ['$rootScope', '$scope', '$sce', '$timeout', 'detailsService',
	function($rootScope, $scope, $sce, $timeout, detailsService) {
		detailsService.getMovieDetails().success(function(data) {
			$scope.movie = data;
			$scope.setTrailer(0);
			$rootScope.movieId = data.id;

			<!-- Fix to delay isotop until images are loaded -->
			$timeout(function() {
				console.log('Re-initiating isotope');
				$scope.$broadcast('iso-init', {name: null, params: null});
			}, 700);
		});
	$scope.setTrailer = function(index) {
		var data = $scope.movie;
		var trailer = data.trailers.youtube[index];
		if(null != data.trailers.youtube[index] || null) {
			console.log("Setting trailer to index " + index);
			$scope.yturl = $sce.trustAsResourceUrl("http://www.youtube.com/embed/" + data.trailers.youtube[index].source + "?enablejsapi=0");
			$scope.trailer = data.trailers.youtube[index];
		}
	};
}]);

angular.module('moiveApp.details.services', [
])
.factory('detailsService', ['$http', '$routeParams', function($http, $routeParams) {
	return {
		getMovieDetails : function() {
			return $http.get("https://api.themoviedb.org/3/movie/" + $routeParams.movieId + "?api_key=013eff1b8075d646416de6ec45620619&append_to_response=credits,trailers");
		}
	};
}]);<|endoftext|>