<commit_before>(function (module) {
    mifosX.controllers = _.extend(module, {
        CreateLoanProductController: function (scope, resourceFactory, location, dateFilter) {
            scope.restrictDate = new Date();
            scope.formData = {};
            scope.charges = [];
            scope.floatingrateoptions = [];
            scope.loanProductConfigurableAttributes = [];
            scope.showOrHideValue = "show";
            scope.configureFundOptions = [];
            scope.specificIncomeAccountMapping = [];
            scope.penaltySpecificIncomeaccounts = [];
            scope.configureFundOption = {};
            scope.date = {};
            scope.pvFlag = false;
            scope.rvFlag = false;
            scope.irFlag = false;
            scope.chargeFlag = false;
            scope.penalityFlag = false;
            scope.frFlag = false;
            scope.fiFlag = false;
            scope.piFlag = false;
            scope.amortization = true;
            scope.arrearsTolerance = true;
            scope.graceOnArrearsAging = true;
            scope.interestCalcPeriod = true;
            scope.interestMethod = true;
            scope.graceOnPrincipalAndInterest = true;
            scope.repaymentFrequency = true;
            scope.transactionProcessingStrategy = true;
            scope.allowAttributeConfiguration = true;
            resourceFactory.loanProductResource.get({resourceType: 'template'}, function (data) {
                scope.product = data;
                scope.assetAccountOptions = scope.product.accountingMappingOptions.assetAccountOptions || [];
                scope.incomeAccountOptions = scope.product.accountingMappingOptions.incomeAccountOptions || [];
                scope.expenseAccountOptions = scope.product.accountingMappingOptions.expenseAccountOptions || [];
                scope.liabilityAccountOptions = scope.product.accountingMappingOptions.liabilityAccountOptions || [];
                scope.incomeAndLiabilityAccountOptions = scope.incomeAccountOptions.concat(scope.liabilityAccountOptions);
                scope.penaltyOptions = scope.product.penaltyOptions || [];
                scope.chargeOptions = scope.product.chargeOptions || [];
                scope.overduecharges = [];
                for (var i in scope.penaltyOptions) {
                    if (scope.penaltyOptions[i].chargeTimeType.code == 'chargeTimeType.overdueInstallment') {
                        scope.overduecharges.push(scope.penaltyOptions[i]);
                    }
                }
                scope.formData.currencyCode = scope.product.currencyOptions[0].code;
                scope.formData.includeInBorrowerCycle = 'false';
                scope.formData.useBorrowerCycle = 'false';
                scope.formData.digitsAfterDecimal = '2';
                scope.formData.inMultiplesOf = '0';
                scope.formData.repaymentFrequencyType = scope.product.repaymentFrequencyType.id;
                scope.formData.interestRateFrequencyType = scope.product.interestRateFrequencyType.id;
                scope.formData.amortizationType = scope.product.amortizationType.id;
                scope.formData.interestType = scope.product.interestType.id;
                scope.formData.interestCalculationPeriodType = scope.product.interestCalculationPeriodType.id;
                scope.formData.transactionProcessingStrategyId = scope.product.transactionProcessingStrategyOptions[0].id;
                scope.formData.principalVariationsForBorrowerCycle = scope.product.principalVariationsForBorrowerCycle;
                scope.formData.interestRateVariationsForBorrowerCycle = scope.product.interestRateVariationsForBorrowerCycle;
                scope.formData.numberOfRepaymentVariationsForBorrowerCycle = scope.product.numberOfRepaymentVariationsForBorrowerCycle;
                scope.formData.multiDisburseLoan = 'false';
                scope.formData.accountingRule = '1';
                scope.formData.daysInYearType = scope.product.daysInYearType.id;
                scope.formData.daysInMonthType = scope.product.daysInMonthType.id;
                scope.formData.isInterestRecalculationEnabled = scope.product.isInterestRecalculationEnabled;
                scope.formData.interestRecalculationCompoundingMethod = scope.product.interestRecalculationData.interestRecalculationCompoundingType.id;
                scope.formData.rescheduleStrategyMethod = scope.product.interestRecalculationData.rescheduleStrategyType.id;
                scope.formData.preClosureInterestCalculationStrategy = scope.product.interestRecalculationData.preClosureInterestCalculationStrategy.id;
                if(scope.product.interestRecalculationData.recalculationRestFrequencyType){
                    scope.formData.recalculationRestFrequencyType = scope.product.interestRecalculationData.recalculationRestFrequencyType.id;
                }
                scope.floatingRateOptions = data.floatingRateOptions ;
                scope.formData.isFloatingInterestRateCalculationAllowed = false ;
                scope.formData.isLinkedToFloatingInterestRates = false ;
                scope.formData.allowVariableInstallments = false ;
            });

            scope.chargeSelected = function (chargeId) {

                if (chargeId) {
                    resourceFactory.chargeResource.get({chargeId: chargeId, template: 'true'}, this.formData, function (data) {
                        data.chargeId = data.id;
                        scope.charges.push(data);
                        //to charge select box empty

                        if (data.penalty) {
                            scope.penalityFlag = true;
                            scope.penalityId = '';
                        } else {
                            scope.chargeFlag = true;
                            scope.chargeId = '';
                        }
                    });
                }
            };

            scope.deleteCharge = function (index) {
                scope.charges.splice(index, 1);
            };

            //advanced accounting rule
            scope.showOrHide = function (showOrHideValue) {

                if (showOrHideValue == "show") {
                    scope.showOrHideValue = 'hide';
                }

                if (showOrHideValue == "hide") {
                    scope.showOrHideValue = 'show';
                }
            };

            scope.addConfigureFundSource = function () {
                scope.frFlag = true;
                scope.configureFundOptions.push({
                    paymentTypeId: scope.product.paymentTypeOptions.length > 0 ? scope.product.paymentTypeOptions[0].id : '',
                    fundSourceAccountId: scope.assetAccountOptions.length > 0 ? scope.assetAccountOptions[0].id : '',
                    paymentTypeOptions: scope.product.paymentTypeOptions.length > 0 ? scope.product.paymentTypeOptions : [],
                    assetAccountOptions: scope.assetAccountOptions.length > 0 ? scope.assetAccountOptions : []
                });
            };

            scope.mapFees = function () {
                scope.fiFlag = true;
                scope.specificIncomeAccountMapping.push({
                    chargeId: scope.chargeOptions.length > 0 ? scope.chargeOptions[0].id : '',
                    incomeAccountId: scope.incomeAndLiabilityAccountOptions.length > 0 ? scope.incomeAndLiabilityAccountOptions[0].id : ''
                });
            };

            scope.addPrincipalVariation = function () {
                scope.pvFlag = true;
                scope.formData.principalVariationsForBorrowerCycle.push({
                    valueConditionType: scope.product.valueConditionTypeOptions[0].id
                });
            };
            scope.addInterestRateVariation = function () {
                scope.irFlag = true;
                scope.formData.interestRateVariationsForBorrowerCycle.push({
                    valueConditionType: scope.product.valueConditionTypeOptions[0].id
                });
            };
            scope.addNumberOfRepaymentVariation = function () {
                scope.rvFlag = true;
                scope.formData.numberOfRepaymentVariationsForBorrowerCycle.push({
                    valueConditionType: scope.product.valueConditionTypeOptions[0].id
                });
            };

            scope.mapPenalty = function () {
                scope.piFlag = true;
                scope.penaltySpecificIncomeaccounts.push({
                    chargeId: scope.penaltyOptions.length > 0 ? scope.penaltyOptions[0].id : '',
                    incomeAccountId: scope.incomeAccountOptions.length > 0 ? scope.incomeAccountOptions[0].id : ''
                });
            };

            scope.deleteFund = function (index) {
                scope.configureFundOptions.splice(index, 1);
            };

            scope.deleteFee = function (index) {
                scope.specificIncomeAccountMapping.splice(index, 1);
            };

            scope.deletePenalty = function (index) {
                scope.penaltySpecificIncomeaccounts.splice(index, 1);
            };

            scope.deletePrincipalVariation = function (index) {
                scope.formData.principalVariationsForBorrowerCycle.splice(index, 1);
            };

            scope.deleteInterestRateVariation = function (index) {
                scope.formData.interestRateVariationsForBorrowerCycle.splice(index, 1);
            };

            scope.deleterepaymentVariation = function (index) {
                scope.formData.numberOfRepaymentVariationsForBorrowerCycle.splice(index, 1);
            };

            scope.cancel = function () {
                location.path('/loanproducts');
            };

            scope.isAccountingEnabled = function () {
                if (scope.formData.accountingRule == 2 || scope.formData.accountingRule == 3 || scope.formData.accountingRule == 4) {
                    return true;
                }
                return false;
            }

            scope.isAccrualAccountingEnabled = function () {
                if (scope.formData.accountingRule == 3 || scope.formData.accountingRule == 4) {
                    return true;
                }
                return false;
            }

                };
            scope.setAttributeValues = function(){
                if(scope.allowAttributeConfiguration == false){
                    scope.amortization = false;
                    scope.arrearsTolerance = false;
                    scope.graceOnArrearsAging = false;
                    scope.interestCalcPeriod = false;
                    scope.interestMethod = false;
                    scope.graceOnPrincipalAndInterest = false;
                    scope.repaymentFrequency = false;
                    scope.transactionProcessingStrategy = false;
                }
            }

	    scope.filterCharges = function(currencyCode, multiDisburseLoan) {
		return function (item) {
			if ((multiDisburseLoan != true) && item.chargeTimeType.id == 12) {
				return false;
			}
			if (item.currency.code != currencyCode) {
				return false;
			}
			return true;
		};
	    };

            scope.submit = function () {
                var reqFirstDate = dateFilter(scope.date.first, scope.df);
                var reqSecondDate = dateFilter(scope.date.second, scope.df);
                scope.paymentChannelToFundSourceMappings = [];
                scope.feeToIncomeAccountMappings = [];
                scope.penaltyToIncomeAccountMappings = [];
                scope.chargesSelected = [];
                scope.selectedConfigurableAttributes = [];

                var temp = '';

                //configure fund sources for payment channels
                for (var i in scope.configureFundOptions) {
                    temp = {
                        paymentTypeId: scope.configureFundOptions[i].paymentTypeId,
                        fundSourceAccountId: scope.configureFundOptions[i].fundSourceAccountId
                    }
                    scope.paymentChannelToFundSourceMappings.push(temp);
                }

                //map fees to specific income accounts
                for (var i in scope.specificIncomeAccountMapping) {
                    temp = {
                        chargeId: scope.specificIncomeAccountMapping[i].chargeId,
                        incomeAccountId: scope.specificIncomeAccountMapping[i].incomeAccountId
                    }
                    scope.feeToIncomeAccountMappings.push(temp);
                }

                //map penalties to specific income accounts
                for (var i in scope.penaltySpecificIncomeaccounts) {
                    temp = {
                        chargeId: scope.penaltySpecificIncomeaccounts[i].chargeId,
                        incomeAccountId: scope.penaltySpecificIncomeaccounts[i].incomeAccountId
                    }
                    scope.penaltyToIncomeAccountMappings.push(temp);
                }

                for (var i in scope.charges) {
                    temp = {
                        id: scope.charges[i].id
                    }
                    scope.chargesSelected.push(temp);
                }

                if(scope.allowAttributeConfiguration == false){
                    scope.amortization = false;
                    scope.arrearsTolerance = false;
                    scope.graceOnArrearsAging = false;
                    scope.interestCalcPeriod = false;
                    scope.interestMethod = false;
                    scope.graceOnPrincipalAndInterest = false;
                    scope.repaymentFrequency = false;
                    scope.transactionProcessingStrategy = false;
                }

                scope.selectedConfigurableAttributes =
                {amortizationType:scope.amortization,
                    interestType:scope.interestMethod,
                    transactionProcessingStrategyId:scope.transactionProcessingStrategy,
                    interestCalculationPeriodType:scope.interestCalcPeriod,
                    inArrearsTolerance:scope.arrearsTolerance,
                    repaymentEvery:scope.repaymentFrequency,
                    graceOnPrincipalAndInterestPayment:scope.graceOnPrincipalAndInterest,
                    graceOnArrearsAgeing:scope.graceOnArrearsAging};

                this.formData.paymentChannelToFundSourceMappings = scope.paymentChannelToFundSourceMappings;
                this.formData.feeToIncomeAccountMappings = scope.feeToIncomeAccountMappings;
                this.formData.penaltyToIncomeAccountMappings = scope.penaltyToIncomeAccountMappings;
                this.formData.charges = scope.chargesSelected;
                this.formData.allowAttributeOverrides = scope.selectedConfigurableAttributes;
                this.formData.locale = scope.optlang.code;
                this.formData.dateFormat = scope.df;
                this.formData.startDate = reqFirstDate;
                this.formData.closeDate = reqSecondDate;

                //Interest recalculation data
                if (this.formData.isInterestRecalculationEnabled) {
                    var restFrequencyDate = dateFilter(scope.date.recalculationRestFrequencyDate, scope.df);
                    scope.formData.recalculationRestFrequencyDate = restFrequencyDate;
                    var compoundingFrequencyDate = dateFilter(scope.date.recalculationCompoundingFrequencyDate, scope.df);
                    scope.formData.recalculationCompoundingFrequencyDate = compoundingFrequencyDate;
                }else{
                    delete scope.formData.interestRecalculationCompoundingMethod;
                    delete scope.formData.rescheduleStrategyMethod;
                    delete scope.formData.recalculationRestFrequencyType;
                    delete scope.formData.recalculationRestFrequencyInterval;
                }

                if(this.formData.isLinkedToFloatingInterestRates) {
                    delete scope.formData.interestRatePerPeriod ;
                    delete scope.formData.minInterestRatePerPeriod ;
                    delete scope.formData.maxInterestRatePerPeriod ;
                    delete scope.formData.interestRateFrequencyType ;
                }else {
                    delete scope.formData.floatingRatesId ;
                    delete scope.formData.interestRateDifferential ;
                    delete scope.formData.isFloatingInterestRateCalculationAllowed ;
                    delete scope.formData.minDifferentialLendingRate ;
                    delete scope.formData.defaultDifferentialLendingRate ;
                    delete scope.formData.maxDifferentialLendingRate ;

                }
                //If Variable Installments is not allowed for this product, remove the corresponding formData
                if(!this.formData.allowVariableInstallments) {
                    delete scope.formData.minimumGap ;
                    delete scope.formData.maximumGap ;
                }

                if(this.formData.interestCalculationPeriodType == 0){
                    this.formData.allowPartialPeriodInterestCalcualtion = false;
                }

                resourceFactory.loanProductResource.save(this.formData, function (data) {
                    location.path('/viewloanproduct/' + data.resourceId);
                });
            };
        }
    });
    mifosX.ng.application.controller('CreateLoanProductController', ['$scope', 'ResourceFactory', '$location', 'dateFilter', mifosX.controllers.CreateLoanProductController]).run(function ($log) {
        $log.info("CreateLoanProductController initialized");
    });
}(mifosX.controllers || {}));
<commit_msg>resolving loading cause issue because of createloanproductcontroller<commit_after>(function (module) {
    mifosX.controllers = _.extend(module, {
        CreateLoanProductController: function (scope, resourceFactory, location, dateFilter) {
            scope.restrictDate = new Date();
            scope.formData = {};
            scope.charges = [];
            scope.floatingrateoptions = [];
            scope.loanProductConfigurableAttributes = [];
            scope.showOrHideValue = "show";
            scope.configureFundOptions = [];
            scope.specificIncomeAccountMapping = [];
            scope.penaltySpecificIncomeaccounts = [];
            scope.configureFundOption = {};
            scope.date = {};
            scope.pvFlag = false;
            scope.rvFlag = false;
            scope.irFlag = false;
            scope.chargeFlag = false;
            scope.penalityFlag = false;
            scope.frFlag = false;
            scope.fiFlag = false;
            scope.piFlag = false;
            scope.amortization = true;
            scope.arrearsTolerance = true;
            scope.graceOnArrearsAging = true;
            scope.interestCalcPeriod = true;
            scope.interestMethod = true;
            scope.graceOnPrincipalAndInterest = true;
            scope.repaymentFrequency = true;
            scope.transactionProcessingStrategy = true;
            scope.allowAttributeConfiguration = true;
            resourceFactory.loanProductResource.get({resourceType: 'template'}, function (data) {
                scope.product = data;
                scope.assetAccountOptions = scope.product.accountingMappingOptions.assetAccountOptions || [];
                scope.incomeAccountOptions = scope.product.accountingMappingOptions.incomeAccountOptions || [];
                scope.expenseAccountOptions = scope.product.accountingMappingOptions.expenseAccountOptions || [];
                scope.liabilityAccountOptions = scope.product.accountingMappingOptions.liabilityAccountOptions || [];
                scope.incomeAndLiabilityAccountOptions = scope.incomeAccountOptions.concat(scope.liabilityAccountOptions);
                scope.penaltyOptions = scope.product.penaltyOptions || [];
                scope.chargeOptions = scope.product.chargeOptions || [];
                scope.overduecharges = [];
                for (var i in scope.penaltyOptions) {
                    if (scope.penaltyOptions[i].chargeTimeType.code == 'chargeTimeType.overdueInstallment') {
                        scope.overduecharges.push(scope.penaltyOptions[i]);
                    }
                }
                scope.formData.currencyCode = scope.product.currencyOptions[0].code;
                scope.formData.includeInBorrowerCycle = 'false';
                scope.formData.useBorrowerCycle = 'false';
                scope.formData.digitsAfterDecimal = '2';
                scope.formData.inMultiplesOf = '0';
                scope.formData.repaymentFrequencyType = scope.product.repaymentFrequencyType.id;
                scope.formData.interestRateFrequencyType = scope.product.interestRateFrequencyType.id;
                scope.formData.amortizationType = scope.product.amortizationType.id;
                scope.formData.interestType = scope.product.interestType.id;
                scope.formData.interestCalculationPeriodType = scope.product.interestCalculationPeriodType.id;
                scope.formData.transactionProcessingStrategyId = scope.product.transactionProcessingStrategyOptions[0].id;
                scope.formData.principalVariationsForBorrowerCycle = scope.product.principalVariationsForBorrowerCycle;
                scope.formData.interestRateVariationsForBorrowerCycle = scope.product.interestRateVariationsForBorrowerCycle;
                scope.formData.numberOfRepaymentVariationsForBorrowerCycle = scope.product.numberOfRepaymentVariationsForBorrowerCycle;
                scope.formData.multiDisburseLoan = 'false';
                scope.formData.accountingRule = '1';
                scope.formData.daysInYearType = scope.product.daysInYearType.id;
                scope.formData.daysInMonthType = scope.product.daysInMonthType.id;
                scope.formData.isInterestRecalculationEnabled = scope.product.isInterestRecalculationEnabled;
                scope.formData.interestRecalculationCompoundingMethod = scope.product.interestRecalculationData.interestRecalculationCompoundingType.id;
                scope.formData.rescheduleStrategyMethod = scope.product.interestRecalculationData.rescheduleStrategyType.id;
                scope.formData.preClosureInterestCalculationStrategy = scope.product.interestRecalculationData.preClosureInterestCalculationStrategy.id;
                if(scope.product.interestRecalculationData.recalculationRestFrequencyType){
                    scope.formData.recalculationRestFrequencyType = scope.product.interestRecalculationData.recalculationRestFrequencyType.id;
                }
                scope.floatingRateOptions = data.floatingRateOptions ;
                scope.formData.isFloatingInterestRateCalculationAllowed = false ;
                scope.formData.isLinkedToFloatingInterestRates = false ;
                scope.formData.allowVariableInstallments = false ;
            });

            scope.chargeSelected = function (chargeId) {

                if (chargeId) {
                    resourceFactory.chargeResource.get({chargeId: chargeId, template: 'true'}, this.formData, function (data) {
                        data.chargeId = data.id;
                        scope.charges.push(data);
                        //to charge select box empty

                        if (data.penalty) {
                            scope.penalityFlag = true;
                            scope.penalityId = '';
                        } else {
                            scope.chargeFlag = true;
                            scope.chargeId = '';
                        }
                    });
                }
            };

            scope.deleteCharge = function (index) {
                scope.charges.splice(index, 1);
            };

            //advanced accounting rule
            scope.showOrHide = function (showOrHideValue) {

                if (showOrHideValue == "show") {
                    scope.showOrHideValue = 'hide';
                }

                if (showOrHideValue == "hide") {
                    scope.showOrHideValue = 'show';
                }
            };

            scope.addConfigureFundSource = function () {
                scope.frFlag = true;
                scope.configureFundOptions.push({
                    paymentTypeId: scope.product.paymentTypeOptions.length > 0 ? scope.product.paymentTypeOptions[0].id : '',
                    fundSourceAccountId: scope.assetAccountOptions.length > 0 ? scope.assetAccountOptions[0].id : '',
                    paymentTypeOptions: scope.product.paymentTypeOptions.length > 0 ? scope.product.paymentTypeOptions : [],
                    assetAccountOptions: scope.assetAccountOptions.length > 0 ? scope.assetAccountOptions : []
                });
            };

            scope.mapFees = function () {
                scope.fiFlag = true;
                scope.specificIncomeAccountMapping.push({
                    chargeId: scope.chargeOptions.length > 0 ? scope.chargeOptions[0].id : '',
                    incomeAccountId: scope.incomeAndLiabilityAccountOptions.length > 0 ? scope.incomeAndLiabilityAccountOptions[0].id : ''
                });
            };

            scope.addPrincipalVariation = function () {
                scope.pvFlag = true;
                scope.formData.principalVariationsForBorrowerCycle.push({
                    valueConditionType: scope.product.valueConditionTypeOptions[0].id
                });
            };
            scope.addInterestRateVariation = function () {
                scope.irFlag = true;
                scope.formData.interestRateVariationsForBorrowerCycle.push({
                    valueConditionType: scope.product.valueConditionTypeOptions[0].id
                });
            };
            scope.addNumberOfRepaymentVariation = function () {
                scope.rvFlag = true;
                scope.formData.numberOfRepaymentVariationsForBorrowerCycle.push({
                    valueConditionType: scope.product.valueConditionTypeOptions[0].id
                });
            };

            scope.mapPenalty = function () {
                scope.piFlag = true;
                scope.penaltySpecificIncomeaccounts.push({
                    chargeId: scope.penaltyOptions.length > 0 ? scope.penaltyOptions[0].id : '',
                    incomeAccountId: scope.incomeAccountOptions.length > 0 ? scope.incomeAccountOptions[0].id : ''
                });
            };

            scope.deleteFund = function (index) {
                scope.configureFundOptions.splice(index, 1);
            };

            scope.deleteFee = function (index) {
                scope.specificIncomeAccountMapping.splice(index, 1);
            };

            scope.deletePenalty = function (index) {
                scope.penaltySpecificIncomeaccounts.splice(index, 1);
            };

            scope.deletePrincipalVariation = function (index) {
                scope.formData.principalVariationsForBorrowerCycle.splice(index, 1);
            };

            scope.deleteInterestRateVariation = function (index) {
                scope.formData.interestRateVariationsForBorrowerCycle.splice(index, 1);
            };

            scope.deleterepaymentVariation = function (index) {
                scope.formData.numberOfRepaymentVariationsForBorrowerCycle.splice(index, 1);
            };

            scope.cancel = function () {
                location.path('/loanproducts');
            };

            scope.isAccountingEnabled = function () {
                if (scope.formData.accountingRule == 2 || scope.formData.accountingRule == 3 || scope.formData.accountingRule == 4) {
                    return true;
                }
                return false;
            }

            scope.isAccrualAccountingEnabled = function () {
                if (scope.formData.accountingRule == 3 || scope.formData.accountingRule == 4) {
                    return true;
                }
                return false;
            }
            scope.setAttributeValues = function(){
                if(scope.allowAttributeConfiguration == false){
                    scope.amortization = false;
                    scope.arrearsTolerance = false;
                    scope.graceOnArrearsAging = false;
                    scope.interestCalcPeriod = false;
                    scope.interestMethod = false;
                    scope.graceOnPrincipalAndInterest = false;
                    scope.repaymentFrequency = false;
                    scope.transactionProcessingStrategy = false;
                }
            }

	    scope.filterCharges = function(currencyCode, multiDisburseLoan) {
		return function (item) {
			if ((multiDisburseLoan != true) && item.chargeTimeType.id == 12) {
				return false;
			}
			if (item.currency.code != currencyCode) {
				return false;
			}
			return true;
		};
	    };

            scope.submit = function () {
                var reqFirstDate = dateFilter(scope.date.first, scope.df);
                var reqSecondDate = dateFilter(scope.date.second, scope.df);
                scope.paymentChannelToFundSourceMappings = [];
                scope.feeToIncomeAccountMappings = [];
                scope.penaltyToIncomeAccountMappings = [];
                scope.chargesSelected = [];
                scope.selectedConfigurableAttributes = [];

                var temp = '';

                //configure fund sources for payment channels
                for (var i in scope.configureFundOptions) {
                    temp = {
                        paymentTypeId: scope.configureFundOptions[i].paymentTypeId,
                        fundSourceAccountId: scope.configureFundOptions[i].fundSourceAccountId
                    }
                    scope.paymentChannelToFundSourceMappings.push(temp);
                }

                //map fees to specific income accounts
                for (var i in scope.specificIncomeAccountMapping) {
                    temp = {
                        chargeId: scope.specificIncomeAccountMapping[i].chargeId,
                        incomeAccountId: scope.specificIncomeAccountMapping[i].incomeAccountId
                    }
                    scope.feeToIncomeAccountMappings.push(temp);
                }

                //map penalties to specific income accounts
                for (var i in scope.penaltySpecificIncomeaccounts) {
                    temp = {
                        chargeId: scope.penaltySpecificIncomeaccounts[i].chargeId,
                        incomeAccountId: scope.penaltySpecificIncomeaccounts[i].incomeAccountId
                    }
                    scope.penaltyToIncomeAccountMappings.push(temp);
                }

                for (var i in scope.charges) {
                    temp = {
                        id: scope.charges[i].id
                    }
                    scope.chargesSelected.push(temp);
                }

                if(scope.allowAttributeConfiguration == false){
                    scope.amortization = false;
                    scope.arrearsTolerance = false;
                    scope.graceOnArrearsAging = false;
                    scope.interestCalcPeriod = false;
                    scope.interestMethod = false;
                    scope.graceOnPrincipalAndInterest = false;
                    scope.repaymentFrequency = false;
                    scope.transactionProcessingStrategy = false;
                }

                scope.selectedConfigurableAttributes =
                {amortizationType:scope.amortization,
                    interestType:scope.interestMethod,
                    transactionProcessingStrategyId:scope.transactionProcessingStrategy,
                    interestCalculationPeriodType:scope.interestCalcPeriod,
                    inArrearsTolerance:scope.arrearsTolerance,
                    repaymentEvery:scope.repaymentFrequency,
                    graceOnPrincipalAndInterestPayment:scope.graceOnPrincipalAndInterest,
                    graceOnArrearsAgeing:scope.graceOnArrearsAging};

                this.formData.paymentChannelToFundSourceMappings = scope.paymentChannelToFundSourceMappings;
                this.formData.feeToIncomeAccountMappings = scope.feeToIncomeAccountMappings;
                this.formData.penaltyToIncomeAccountMappings = scope.penaltyToIncomeAccountMappings;
                this.formData.charges = scope.chargesSelected;
                this.formData.allowAttributeOverrides = scope.selectedConfigurableAttributes;
                this.formData.locale = scope.optlang.code;
                this.formData.dateFormat = scope.df;
                this.formData.startDate = reqFirstDate;
                this.formData.closeDate = reqSecondDate;

                //Interest recalculation data
                if (this.formData.isInterestRecalculationEnabled) {
                    var restFrequencyDate = dateFilter(scope.date.recalculationRestFrequencyDate, scope.df);
                    scope.formData.recalculationRestFrequencyDate = restFrequencyDate;
                    var compoundingFrequencyDate = dateFilter(scope.date.recalculationCompoundingFrequencyDate, scope.df);
                    scope.formData.recalculationCompoundingFrequencyDate = compoundingFrequencyDate;
                }else{
                    delete scope.formData.interestRecalculationCompoundingMethod;
                    delete scope.formData.rescheduleStrategyMethod;
                    delete scope.formData.recalculationRestFrequencyType;
                    delete scope.formData.recalculationRestFrequencyInterval;
                }

                if(this.formData.isLinkedToFloatingInterestRates) {
                    delete scope.formData.interestRatePerPeriod ;
                    delete scope.formData.minInterestRatePerPeriod ;
                    delete scope.formData.maxInterestRatePerPeriod ;
                    delete scope.formData.interestRateFrequencyType ;
                }else {
                    delete scope.formData.floatingRatesId ;
                    delete scope.formData.interestRateDifferential ;
                    delete scope.formData.isFloatingInterestRateCalculationAllowed ;
                    delete scope.formData.minDifferentialLendingRate ;
                    delete scope.formData.defaultDifferentialLendingRate ;
                    delete scope.formData.maxDifferentialLendingRate ;

                }
                //If Variable Installments is not allowed for this product, remove the corresponding formData
                if(!this.formData.allowVariableInstallments) {
                    delete scope.formData.minimumGap ;
                    delete scope.formData.maximumGap ;
                }

                if(this.formData.interestCalculationPeriodType == 0){
                    this.formData.allowPartialPeriodInterestCalcualtion = false;
                }

                resourceFactory.loanProductResource.save(this.formData, function (data) {
                    location.path('/viewloanproduct/' + data.resourceId);
                });
            };
        }
    });
    mifosX.ng.application.controller('CreateLoanProductController', ['$scope', 'ResourceFactory', '$location', 'dateFilter', mifosX.controllers.CreateLoanProductController]).run(function ($log) {
        $log.info("CreateLoanProductController initialized");
    });
}(mifosX.controllers || {}));
<|endoftext|>


<commit_before>/*
  by @bordignon
  October 2013
  You can do what you want with the code as long as you provide attribution back to me and don�t hold me liable.

  An example of using the MQTT javascript library, websockets and chrome extensions.
  This extension will connect to a MQTT broker using websockets and then subscribe to a topic.
  When a message is received it will then display the notification using chrome's built-in notifications function.

  Requires "notifications" permission.
*/

// SETTINGS BEGIN HERE
var broker = "test.mosquitto.org"; //broker websocket address
var broker_port = 80; //broker websocket port
var subtopic = "/test/helloworld" //topic to subscribe to
//SETTINGS END HERE

function connect() {
  client = new Messaging.Client(broker, broker_port, "myclientid_" + parseInt(Math.random() * 100, 10)); // connect to broker, uses random clientid
  client.onConnectionLost = onConnectionLost;
  client.onMessageArrived = onMessageArrived;
  client.connect({onSuccess:onConnect});
}

function onConnect() {
  // Once a connection has been made, make a subscription and send a message.
  console.log("onConnect");
  client.subscribe(subtopic);
  chrome.browserAction.setIcon({path:"icon.png"})

  //uncomment the below if you want to publish to a topic on connect
  //message = new Messaging.Message("Hello");
  //message.destinationName = "/World";
  //client.send(message);
};

function onConnectionLost(responseObject) {
  if (responseObject.errorCode !== 0)
    console.log("onConnectionLost:"+responseObject.errorMessage);
    chrome.browserAction.setIcon({path:"icon_noconnection.png"})
    alert("Connection failed: " + responseObject.errorMessage);
};

function onMessageArrived(message) {
  //console.log("onMessageArrived:"+message.destinationName + " " + message.payloadString);
  var havePermission = window.webkitNotifications.checkPermission();
	if (havePermission == 0) {
	// 0 is PERMISSION_ALLOWED
	var notification = window.webkitNotifications.createNotification(
	  'https://si0.twimg.com/profile_images/1512652562/mqtticon-large_bigger.png',
	  'Topic: '+message.destinationName,
	  'Message: '+message.payloadString
	);
	notification.show();
	} else {
	  window.webkitNotifications.requestPermission();
	};

};

// Test for notification support.
if (window.webkitNotifications) {

  connect();

}
<commit_msg>added in the notification window timeout<commit_after>/*
  by @bordignon
  October 2013
  You can do what you want with the code as long as you provide attribution back to me and don�t hold me liable.

  An example of using the MQTT javascript library, websockets and chrome extensions.
  This extension will connect to a MQTT broker using websockets and then subscribe to a topic.
  When a message is received it will then display the notification using chrome's built-in notifications function.

  Requires "notifications" permission.
*/

// SETTINGS BEGIN HERE
var broker = "test.mosquitto.org"; //broker websocket address
var broker_port = 80; //broker websocket port
var subtopic = "/test/helloworld" //topic to subscribe to

var notifyTimeout = 60 //notification window timeout in seconds
//SETTINGS END HERE

function connect() {
  client = new Messaging.Client(broker, broker_port, "myclientid_" + parseInt(Math.random() * 100, 10)); // connect to broker, uses random clientid
  client.onConnectionLost = onConnectionLost;
  client.onMessageArrived = onMessageArrived;
  client.connect({onSuccess:onConnect});
}

function onConnect() {
  // Once a connection has been made, make a subscription and send a message.
  console.log("onConnect");
  client.subscribe(subtopic);
  chrome.browserAction.setIcon({path:"icon.png"})

  //uncomment the below if you want to publish to a topic on connect
  //message = new Messaging.Message("Hello");
  //message.destinationName = "/World";
  //client.send(message);
};

function onConnectionLost(responseObject) {
  if (responseObject.errorCode !== 0)
    console.log("onConnectionLost:"+responseObject.errorMessage);
    chrome.browserAction.setIcon({path:"icon_noconnection.png"})
    alert("Connection failed, reload plugin to reconnect: " + responseObject.errorMessage);
};

function onMessageArrived(message) {
  //console.log("onMessageArrived:"+message.destinationName + " " + message.payloadString);
  var havePermission = window.webkitNotifications.checkPermission();
	if (havePermission == 0) {
	// 0 is PERMISSION_ALLOWED
	var notification = window.webkitNotifications.createNotification(
	  'https://si0.twimg.com/profile_images/1512652562/mqtticon-large_bigger.png',
	  'Topic: '+message.destinationName,
	  'Message: '+message.payloadString
	);
	notification.show();
	setTimeout( function() { notification.cancel(); }, notifyTimeout * 1000 ); //notification window timeout
	} else {
	  window.webkitNotifications.requestPermission();
	};

};

// Test for notification support.
if (window.webkitNotifications) {
  //if support, let's conenct to the broker
  connect();

}
<|endoftext|>


<commit_before>/*
 * Namespace: lb.base.dom.factory
 * DOM (Document Object Model) Factory, Adapter Module for Base Library
 *
 * This module provides the base implementation of a factory to create DOM
 * elements, listeners and events. It is intended to be replaced with a custom
 * factory creating widgets on top of regular DOM elements for the support of
 * Rich Internet Applications.
 *
 * How to design a custom factory:
 * A custom factory is an object with the same methods defined in this module.
 * All the methods defined in the base factory must be supported by your
 * custom factory.
 *
 * The custom factory can be configured by calling setOptions on the
 * application core:
 * | lb.core.application.setOptions({ lbFactory: your.customFactory })
 *
 * To develop your own custom factory, you can start by creating a new module
 * as a closure assigned to your own namespace. You can then add all required
 * methods, just calling the same method in the base factory to use the default
 * implementation. You may find it handy to declare an alias for the base
 * factory at the start of your module:
 * | var baseFactory = lb.base.dom.factory;
 *
 * In addition to the mandatory methods defined by the base factory, you may
 * optionally support the initElement method, which is an extrat extension
 * point intended for use in custom factories:
 * o <initElement(element)>
 *
 * Author:
 * Eric Bréchemier <legalbox@eric.brechemier.name>
 *
 * Copyright:
 * Legal Box SAS (c) 2010, All Rights Reserved
 *
 * License:
 * BSD License
 * http://creativecommons.org/licenses/BSD/
 *
 * Version:
 * 2010-08-11
 */
/*requires lb.base.dom.js */
/*jslint white:false, plusplus:false */
/*global lb, goog */
// preserve the module, if already loaded
lb.base.dom.factory = lb.base.dom.factory || (function() {
  // Builder of
  // Closure for lb.base.dom.factory module

  // Declare aliases
      /*requires closure/goog.dom.js */
  var createDom = goog.dom.createDom,
      removeElement = goog.dom.removeNode,
      /*requires closure/goog.events.js */
      fireListeners = goog.events.fireListeners,
      Event = goog.events.Event,
      /*requires lb.base.dom.Listener.js */
      Listener = lb.base.dom.Listener,
      /*requires lb.base.array.js */
      toArray = lb.base.array.toArray;

  // Function: initElement(element)
  // (optional) Customize a newly inserted element.
  // Not implemented in the base factory.
  //
  // The method differs from createElement which is responsible for the
  // actual creation of the element node and is called before the node is
  // inserted in the DOM. On the contrary, this method will be called on
  // elements already part of the DOM.
  //
  // When available on the configured factory, this method is currently called
  // before a module starts, with the box element at the root of the module.
  // It is also intended to get called in a template engine, to be added in a
  // future version of the library, after inserting new contents in the box.
  //
  // A custom factory may, for example, iterate recursively on the children
  // of the given element, creating Rich Internet Application widgets when
  // expected CSS classes are found on an element.
  //
  // Parameter:
  //   element - DOM Element, an element part of the document.

  function createElement(name,attributes){
    // Function: createElement(name[,attributes[,childNodes]]): DOM Element
    // Create a new element with given name, attributes and child nodes.
    //
    // Parameters:
    //   name - string, the name of the element, e.g. 'div'
    //   attributes - object, the set of attributes,
    //                e.g. {id:'myDiv', 'class':'big box'}
    //   childNodes - array or list, the list of child nodes.
    //                The child nodes may be provided as an array,
    //                or as a list of arguments (after name and attributes).
    //
    // Returns:
    //   DOM Element, the newly created element

    // clone arguments before modifying - avoid changing function arguments
    // http://tech.groups.yahoo.com/group/jslint_com/message/11
    var args = toArray(arguments);

    // convert name to uppercase to ensure cross-browser consistency
    // (IE keeps original case for unknown nodeName/tagName)
    if (args[0] && args[0].toUpperCase){
      args[0] = args[0].toUpperCase();
    }

    return createDom.apply(this,args);
  }

  function destroyElement(element){
    // Function: destroyElement(element)
    // Terminate usage of a DOM element by removing it from its parent.
    //
    // Parameter:
    //   element - DOM element, an element (with or without parent)
    //
    // Note:
    // Nothing happens in case the element has no parent.

    removeElement(element);
  }

  function createListener(element, type, callback, useCapture){
    // Function: createListener(element, type, callback[, useCapture])
    // Create a new listener for a type of event on a DOM element.
    //
    // Parameters:
    //   element - DOM Element, an element
    //   type - string, the name of an event (without 'on') e.g. 'click'
    //   callback - function, a function to call when the event is dispatched.
    //   useCapture - boolean, whether the callback is set for capture phase.
    //                Optional: defaults to false. See [1] for details.
    //
    // Returns:
    //   object, a new instance of <lb.base.dom.Listener>
    //
    // Reference:
    //   [1] DOM Level 2 Events: addEventListener
    //   <http://bit.ly/9SQoL4>

    return new Listener(element, type, callback, useCapture);
  }

  function destroyListener(listener){
    // Function: destroyListener(listener)
    // Terminate a listener by removing it from the target DOM element.
    //
    // Parameter:
    //   listener - object, the listener returned by createListener,
    //              instance of <lb.base.dom.Listener>

    listener.detach();
  }

  function createEvent(element, type, properties, useCapture){
    // Function: createEvent(element, type[, properties[, useCapture]])
    // Create a new DOM event and fire it on given target element.
    //
    // Parameters:
    //   element - DOM element, the target element for the event dispatch
    //   type - string, the name of an event (without 'on') e.g. 'click'
    //   properties - object, optional properties to set to the new event.
    //   useCapture - boolean, whether the callback is set for capture phase.
    //                Optional: defaults to false. See [1] for details.
    //
    // Returns:
    //   object, the new DOM Event [2] created
    //
    // References:
    //   [1] DOM Level 2 Events: addEventListener
    //   <http://bit.ly/9SQoL4>
    //
    //   [2] DOM Level 2 Events: Event interface
    //   <http://bit.ly/b7KwF5>
    useCapture = useCapture || false;

    // Note: event is actually an instance of goog.events.Event.
    // We may define our own wrapper instead if needed.
    var event = new Event(type),
        name;
    for (name in properties){
      if ( properties.hasOwnProperty(name) ){
        event[name] = properties[name];
      }
    }
    fireListeners(element,type,useCapture,event);
    return event;
  }

  function destroyEvent(event){
    // Function: destroyEvent(event)
    // Terminate a DOM event: prevent default action and stop propagation.
    //
    // Nothing happens in case the event is undefined, or lacks both of the
    // expected stopPropagation() and preventDefault() methods. In case only
    // one of the methods is missing, the other will get called.
    //
    // Parameter:
    //   event - object, the DOM Event [1]
    //
    // Reference:
    //   [1] DOM Level 2 Events: Event interface
    //   <http://bit.ly/b7KwF5>
    if (!event){
      return;
    }

    if (event.stopPropagation){
      event.stopPropagation();
    }

    if (event.preventDefault){
      event.preventDefault();
    }
  }

  return { // public API
    createElement: createElement,
    destroyElement: destroyElement,
    createListener: createListener,
    destroyListener: destroyListener,
    createEvent: createEvent,
    destroyEvent: destroyEvent
  };
}());
<commit_msg>Fixed typo in documentation<commit_after>/*
 * Namespace: lb.base.dom.factory
 * DOM (Document Object Model) Factory, Adapter Module for Base Library
 *
 * This module provides the base implementation of a factory to create DOM
 * elements, listeners and events. It is intended to be replaced with a custom
 * factory creating widgets on top of regular DOM elements for the support of
 * Rich Internet Applications.
 *
 * How to design a custom factory:
 * A custom factory is an object with the same methods defined in this module.
 * All the methods defined in the base factory must be supported by your
 * custom factory.
 *
 * The custom factory can be configured by calling setOptions on the
 * application core:
 * | lb.core.application.setOptions({ lbFactory: your.customFactory })
 *
 * To develop your own custom factory, you can start by creating a new module
 * as a closure assigned to your own namespace. You can then add all required
 * methods, just calling the same method in the base factory to use the default
 * implementation. You may find it handy to declare an alias for the base
 * factory at the start of your module:
 * | var baseFactory = lb.base.dom.factory;
 *
 * In addition to the mandatory methods defined by the base factory, you may
 * optionally support the initElement method, which is an extra extension
 * point intended for use in custom factories:
 * o <initElement(element)>
 *
 * Author:
 * Eric Bréchemier <legalbox@eric.brechemier.name>
 *
 * Copyright:
 * Legal Box SAS (c) 2010, All Rights Reserved
 *
 * License:
 * BSD License
 * http://creativecommons.org/licenses/BSD/
 *
 * Version:
 * 2010-09-24
 */
/*requires lb.base.dom.js */
/*jslint white:false, plusplus:false */
/*global lb, goog */
// preserve the module, if already loaded
lb.base.dom.factory = lb.base.dom.factory || (function() {
  // Builder of
  // Closure for lb.base.dom.factory module

  // Declare aliases
      /*requires closure/goog.dom.js */
  var createDom = goog.dom.createDom,
      removeElement = goog.dom.removeNode,
      /*requires closure/goog.events.js */
      fireListeners = goog.events.fireListeners,
      Event = goog.events.Event,
      /*requires lb.base.dom.Listener.js */
      Listener = lb.base.dom.Listener,
      /*requires lb.base.array.js */
      toArray = lb.base.array.toArray;

  // Function: initElement(element)
  // (optional) Customize a newly inserted element.
  // Not implemented in the base factory.
  //
  // The method differs from createElement which is responsible for the
  // actual creation of the element node and is called before the node is
  // inserted in the DOM. On the contrary, this method will be called on
  // elements already part of the DOM.
  //
  // When available on the configured factory, this method is currently called
  // before a module starts, with the box element at the root of the module.
  // It is also intended to get called in a template engine, to be added in a
  // future version of the library, after inserting new contents in the box.
  //
  // A custom factory may, for example, iterate recursively on the children
  // of the given element, creating Rich Internet Application widgets when
  // expected CSS classes are found on an element.
  //
  // Parameter:
  //   element - DOM Element, an element part of the document.

  function createElement(name,attributes){
    // Function: createElement(name[,attributes[,childNodes]]): DOM Element
    // Create a new element with given name, attributes and child nodes.
    //
    // Parameters:
    //   name - string, the name of the element, e.g. 'div'
    //   attributes - object, the set of attributes,
    //                e.g. {id:'myDiv', 'class':'big box'}
    //   childNodes - array or list, the list of child nodes.
    //                The child nodes may be provided as an array,
    //                or as a list of arguments (after name and attributes).
    //
    // Returns:
    //   DOM Element, the newly created element

    // clone arguments before modifying - avoid changing function arguments
    // http://tech.groups.yahoo.com/group/jslint_com/message/11
    var args = toArray(arguments);

    // convert name to uppercase to ensure cross-browser consistency
    // (IE keeps original case for unknown nodeName/tagName)
    if (args[0] && args[0].toUpperCase){
      args[0] = args[0].toUpperCase();
    }

    return createDom.apply(this,args);
  }

  function destroyElement(element){
    // Function: destroyElement(element)
    // Terminate usage of a DOM element by removing it from its parent.
    //
    // Parameter:
    //   element - DOM element, an element (with or without parent)
    //
    // Note:
    // Nothing happens in case the element has no parent.

    removeElement(element);
  }

  function createListener(element, type, callback, useCapture){
    // Function: createListener(element, type, callback[, useCapture])
    // Create a new listener for a type of event on a DOM element.
    //
    // Parameters:
    //   element - DOM Element, an element
    //   type - string, the name of an event (without 'on') e.g. 'click'
    //   callback - function, a function to call when the event is dispatched.
    //   useCapture - boolean, whether the callback is set for capture phase.
    //                Optional: defaults to false. See [1] for details.
    //
    // Returns:
    //   object, a new instance of <lb.base.dom.Listener>
    //
    // Reference:
    //   [1] DOM Level 2 Events: addEventListener
    //   <http://bit.ly/9SQoL4>

    return new Listener(element, type, callback, useCapture);
  }

  function destroyListener(listener){
    // Function: destroyListener(listener)
    // Terminate a listener by removing it from the target DOM element.
    //
    // Parameter:
    //   listener - object, the listener returned by createListener,
    //              instance of <lb.base.dom.Listener>

    listener.detach();
  }

  function createEvent(element, type, properties, useCapture){
    // Function: createEvent(element, type[, properties[, useCapture]])
    // Create a new DOM event and fire it on given target element.
    //
    // Parameters:
    //   element - DOM element, the target element for the event dispatch
    //   type - string, the name of an event (without 'on') e.g. 'click'
    //   properties - object, optional properties to set to the new event.
    //   useCapture - boolean, whether the callback is set for capture phase.
    //                Optional: defaults to false. See [1] for details.
    //
    // Returns:
    //   object, the new DOM Event [2] created
    //
    // References:
    //   [1] DOM Level 2 Events: addEventListener
    //   <http://bit.ly/9SQoL4>
    //
    //   [2] DOM Level 2 Events: Event interface
    //   <http://bit.ly/b7KwF5>
    useCapture = useCapture || false;

    // Note: event is actually an instance of goog.events.Event.
    // We may define our own wrapper instead if needed.
    var event = new Event(type),
        name;
    for (name in properties){
      if ( properties.hasOwnProperty(name) ){
        event[name] = properties[name];
      }
    }
    fireListeners(element,type,useCapture,event);
    return event;
  }

  function destroyEvent(event){
    // Function: destroyEvent(event)
    // Terminate a DOM event: prevent default action and stop propagation.
    //
    // Nothing happens in case the event is undefined, or lacks both of the
    // expected stopPropagation() and preventDefault() methods. In case only
    // one of the methods is missing, the other will get called.
    //
    // Parameter:
    //   event - object, the DOM Event [1]
    //
    // Reference:
    //   [1] DOM Level 2 Events: Event interface
    //   <http://bit.ly/b7KwF5>
    if (!event){
      return;
    }

    if (event.stopPropagation){
      event.stopPropagation();
    }

    if (event.preventDefault){
      event.preventDefault();
    }
  }

  return { // public API
    createElement: createElement,
    destroyElement: destroyElement,
    createListener: createListener,
    destroyListener: destroyListener,
    createEvent: createEvent,
    destroyEvent: destroyEvent
  };
}());
<|endoftext|>


<commit_before><commit_msg>implements about routes for press and team<commit_after><|endoftext|>


<commit_before>define(
// Requirements
["lib/undo-manager", "lib/jquery"],

// Module definition
function (UndoManager) {

var Player = function (config) {

    var self = this;

    // Default configuration
    var defaultConfig = {
        x: 0,
        y: 0,
        bearing: [0, -1, 0, 1]
    };

    config = $.extend({}, defaultConfig, config);

    // Set up undo/redo
    var undoManager = new UndoManager();
    self.hasUndo = undoManager.hasUndo;
    self.hasRedo = undoManager.hasRedo;

    /**
     * Redo a previously undone action.
     */
    self.redo = function () {
        // TODO
    }

    /**
     * Undo a previously recorded action.
     */
    self.undo = function () {
        // TODO
    }

    // Define getters for x/y coords to make 'em easier to access.
    self.__defineGetter__("x", function () {
        return config.x;
    });
    self.__defineGetter__("y", function () {
        return config.y;
    });

    /**
     * Move the Player.  If no arguments are given, the player will be moved by
     * one tile in the direction of their current bearing.
     *
     * @param {Number} [x] - X position to move the Player to.
     * @param {Number} [y] - Y position to move the player to.
     * @param {Number} [bearing] - The new bearing for the user to face.
     *
     * @return Void
     */
    self.move = function (newX, newY, newBearing) {
        // Move the Player and store a copy of the data that is generated.
        var stepData = _movePlayer(newX, newY, newBearing);

        // TODO: Check redo stack to see if the requested movement is a copy of previously recorded action.

        // Add the movement action to the undo/redo stack.
        undoManager.add({
            undo: function () {
                _move(stepData.from.x, stepData.from.y);
            },
            redo: function () {
                _move(stepData.to.x, stepData.to.y);
            }
        });
    };

    /**
     * Private function to facilitate the actual movement logic.  Clients that
     * are external to the Player module will make use of this by calling
     * Player.move() on a Player instance.
     * @private
     */
    function _move (newX, newY, newBearing) {
        // Derive new values if necessary.
        newX = newX || config.bearing[0];
        newY = newY || config.bearing[1];
        newBearing = newBearing || config.bearing;

        var stepData = {
            from: {
                x: config.x,
                y: config.y,
                bearing: config.bearing
            },
            to: {
                x: newX,
                y: newY,
                bearing: newBearing
            },
        }

        // Update current values.
        config.x = newX;
        config.y = newY;
        self.bear(newBearing);

        return stepData;
    }

    /**
     * Return the player's current bearing as an Array where the indices
     * represent the x and y offset, respectively.
     */
    self.__defineGetter("bearing", function () {
        return [config.bearing[0], config.bearing[1]];
    });

    /**
     * Cause the player's bearing to shift 90 deg to the right.
     */
    self.bearRight = function () {
        var n = config.bearing.pop();
        config.bearing.unshift(n);
    };

    /**
     * Cause the player's bearing to shift 90 deg to the left.
     */
    self.bearLeft = function () {
        var n = config.bearing.shift();
        config.bearing.push(n);
    };
}

return Player;
});<commit_msg>Fix typo in player.js.<commit_after>define(
// Requirements
["lib/undo-manager", "lib/jquery"],

// Module definition
function (UndoManager) {

var Player = function (config) {

    var self = this;

    // Default configuration
    var defaultConfig = {
        x: 0,
        y: 0,
        bearing: [0, -1, 0, 1]
    };

    config = $.extend({}, defaultConfig, config);

    // Set up undo/redo
    var undoManager = new UndoManager();
    self.hasUndo = undoManager.hasUndo;
    self.hasRedo = undoManager.hasRedo;

    /**
     * Redo a previously undone action.
     */
    self.redo = function () {
        // TODO
    }

    /**
     * Undo a previously recorded action.
     */
    self.undo = function () {
        // TODO
    }

    // Define getters for x/y coords to make 'em easier to access.
    self.__defineGetter__("x", function () {
        return config.x;
    });
    self.__defineGetter__("y", function () {
        return config.y;
    });

    /**
     * Move the Player.  If no arguments are given, the player will be moved by
     * one tile in the direction of their current bearing.
     *
     * @param {Number} [x] - X position to move the Player to.
     * @param {Number} [y] - Y position to move the player to.
     * @param {Number} [bearing] - The new bearing for the user to face.
     *
     * @return Void
     */
    self.move = function (newX, newY, newBearing) {
        // Move the Player and store a copy of the data that is generated.
        var stepData = _movePlayer(newX, newY, newBearing);

        // TODO: Check redo stack to see if the requested movement is a copy of previously recorded action.

        // Add the movement action to the undo/redo stack.
        undoManager.add({
            undo: function () {
                _move(stepData.from.x, stepData.from.y);
            },
            redo: function () {
                _move(stepData.to.x, stepData.to.y);
            }
        });
    };

    /**
     * Private function to facilitate the actual movement logic.  Clients that
     * are external to the Player module will make use of this by calling
     * Player.move() on a Player instance.
     * @private
     */
    function _move (newX, newY, newBearing) {
        // Derive new values if necessary.
        newX = newX || config.bearing[0];
        newY = newY || config.bearing[1];
        newBearing = newBearing || config.bearing;

        var stepData = {
            from: {
                x: config.x,
                y: config.y,
                bearing: config.bearing
            },
            to: {
                x: newX,
                y: newY,
                bearing: newBearing
            },
        }

        // Update current values.
        config.x = newX;
        config.y = newY;
        self.bear(newBearing);

        return stepData;
    }

    /**
     * Return the player's current bearing as an Array where the indices
     * represent the x and y offset, respectively.
     */
    self.__defineGetter__("bearing", function () {
        return [config.bearing[0], config.bearing[1]];
    });

    /**
     * Cause the player's bearing to shift 90 deg to the right.
     */
    self.bearRight = function () {
        var n = config.bearing.pop();
        config.bearing.unshift(n);
    };

    /**
     * Cause the player's bearing to shift 90 deg to the left.
     */
    self.bearLeft = function () {
        var n = config.bearing.shift();
        config.bearing.push(n);
    };
}

return Player;
});<|endoftext|>


<commit_before>var canvas;
var canvasContext;
var image;
var animation = new ConvertingAnimation();
var loggedIn = false;
var restricted = false;
var error = '';
var pendingStatusRequest = false;

function ConvertingAnimation() {
    this.timerId_ = 0;
    this.imageXPos_ = 0;
}

ConvertingAnimation.prototype.paintFrame = function() {
    canvasContext.save();

    var imgHeight = canvas.height - 6;
    var imgWidth = canvas.width - this.imageXPos_;

    canvasContext.drawImage(image, 0, 0);
    canvasContext.drawImage(image, 0, 3, imgWidth, imgHeight, this.imageXPos_, 3, imgWidth, imgHeight);

    if (this.imageXPos_) {
        canvasContext.drawImage(
            image, 0, 3, canvas.width, imgHeight, -canvas.width + this.imageXPos_, 3, canvas.width, imgHeight);
    }

    canvasContext.restore();

    chrome.browserAction.setIcon({imageData: canvasContext.getImageData(0, 0, canvas.width, canvas.height)});
    this.imageXPos_ += 1;

    if (this.imageXPos_ >= canvas.width)
        this.imageXPos_ = 0;
}

ConvertingAnimation.prototype.start = function() {
    if (this.timerId_)
        return;

    var self = this;
    this.timerId_ = window.setInterval(function() {
        self.paintFrame();
    }, 100);
}

ConvertingAnimation.prototype.stop = function() {
    if (!this.timerId_)
        return;
    window.clearInterval(this.timerId_);
    this.timerId_ = 0;
    this.imageXPos_ = 0;
    showStaticIcon();
}

function showStaticIcon() {
    if (animation.timerId_ != 0) return;
    canvasContext.drawImage(image, 0, 0);
    drawLoggedIn();
    chrome.browserAction.setIcon({imageData: canvasContext.getImageData(0, 0, canvas.width, canvas.height)});
}

function updateBadgeAndTitle() {
    if (error) {
        chrome.browserAction.setTitle({title: error});
        chrome.browserAction.setBadgeText({text: 'ERR'});
        chrome.browserAction.setBadgeBackgroundColor({color:"#f00"});
    } else {
        var title = "Save as PDF - by pdfcrowd.com"
        chrome.browserAction.setTitle({title: title});
        chrome.browserAction.setBadgeText({text: ''});
    }
}

function showError(msg) {
    error = msg;
    updateBadgeAndTitle();
}

function clearError() {
    error = '';
    updateBadgeAndTitle();
}

function drawLoggedIn() {
    if (loggedIn && !restricted)
        return;

    canvasContext.save();
    canvasContext.fillStyle = "red";
    canvasContext.arc(15, 4, 2, 0, 2*Math.PI);
    canvasContext.fill();
    canvasContext.restore();
}

function updateLoggedIn(user) {
    loggedIn = user.authenticated;
    if (loggedIn)
        restricted = user.restricted;
    updateBadgeAndTitle();
    showStaticIcon();
}

function onDataReady(xhr, callbacks) {
    return function(data) {
        if (xhr.readyState == 4) {
            if (xhr.status == 200) {
                if (callbacks.onSuccess) {
                    try {
                        var data = JSON.parse(xhr.responseText);
                        callbacks.onSuccess(data);
                    } catch (e) {
                        showError("Conversion failed.");
                    }
                }
            } else {
                if (callbacks.onError)
                    callbacks.onError(xhr.responseText)
            }
            if (callbacks.onComplete)
                callbacks.onComplete();
        }
    };
}

function canRunConversion(tab) {
    var rex = /^((?:chrome|file|chrome-extension|about|moz-extension):.*$)/i;
    var result = rex.exec(tab.url);
    if (result) {
        showError("Conversion of local URLs is not supported (" + result[1] + ").");
        return false;
    }
    // is there an ongoing conversion?
    if (animation.timerId_ != 0) return false;

    return true;
}

function createPdf(tab, apiUrl) {

    clearError();

    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = onDataReady(xhr, {
        onSuccess: function(data) {
            if (data.status === 'ok') {
                chrome.tabs.update(tab.id, {url: data.url});
	        } else if (data.status === 'error') {
                showError(data.message);
            } else if (data.status === 'redirect') {
                      // tbd
            }
            updateLoggedIn(data.user);
        },

        onError: function(responseText) {
            try {
                var data = JSON.parse(xhr.responseText);
                var error = data.error || "Conversion failed."
                showError(error);
            } catch (e) {
                showError("Conversion failed.");
            }
        },

        onComplete: function() {
            animation.stop();
        }
    });

    xhr.open('POST', apiUrl, true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xhr.send("src=" + escape(tab.url));
};

function init() {

    var version = "1.10";
    //Show updated page first load
    if(localStorage.updatedToVersion && localStorage.updatedToVersion != version) {
        chrome.tabs.create( {url:"updated.html"} );
    }
    localStorage.updatedToVersion = version;

    image = document.getElementById("standard_icon")
    canvas = document.getElementById("canvas");
    canvasContext = canvas.getContext("2d");
    updateBadgeAndTitle();
    //findOutUserStatus();
}

var baseUrl = 'https://pdfcrowd.com'
var apiUrls = {
    1: baseUrl + '/session/json/convert/uri/',
    2: baseUrl + '/session/json/convert/uri/v2/'
}

var apiVersionUrl = baseUrl + '/session/api-version/'

chrome.browserAction.onClicked.addListener(function(tab) {
    if (!canRunConversion(tab)) {
        return;
    }

    animation.start();

    // find out the api version for the current user
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = onDataReady(xhr, {
        onSuccess: function(data) {
            var apiUrl = apiUrls[data.api_version];
            if (apiUrl === undefined) {
                apiUrl = apiUrls[2];
            }
            // create pdf
            createPdf(tab, apiUrl);
        },
        onError: function(responseText) {
            showError("Can't connect to Pdfcrowd");
            animation.stop();
        },
    });
    xhr.open('GET', apiVersionUrl, true);
    xhr.send(null);
});

init();
<commit_msg>do not convert wyciwyg: urls<commit_after>var canvas;
var canvasContext;
var image;
var animation = new ConvertingAnimation();
var loggedIn = false;
var restricted = false;
var error = '';
var pendingStatusRequest = false;

function ConvertingAnimation() {
    this.timerId_ = 0;
    this.imageXPos_ = 0;
}

ConvertingAnimation.prototype.paintFrame = function() {
    canvasContext.save();

    var imgHeight = canvas.height - 6;
    var imgWidth = canvas.width - this.imageXPos_;

    canvasContext.drawImage(image, 0, 0);
    canvasContext.drawImage(image, 0, 3, imgWidth, imgHeight, this.imageXPos_, 3, imgWidth, imgHeight);

    if (this.imageXPos_) {
        canvasContext.drawImage(
            image, 0, 3, canvas.width, imgHeight, -canvas.width + this.imageXPos_, 3, canvas.width, imgHeight);
    }

    canvasContext.restore();

    chrome.browserAction.setIcon({imageData: canvasContext.getImageData(0, 0, canvas.width, canvas.height)});
    this.imageXPos_ += 1;

    if (this.imageXPos_ >= canvas.width)
        this.imageXPos_ = 0;
}

ConvertingAnimation.prototype.start = function() {
    if (this.timerId_)
        return;

    var self = this;
    this.timerId_ = window.setInterval(function() {
        self.paintFrame();
    }, 100);
}

ConvertingAnimation.prototype.stop = function() {
    if (!this.timerId_)
        return;
    window.clearInterval(this.timerId_);
    this.timerId_ = 0;
    this.imageXPos_ = 0;
    showStaticIcon();
}

function showStaticIcon() {
    if (animation.timerId_ != 0) return;
    canvasContext.drawImage(image, 0, 0);
    drawLoggedIn();
    chrome.browserAction.setIcon({imageData: canvasContext.getImageData(0, 0, canvas.width, canvas.height)});
}

function updateBadgeAndTitle() {
    if (error) {
        chrome.browserAction.setTitle({title: error});
        chrome.browserAction.setBadgeText({text: 'ERR'});
        chrome.browserAction.setBadgeBackgroundColor({color:"#f00"});
    } else {
        var title = "Save as PDF - by pdfcrowd.com"
        chrome.browserAction.setTitle({title: title});
        chrome.browserAction.setBadgeText({text: ''});
    }
}

function showError(msg) {
    error = msg;
    updateBadgeAndTitle();
}

function clearError() {
    error = '';
    updateBadgeAndTitle();
}

function drawLoggedIn() {
    if (loggedIn && !restricted)
        return;

    canvasContext.save();
    canvasContext.fillStyle = "red";
    canvasContext.arc(15, 4, 2, 0, 2*Math.PI);
    canvasContext.fill();
    canvasContext.restore();
}

function updateLoggedIn(user) {
    loggedIn = user.authenticated;
    if (loggedIn)
        restricted = user.restricted;
    updateBadgeAndTitle();
    showStaticIcon();
}

function onDataReady(xhr, callbacks) {
    return function(data) {
        if (xhr.readyState == 4) {
            if (xhr.status == 200) {
                if (callbacks.onSuccess) {
                    try {
                        var data = JSON.parse(xhr.responseText);
                        callbacks.onSuccess(data);
                    } catch (e) {
                        showError("Conversion failed.");
                    }
                }
            } else {
                if (callbacks.onError)
                    callbacks.onError(xhr.responseText)
            }
            if (callbacks.onComplete)
                callbacks.onComplete();
        }
    };
}

function canRunConversion(tab) {
    var rex = /^((?:chrome|file|chrome-extension|about|moz-extension|wyciwyg):.*$)/i;
    var result = rex.exec(tab.url);
    if (result) {
        showError("Conversion of local URLs is not supported (" + result[1] + ").");
        return false;
    }
    // is there an ongoing conversion?
    if (animation.timerId_ != 0) return false;

    return true;
}

function createPdf(tab, apiUrl) {

    clearError();

    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = onDataReady(xhr, {
        onSuccess: function(data) {
            if (data.status === 'ok') {
                chrome.tabs.update(tab.id, {url: data.url});
	        } else if (data.status === 'error') {
                showError(data.message);
            } else if (data.status === 'redirect') {
                      // tbd
            }
            updateLoggedIn(data.user);
        },

        onError: function(responseText) {
            try {
                var data = JSON.parse(xhr.responseText);
                var error = data.error || "Conversion failed."
                showError(error);
            } catch (e) {
                showError("Conversion failed.");
            }
        },

        onComplete: function() {
            animation.stop();
        }
    });

    xhr.open('POST', apiUrl, true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xhr.send("src=" + escape(tab.url));
};

function init() {

    var version = "1.10";
    //Show updated page first load
    if(localStorage.updatedToVersion && localStorage.updatedToVersion != version) {
        chrome.tabs.create( {url:"updated.html"} );
    }
    localStorage.updatedToVersion = version;

    image = document.getElementById("standard_icon")
    canvas = document.getElementById("canvas");
    canvasContext = canvas.getContext("2d");
    updateBadgeAndTitle();
    //findOutUserStatus();
}

var baseUrl = 'https://pdfcrowd.com'
var apiUrls = {
    1: baseUrl + '/session/json/convert/uri/',
    2: baseUrl + '/session/json/convert/uri/v2/'
}

var apiVersionUrl = baseUrl + '/session/api-version/'

chrome.browserAction.onClicked.addListener(function(tab) {
    if (!canRunConversion(tab)) {
        return;
    }

    animation.start();

    // find out the api version for the current user
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = onDataReady(xhr, {
        onSuccess: function(data) {
            var apiUrl = apiUrls[data.api_version];
            if (apiUrl === undefined) {
                apiUrl = apiUrls[2];
            }
            // create pdf
            createPdf(tab, apiUrl);
        },
        onError: function(responseText) {
            showError("Can't connect to Pdfcrowd");
            animation.stop();
        },
    });
    xhr.open('GET', apiVersionUrl, true);
    xhr.send(null);
});

init();
<|endoftext|>