diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..cfdff80a5 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,16 @@ +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..9f2324cf2 --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +Apache Fineract: A Platform for Microfinance +====== + +The next evolution of fineract focussing being faster, lighter and cheaper to change (than existing mifos) so that it is more responsive to the needs of MFI’s and Integrators + +Build Status +============ + +Travis + +[![Build +Status](https://travis-ci.org/openMF/mifosx.png?branch=master)](https://travis-ci.org/openMF/mifosx) + +Cloudbees Jenkins + +[![Build +Status](https://openmf.ci.cloudbees.com/job/MIFOSX%20INTEGRATION%20TEST/badge/icon)](https://openmf.ci.cloudbees.com/job/MIFOSX%20INTEGRATION%20TEST/) + +Jenkins@CloudBees Unit + Integration Tests + + +Version +========== + +The API for the fineract-platform (project named 'Apache Fineract')is documented in the api-docs under Full API Matrix and can be viewed here + + +Latest stable release can always been viewed on master branch: Latest Release on Master, View change log + +License +============= + +This project is licensed under the open source MPL V2. See https://github.com/openMF/mifosx/blob/master/LICENSE.md + +Fineract Platform API +===================== + +API Documentation (Demo Server) + + +Online Demos +============================= + +* Community App +* ~~Reference Client App (Deprecated)~~ + +Developers +========== +see https://mifosforge.jira.com/wiki/display/MIFOSX/MifosX+Technical - Developers Wiki Page + +see https://mifosforge.jira.com/wiki/display/MIFOSX/Getting+started+-+Contributing+to+MifosX - Getting Started. + +see https://mifosforge.jira.com/wiki/display/MIFOSX/The+Basic+Design - Overview of Platform Implementation + +see https://github.com/openMF/mifosx/wiki/Screen-Based-Reporting for info around reporting + +see https://github.com/openMF/mifosx/wiki/Git-Usuage for info around using git + +see https://www.ohloh.net/p/mifosx for activity overview and basic code analysis. + +Roadmap +============== + +Community Roadmap (High Level) + +Project Release Roadmap on JIRA (Detailed View) + +Video Demonstration +=============== + +Demonstration of first Prototype of this platform with browser App (April 2012) - http://www.youtube.com/watch?v=zN5Dn1Lc_js diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm new file mode 100644 index 000000000..0eec1fdb6 --- /dev/null +++ b/api-docs/apiLive.htm @@ -0,0 +1,42924 @@ + + + + + + +Apache Fineract API Documentation + + + + + +
+
+ + +
+

Client

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
ClientclientsCreate a ClientList Clients
clients/{clientId}Retrieve a ClientUpdate a ClientDelete a Client
clients/{clientId}?command=activateActivate a Client
clients/{clientId}?command=closeClose a Client
clients/{clientId}?command=rejectReject a Client Application
clients/{clientId}?command=withdrawWithdraw a Client Application
clients/{clientId}?command=reactivateReactivate a Client
clients/{clientId}?command=assignStaffAssign Staff
clients/{clientId}?command=unassignStaffUnassign Staff
clients/{clientId}?command=proposeTransferPropose a Client Transfer
clients/{clientId}?command=withdrawTransferWithdraw Client Transfer Proposal
clients/{clientId}?command=acceptTransferAccept Client Transfer
clients/{clientId}?command=rejectTransferReject Client Transfer
clients/{clientId}?command=updateSavingsAccountUpdate Default Savings Account
clients/{clientId}?command=proposeAndAcceptTransferPropose and Accept a Client Transfer
clients/{clientId}/accountsRetrieve client accounts overview
Client Identifiersclients/{clientId}/identifiersCreate an Identifier for a ClientList all Identifiers for a Client
clients/{clientId}/identifiers/{identifierId}Retrieve a Client IdentifierUpdate a Client IdentifierDelete a Client Identifier
Client Imagesclients/{clientId}/imagesUpload an Image for a Client (as DATA URI)Get Client Image (DATA URI)Update Client Image (DATA URI)Delete Client Image
+ Upload an Image for a Client (Multi-part form data) + Get Client Image (Binary file) + Update Client Image (Multi-part form data) +
Standing InstructionsstandinginstructionsCreate Standing InstructionList Standing Instructions
standinginstructions/{standingInstructionId}Retrieve a Standing InstructionUpdate Standing InstructionDelete Standing Instruction(status change)
standinginstructionrunhistoryStanding Instructions Run History
Account TransferaccounttransfersCreate Account TransferList Account Transfer
accounttransfers/{accountTransferId}Retrieve a Account Transfer
accounttransfers/templateRefundByTransferRetrieve Refund of an Active Loan by Transfer Template
accounttransfers/refundByTransferRefund an active loan by transfer
Client Chargeclients/{clientId}/chargesAdd Client ChargeList Client Charges
clients/{clientId}/charges/{clientChargeId}Retrieve a Client ChargeDelete a Client Charge
clients/{clientId}/charges/{clientChargeId}?command=payPay a Client Charge
clients/{clientId}/charges/{clientChargeId}?command=waiveWaive a Client Charge
Client Transactionsclients/{clientId}/transactionsList Client Transactions
clients/{clientId}/transactions/{transactionId}?command=undoUndo a Client TransactionRetrieve a Client Transaction
+
+
+
+ +
+

Savings

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
Savings AccountssavingsaccountsSubmit new savings applicationList savings application/accounts
savingsaccounts/{accountId}Retrieve a savings application/accountModify a savings applicationDelete a savings application
savingsaccounts/{accountId}?command=approveApprove a savings application
savingsaccounts/{accountId}?command=undoApprovalUndo savings application approval
savingsaccounts/{accountId}?command=assignSavingsOfficerAssign Savings Officer
savingsaccounts/{accountId}?command=unassignSavingsOfficerUnassign Savings Officer
savingsaccounts/{accountId}?command=rejectReject a savings application
savingsaccounts/{accountId}?command=withdrawWithdraw savings application
savingsaccounts/{accountId}?command=activateActivate a savings account
savingsaccounts/{accountId}?command=closeClose a savings account
savingsaccounts/{accountId}?command=calculateInterestCalculate interest on a savings account
savingsaccounts/{accountId}?command=postInterestPost interest on a savings account
Savings Transactionssavingsaccounts/{accountId}/transactions?command=depositMake a deposit
savingsaccounts/{accountId}/transactions?command=withdrawalMake a withdrawal
savingsaccounts/{accountId}/transactions/{transactionId}?command=undoUndo transaction
savingsaccounts/{accountId}/transactions/{transactionId}?command=modifyAdjust transaction
savingsaccounts/{accountId}/transactions/templateRetrieve savings account transaction template
savingsaccounts/{accountId}/transactions/{transactionId}Retrieve savings account transaction
Savings Account Chargessavingsaccounts/{accountId}/chargesAdd a Savings Account ChargeList Savings Account Charges
savingsaccounts/{accountId}/charges/{savingsAccountChargeId}Retrieve a Savings Account ChargeModify a Savings Account ChargeDelete a Savings Account Charge
savingsaccounts/{accountId}/charges/{savingsAccountChargeId}?command=paychargePay a Savings Account Charge
savingsaccounts/{accountId}/charges/{savingsAccountChargeId}?command=waiveWaive a Savings Account Charge
savingsaccounts/{accountId}/charges/{savingsAccountChargeId}?command=inactivateInactivate a Savings Account Charge
Fixed Deposit AccountsfixeddepositaccountsSubmit new fixed deposit applicationList fixed deposit application/accounts
fixeddepositaccounts/{accountId}Retrieve a fixed deposit application/accountModify a fixed deposit applicationDelete a fixed deposit application
fixeddepositaccounts/{accountId}?command=approveApprove a fixed deposit application
fixeddepositaccounts/{accountId}?command=undoApprovalUndo fixed deposit application approval
fixeddepositaccounts/{accountId}?command=rejectReject a fixed deposit application
fixeddepositaccounts/{accountId}?command=withdrawWithdraw fixed deposit application
fixeddepositaccounts/{accountId}?command=activateActivate a fixed deposit account
fixeddepositaccounts/{accountId}?command=closeClose a fixed deposit account
fixeddepositaccounts/{accountId}?command=prematureClosePremature Close a fixed deposit account
fixeddepositaccounts/{accountId}?command=calculatePrematureAmountCalculate Premature amount on a fixed deposit account
fixeddepositaccounts/{accountId}?command=calculateInterestCalculate interest on a fixed deposit account
fixeddepositaccounts/{accountId}?command=postInterestPost interest on a fixed deposit account
Recurring Deposit AccountsrecurringdepositaccountsSubmit new recurring deposit applicationList recurring deposit application/accounts
recurringdepositaccounts/{accountId}Retrieve a recurring deposit application/accountModify a recurring deposit applicationDelete a recurring deposit application
recurringdepositaccounts/{accountId}?command=approveApprove a recurring deposit application
recurringdepositaccounts/{accountId}?command=undoApprovalUndo recurring deposit application approval
recurringdepositaccounts/{accountId}?command=rejectReject a recurring deposit application
recurringdepositaccounts/{accountId}?command=withdrawWithdraw recurring deposit application
recurringdepositaccounts/{accountId}?command=activateActivate a recurring deposit account
recurringdepositaccounts/{accountId}?command=updateDepositAmountUpdate recommended deposit amount
recurringdepositaccounts/{accountId}?command=closeClose a recurring deposit account
recurringdepositaccounts/{accountId}?command=prematureClosePremature Close a recurring deposit account
recurringdepositaccounts/{accountId}?command=calculatePrematureAmountCalculate Premature amount on a recurring deposit account
recurringdepositaccounts/{accountId}?command=calculateInterestCalculate interest on a recurring deposit account
recurringdepositaccounts/{accountId}?command=postInterestPost interest on a recurring deposit account
Recurring Deposit Transactionsrecurringdepositaccounts/{accountId}/transactions?command=depositMake a deposit
recurringdepositaccounts/{accountId}/transactions?command=withdrawalMake a withdrawal
recurringdepositaccounts/{accountId}/transactions/{transactionId}?command=undoUndo transaction
recurringdepositaccounts/{accountId}/transactions/{transactionId}?command=modifyAdjust transaction
recurringdepositaccounts/{accountId}/transactions/templateRetrieve Deposit account transaction template
recurringdepositaccounts/{accountId}/transactions/{transactionId}Retrieve Deposit account transaction
+
+
+
+ +
+

Loan

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
Loansloans?calculateLoanScheduleCalculate Loan Repayment Schedule
loansSubmit a new Loan ApplicationList Loans/Loan Applications
loans/{loanId}Retrieve a LoanUpdate a LoanDelete a Loan Application
loans/{loanId}?command=approveApprove Loan Application
loans/{loanId}?command=undoApprovalUndo Loan Application Approval
loans/{loanId}?command=assignLoanOfficerAssign a Loan Officer
loans/{loanId}?command=unassignLoanOfficerUnassign a Loan Officer
loans/{loanId}?command=rejectReject Loan Application
loans/{loanId}?command=withdrawWithdraw Loan Application
loans/{loanId}?command=disburseDisburse Loan
loans/{loanId}?command=disburseToSavingsDisburse Loan To Savings Account
loans/{loanId}?command=undoDisbursalUndo Loan Application Disbursal
loans/{loanId}?command=recoverGuaranteesRecover From Guarantors
Loan Transactionsloans/{loanId}/transactions?command=repaymentEnter a repayment
loans/{loanId}/transactions?command=waiveInterestWaive Interest
loans/{loanId}/transactions?command=writeoffWrite-off Loan
loans/{loanId}/transactions?command=undowriteoffUndo Loan Write-off transaction
loans/{loanId}/transactions?command=prepayLoanLoan Pre-Closure transaction template
loans/{loanId}/transactions?command=recoverypaymentMake a Recovery Payment
loans/{loanId}/transactions/{transactionId}Retrieve a transactions details
loans/{loanId}/transactions/{transactionId}Adjust a Transaction
loans/{loanId}/transactions?command=refundByCashRefund an Active Loan by Cash
Loan Chargesloans/{loanId}/chargesAdd a Loan Charge
loans/{loanId}/charges/{loanChargeId}Pay Loan Charge from Linked SavingsRetrieve a Loan ChargeModify a Loan ChargeDelete a Loan Charge
Loan Guarantorsloans/{loanId}/guarantorsCreate a Guarantor + List Guarantors +
loans/{loanId}/guarantors/{guarantorId}Retrieve a GuarantorUpdate a GuarantorDelete a Guarantor
Loan Collateralloans/{loanId}/collateralsCreate a Collateral + List collaterals +
loans/{loanId}/collaterals/{collateralId}Retrieve a CollateralUpdate a CollateralDelete a Collateral
Loan ReschedulingrescheduleloansCreate new loan reschedule request
rescheduleloans/{requestId}Retrieve a Loan Reschedule Request
rescheduleloans/{requestId}?command=previewLoanRescheduleRetrieve a Preview of The New Loan Repayment Schedule
rescheduleloans/{requestId}?command=rejectReject Loan Reschedule Request
rescheduleloans/{requestId}?command=approveApprove Loan Reschedule Request
Loan Term Variations/loans/{loanId}/schedule?command=calculateLoanScheduleCalculate Schedule with Loan Term Variations
/loans/{loanId}/schedule?command=addVariationsCreate Loan Term Variations
/loans/{loanId}/schedule?command=deleteVariationsRemove All Loan Term Variations
+
+
+
+ +
+

Groups

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
GroupgroupsCreate a GroupList Groups
groups/templateRetrieve Group Template
groups/{groupId}Retrieve a GroupUpdate a GroupDelete a Group
groups/{groupId}?command=activateActivate a Group
groups/{groupId}?command=associateClientsAssociate Clients
groups/{groupId}?command=disassociateClientsDisassociate Clients
groups/{groupId}/accountsRetrieve Group accounts summary
groups/{groupId}?command=transferClientsBulk Transfer Clients across Groups
groups/{groupId}?command=generateCollectionSheetGenerate Collection Sheet
groups/{groupId}?command=saveCollectionSheetSave Collection Sheet
groups/{groupId}?command=unassignStaffUnassign Staff
groups/{groupId}?command=assignStaffAssign Staff
groups/{groupId}?command=closeClose Group
groups/{groupId}?command=assignRoleAssign Role
groups/{groupId}?command=unassignRoleUnassign Role
groups/{groupId}?command=updateRoleUpdate Role
CentercentersCreate a CenterList Centers
centers/templateRetrieve Center Template
centers/{centerId}Retrieve a CenterUpdate a CenterDelete a Center
centers/{centerId}?command=activateActivate a Center
centers/{centerId}?command=closeClose Center
centers/{centerId}?command=associateGroupsAssociate Groups
centers/{centerId}?command=disassociateGroupsDisassociate Groups
centers/{centerId}/accountsRetrieve Center accounts summary
centers/{centerId}?command=generateCollectionSheetGenerate Collection Sheet
centers/{centerId}?command=saveCollectionSheetSave Collection Sheet
Collection Sheetcollectionsheet?command=generateCollectionSheetGenerate Collection Sheet
collectionsheet?command=saveCollectionSheetSave Collection Sheet
+
+
+
+ +
+

Accounting

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + P + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
General Ledger AccountglaccountsCreate a New Ledger AccountList Ledger Accounts
glaccounts/{glaccountId}Retrieve a Ledger AccountUpdate a Ledger AccountDelete a Ledger Account
Accounting ClosureglclosuresCreate an Accounting ClosureList Accounting Closures
glclosures/{glclosureId}Retrieve an Accounting ClosureUpdate an Accounting ClosureDelete an Accounting Closure
Journal EntriesjournalentriesCreate Journal EntriesList Journal Entries
journalentries?command=updateRunningBalanceUpdate Running Balance for Journal Entries
journalentries/{entryId}Retrieve a single Entry
journalentries/{transactionId}/reversalReverse Journal Entries
Accounting RulesaccountingrulesCreate a Accounting RuleList Accounting Rules
accountingrules/{accountingruleId}Retrieve a Accounting RuleUpdate a Accounting RuleDelete a Accounting Rule
Mapping Financial Activities to AccountsfinancialactivityaccountsCreate Financial Activity to Account Mapping
List Financial Activities to Accounts Mappings
financialactivityaccounts/{financialActivityAccountId}Retrieve a Financial Activity to Account MappingUpdate a Financial Activity to Account MappingDelete a Financial Activity to Account Mapping
Periodic Accrual AccountingaccrualaccountingExecute Periodic Accrual Accounting
Provisioning EntriesprovisioningentriesCreate Provisioning Entry
List Provisioning Entries
provisioningentries/{entryId}Retrieve Provisioning EntryRecreates Provisionin EntryAdd Provisioning Journal Entries
+
+
+
+
+

Org

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
OfficeofficesCreate an OfficeList Offices
offices/{officeId}Retrieve an OfficeUpdate an Office
Loan ProductloanproductsCreate a Loan + ProductList Loan Products
loanproducts/{productId}Retrieve a Loan + ProductUpdate a Loan + Product
Savings ProductsavingsproductsCreate a Savings productList Savings products
savingsproducts/{productId}Retrieve a savings productUpdate a savings productDelete a savings product
Fixed Deposit ProductfixeddepositproductsCreate a Fixed Deposit productList Fixed Deposit products
fixeddepositproducts/{productId}Retrieve a Fixed Deposit productUpdate a Fixed Deposit productDelete a Fixed Deposit product
Recurring Deposit ProductrecurringdepositproductsCreate a Recurring Deposit productList Recurring Deposit products
recurringdepositproducts/{productId}Retrieve a Recurring Deposit productUpdate a Recurring Deposit productDelete a Recurring Deposit product
CurrencycurrenciesRetrieve + Currency ConfigurationUpdate Currency + Configuration
FundsfundsCreate a FundList Funds
funds/{fundId}Retrieve a FundUpdate a Fund
StaffstaffCreate a Staff MemberList Staff
staff/{staffId}Retrieve a Staff MemberUpdate a Staff Member
Staff Imagesstaff/{staffId}/imagesUpload an Image for a Staff Member (as DATA URI)Get Staff Image (DATA URI)Update Staff Image (DATA URI)Delete Staff Image
+ Upload an Image for a Staff Member (Multi-part form data) + Get Staff Image (Binary file) + Update Staff Image (Multi-part form data) +
ChargeschargesCreate a ChargeList Charges
charges/{chargeId}Retrieve a ChargeUpdate a ChargeDelete a Charge
Loan Product Mixloanproducts?associations=productMixesList Loan Products Mix
loanproducts/{productId}/productmixCreate a Loan Product MixRetrieve Loan Products MixUpdate Loan Product MixDelete Loan Products Mix
HolidaysholidaysCreate a HolidayList Holidays
holidays/{holidayId}Retrieve a HolidayUpdate a HolidayDelete a Holiday
holidays/{holidayId}?command=activateActivate a Holiday
Working daysworkingdaysList workingdaysWorking days template
workingdays/{workingdaysId}Update a workingdays
User Generated DocumentstemplatesCreate a UGDList UGDs
templates/{templateId}Retrieve a UGDUpdate a UGDDelete a UGD
Interest Rate ChartschartsCreate a ChartList Charts
interestratecharts/{chartId}Retrieve a ChartUpdate a ChartDelete a Chart
Interest Rate SlabsslabsCreate a SlabList Slabs
interestrateslabs/{slabId}Retrieve a SlabUpdate a SlabDelete a Slab
Teller Cash ManagementtellersCreate TellerList Tellers
tellers/{tellerId}Find TellerUpdate TellerDelete Teller
tellers/{tellerId}/cashiersCreate CashierRetrieve Cashier
tellers/{tellerId}/cashiers/{cashierId}Find CashierUpdate CashierDelete Cashier
tellers/{tellerId}/cashiers/templateRetrieve Cashier Template
tellers/{tellerId}/cashiers/{cashierId}/allocateAllocate Cash To Cashier
tellers/{tellerId}/cashiers/{cashierId}/settleSettle Cash From Cashier
tellers/{tellerId}/cashiers/{cashierId}/transactionsRetrieve Cashier Transactions
tellers/{tellerId}/cashiers/{cashierId}/summaryandtransactionsRetrieve Cashier Transactions With Summary
tellers/{tellerId}/cashiers/{cashierId}/transactions/templateRetrieve Cashier Transaction Template
Payment TypepaymenttypesCreate Payment TypeList Payment Types
paymenttypes/{paymentTypeId}Retrieve Payment TypeUpdate Payment TypeDelete Payment Type
Provisioning CriteriaprovisioningcriteriaCreate Provisioning CriteriaList Provisioning Criteria
provisioningcriteria/{criteriaId}Retrieve Provisioning CriteriaUpdate Provisioning CriteriaDelete Provisioning Criteria
Floating RatesfloatingratesCreate Floating RateList Floating Rates
floatingrates/{floatingRateId}Retrieve Floating RateUpdate Floating Rate
+
+
+
+
+

User

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
Authentication HTTP BasicauthenticationVerify Authentication
Authentication Oauth2oauth/tokenOAuth2 Access and refresh Token Request
OAuth2 Access Token Request from refresh token
authenticated userFetch Authenticated user details
UserusersCreate a UserList Users
users/{userId}Retrieve a UserUpdate a UserDelete a User
RolerolesCreate a New RoleList Roles
roles/{roleId}Retrieve a RoleUpdate a RoleDelete Role
roles/{roleId}/permissionsRetrieve a + Role's PermissionsUpdate a Role's + Permissions
roles/{roleId}?command=enableEnable Role
roles/{roleId}?command=disableDisable Role
PermissionpermissionsList Application PermissionsEnable/Disable Permissions for Maker Checker
Password preferencespasswordpreferencesGet Password PreferencesUpdate Password Preferences
+
+
+
+
+

System

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
Global ConfigurationconfigurationsList + Global Configuration
Global Configurationconfigurations/{configId}Retrieve + a Global ConfigurationUpdate + Global Configuration
HookshooksCreate a HookList Hooks
hooks/{hookId}Retrieve a HookUpdate a HookDelete a Hook
Account number formataccountnumberformatsCreate an Account number formatList Account number formats
accountnumberformats/{accountnumberformatId}Retrieve an Account number formatUpdate an Account number formatDelete an Account number format
CodescodesCreate a CodeList Codes
codes/{codeId}Retrieve a CodeUpdate a CodeDelete a Code
Code Valuescodes/{codeId}/codevaluesCreate a Code ValueList Code Values
codes/{codeId}/codevalues/{codevalueId}Retrieve a Code ValueUpdate a Code ValueDelete a Code Value
AuditsauditsList Audits
audits/{auditId}Retrieve an Audit Entry
MakercheckersmakercheckersList Maker Checker Entries
makercheckers/{auditId}Delete Maker Checker Entry
makercheckers/{auditId}?command=approveApprove Maker Checker Entry
Scheduler jobsjobsList Scheduler jobs
jobs/{jobId}Retrieve a jobUpdate a job
jobs/{jobId}?command=executeJobRun a job
jobs/{jobid}/runhistoryRetrieve job history
schedulerRetrieve scheduler status
scheduler?command=startActivate a scheduler service
scheduler?command=stopSuspend a scheduler service
External Servicesexternalservice/{servicename}Retrieve + a external service configurationUpdate + external service Configuration
+
+
+
+
+

Non-Core

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
Data TabledatatablesCreate Data TableList Data Tables
datatables/{datatable}Retrieve Data Table DetailsUpdate Data TableDelete Data Table
datatables/register/{datatable}/{apptable}Register Data Table
datatables/deregister/{datatable}Deregister Data + Table
datatables/{datatable}/{apptableId}Create Entry in Data + TableRetrieve Entry(s) + from Data TableUpdate Entry in Data + Table (One to One)Delete Entry(s) in + Data Table
datatables/{datatable}/{apptableId}/{datatableId}Update Entry in + Data Table (One to Many)Delete Entry in + Data Table (One to Many)
Notes{resource}/{resourceId}/notesAdd a Resource NoteRetrieve a Resource's Notes
{resource}/{resourceId}/notes/{noteId}List All + Notes for a ResourceUpdate a Resource NoteDelete a Resource Note
Documents{entityType}/{entityId}/documentsCreate a DocumentList All Document Details
{entityType}/{entityId}/documents/{documentId}Retrieve a Documents DetailsUpdate a DocumentDelete a Document
{entityType}/{entityId}/documents/{documentId}/attachmentRetrieve + binary file associated with a + Document +
SearchsearchSearch Resources
AdHoc Searchsearch/advanceAdvance Search
Surveysurvey/List surveys
survey/{surveyName}Retrieve Survey details
survey/{surveyName}/{clientId}Create Entry in the survey table
+
+
+
+
+

Report

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
ReportreportsCreate a ReportList Reports
reports/{id}Retrieve a ReportUpdate a ReportDelete a Report
Run Reportrunreports/{reportName}Run a Report
+
+
+
+
+

Template

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
GET
read
clients/templateRetrieve Client Template
groups/templateRetrieve Group Template
loanproducts/templateRetrieve Loan Product Template
loanproducts/template?isProductMixTemplate=trueRetrieve Loan Product Mix Template
loans/template?clientId={clientId}Retrieve Loan Template
loans/{loanId}/transactions/templateRetrieve Loan Transaction Template
charges/templateRetrieve Charge Template
offices/templateRetrieve Office Template
users/templateRetrieve User Template
hooks/templateRetrieve Hooks Template
audits/searchtemplateRetrieve Audit Search Template
makercheckers/searchtemplateRetrieve Maker Checker Search Template
reports/templateRetrieve Report Template
accountingrules/templateRetrieve Accounting Rule Template
savingproducts/templateRetrieve Savings Product Template
savingsaccounts/template?clientId={clientId}Retrieve savings template
savingsaccounts/{accountId}/transactions/templateRetrieve savings account transaction template
standinginstructions/templateRetrieve Standing Instruction Template
accounttransfers/templateRetrieve Account Transfer Template
+
+
+
+ + +
+

SPM

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
SurveysurveysCreate a SurveyList Surveys
surveys/{id}Retrieve a SurveyDeactivate a Survey
Lookup Tablesurveys/{id}/lookuptablesCreate a Lookup Table entryList Lookup Table entries
surveys/{id}/lookuptables/{id}Retrieve an Entry
Scorecardsurveys/{id}/scorecardsCreate a Scorecard entryList Scorecard entries
+
+
+
+ + +
+

Self Service

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex + update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
Authentication HTTP Basicself/authenticationVerify Authentication
Authentication Oauth2self/userdetailsFetch Authenticated User Details
Clientsself/clientsList Clients
self/clients/{clientId}Retrieve Client
self/clients/{clientId}/accountsRetrieve Client Accounts Overview
self/clients/{clientId}/imagesRetrieve Client Image
self/clients/{clientId}/chargesList Client Charges
self/clients/{clientId}/charges/{chargeId}Retrieve a Client Charge
self/clients/{clientId}/transactionsList Client Transactions
self/clients/{clientId}/transactions/{transactionId}Retrieve a Client Transaction
Loansself/loans/{loanId}Retrieve a Loan
self/loans/{loanId}/transactions/{transactionId}Retrieve a Loan Transaction Details
self/loans/{loanId}/chargesRetrieve Loan Charges
self/loans/{loanId}/charges/{chargeId}Retrieve a Loan Charge Details
Savingsself/savingsaccounts/{accountId}Retrieve a Savings Account
self/savingsaccounts/{accountId}/transactions/{transactionId}Retrieve a Savings Transaction Details
self/savingsaccounts/{accountId}/chargesRetrieve Savings Charges
self/savingsaccounts/{accountId}/charges/{savingsAccountChargeId}Retrieve a Savings Charge Details
Own Account Transfersself/accounttransfers/templateAccount Transfer Template
self/accounttransfersAccount Transfer
+
+
+
+ +
+ +
+   +
+
+

Apache Fineract API Documentation

+

Apache Fineract is a secure, multi-tenanted microfinance platform.

+

+ The goal of the Apache Fineract API is to empower developers to build apps + on top of the Apache Fineract Platform. The reference app + (username: mifos, password: password) works on the same demo + 'tenant' as the interactive links in this documentation. +

+

+ The API is organized around REST. +

+

+ The API is designed to have:
- predictable, + resource-oriented URLs
- to use HTTP response codes to + indicate API errors
- to use built-in HTTP features, like + HTTP authentication and HTTP verbs, which can be understood by + off-the-shelf HTTP clients. +

+

+ JSON is + returned in all responses from the API, including errors. +

+

+ Much of the API presentation and design ideas are owed to the + excellent Apigee "Web API Design" eBook/PDF and the + very good Stripe + API reference. +

+
+
+ +   +
+
+

Try The API From Your Browser

+

GET (read) examples can be run directly from this + documentation. It is just a matter of clicking a link. Most + browsers display the output on the same page (or another tab if + you right click and select that option). Internet Explorer will + probably treat the output as if you wanted to download a file. In + that case just elect to open the output in a text editor.

+

+ If you want to check out the POST, PUT and DELETE (update) + examples a good approach is to take a moment to install a REST + plugin for your browser e.g. RESTClient for FireFox +

+ The REST plugins will allow you to +
    +
  • Select the "Verb" (e.g. POST)
  • +
  • Enter the resource name (e.g. offices)
  • +
  • Add a header to indicate you are sending + JSON data as part of the request body (Content-Type: + application/json)
  • +
  • Add a header to indicate your 'tenant' + (X-Mifos-Platform-TenantId: default)
  • +
  • Paste the example JSON into a Request Body
  • +
  • Send the Request (and receive a Response)
  • +
+
+
+ +   +
+
+

Generic Options

+

Convenience Templates

+

There are a list of convenience resources (see Template + menu option). These resources end with "/template" and can be + useful when building maintenance user interface screens for client + applications. The template data returned may consist of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

+ Also, many "Retrieve a" type resources (Retrieve a Client for example) allow + the parameter option "template=true". This appends any "Allowed + Value Lists" which can be useful when building update + functionality. +

+ +

Restrict Returned Fields

+

Parameter "fields={fieldlist}" can be used on GET requests + to restrict the fields returned.

+

Normal Request:

+
offices/1
+

+

Request (restricting fields returned):

+
offices/1?fields=id,name
+

+

Pretty JSON Formatting

+

Parameter "pretty=true" can be used to display JSON from GET + requests in an easy-to-read format. This parameter is used in this + documentation.

+

Easy-to-read JSON output for POSTs, PUTs and DELETEs will + available in the REST plugin you use e.g. RESTClient for FireFox

+

Normal Request (with pretty printing/formatting):

+
offices/1?pretty=true
+

+
+ +
+ +   +
+
+

Creating and Updating

+

When you want to 'Create a ...' you have to at least supply + the mandatory fields. The mandatory fields are listed in this + documentation under the relevant 'Create a ...' heading.

+ +

When you want to 'Update a ...' you can update individual + fields or a combination of fields (subject to data integrity + rules).

+
+ +
+ + +   +
+
+

Updating Dates and Numbers

+

Dates

+

+ Dates are returned in GET requests as an array e.g. [ 2007, 4, + 11]. However, the API accepts them as strings in POST and PUT + requests. If there are any dates in your POST or PUT requests, you + need to provide the "locale" and "dateFormat". This can be any + date pattern supported by Joda-Time. + This capability can help you when saving data in your client + application as you shouldn't need to do any date format conversion + prior to issuing your POST or PUT request. +

+JSON examples: +{ + "locale": "en_US", + "dateFormat": "dd MMMM yyyy", + "openingDate": "01 July 2007" +} + +{ + "locale": "en_US", + "dateFormat": "yyyy-MM-dd", + "openingDate": "2007-03-21" +} + +

Numbers

+

You must provide a "locale" when updating numbers. Numbers + are not "Ids" or "Types" but are typically money amounts or + percentages that relate to loans. In any case, the API will send + back an error message if you forget.

+JSON examples: +{ + "locale": "en_US", + "principal": "240,400.88" +} +{ + "locale": "fr_CH", + "principal": "240 400.88" +} + +
+ +
+ +   +
+
+

Field Descriptions

+

+ Most fields are self-explanatory. Fields that aren't are described + under the relevant resource heading e.g. AUTHENTICATION +

+ +
+ +
+ +   +
+
+

Authentication Overview

+

+ Authentication to the API can be configured to be supported via HTTP + Basic Auth or OAuth2. +

+ +

+ Default authentication is using HTTP Basic Auth. Oauth2 can be enabled by using -Psecurity=oauth option on gradle build command , refer + the platform setup wiki for additional details. +

+

+ The platform has been configured to reject plain HTTP requests and + to expect all API requests to be made over HTTPS. All + requests must be authenticated. +

+
+
+ +
+
+ +   +
+
+

Authentication HTTP Basic

+

+ Authentication to the API occurs via HTTP + Basic Auth. +

+ +
+
+ +// A Javascript/Jquery example of how to login to Apache Fineract and use its api. +// Typically, the javascript application would +// 1) Display a login page to retrieve the username and password. +// 2) Send the username and password to a function +// such as setBasicAuthKey below which sets the HTTP Basic Auth key. +// 3) The HTTP Basic Auth key is used in all subsequent requests +// (see the function executeAjaxRequest below). + +function setBasicAuthKey(username, password) { + + var jqxhr = $.ajax({ + url : "authentication?username=" + username + "&password=" + password, + type : 'POST', + contentType : "application/json; charset=utf-8", + dataType : 'json', + data : "{}", + cache : false, + success : function(data, textStatus, jqXHR) { + basicAuthKey = data.base64EncodedAuthenticationKey; + }, + error : function(jqXHR, textStatus, errorThrown) { + //error processing + } + }); +} + +function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFunction, errorFunction) { + var jqxhr = $.ajax({ + url : url, + type : verbType, //POST, GET, PUT or DELETE + contentType : "application/json; charset=utf-8", + dataType : 'json', + data : jsonData, + cache : false, + beforeSend : function(xhr) { + xhr.setRequestHeader("Authorization", "Basic " + basicAuthKey); + }, + success : successFunction, + error : errorFunction + }); +} + +
+
+ +   +
+
+

Authentication Oauth2

+

+ Authentication to the API occurs via OAuth2. 'Resource Owner Password Credentials Grant' type is used. +

+ +
+
+ +// A Javascript/Jquery example of how to login to Apache Fineract and use its api. +// Typically, the javascript application would +// 1) Display a login page to retrieve the username and password. +// 2) Send the username, password, client_id , grant_type and client_secret to a function +// such as getOauthToken below which sets the HTTP bearer Auth key. +// 3) The HTTP bearer Auth key is used in all subsequent requests +// (see the function executeAjaxRequest below). + +function getOauthToken(username, password) { + + var jqxhr = $.ajax({ + url : "/fineract-provider/api/oauth/token?username=" + credentials.username + "&password=" + credentials.password +"&client_id=community-app&grant_type=password&client_secret=123, + type : 'POST', + contentType : "application/json; charset=utf-8", + dataType : 'json', + data : "{}", + cache : false, + success : function(data, textStatus, jqXHR) { + authKey = data.access_token; + }, + error : function(jqXHR, textStatus, errorThrown) { + //error processing + } + }); +} + +function executeAjaxRequest(url, verbType, jsonData, authKey, successFunction, errorFunction) { + var jqxhr = $.ajax({ + url : url, + type : verbType, //POST, GET, PUT or DELETE + contentType : "application/json; charset=utf-8", + dataType : 'json', + data : jsonData, + cache : false, + beforeSend : function(xhr) { + xhr.setRequestHeader("Authorization", "bearer " + authKey); + }, + success : successFunction, + error : errorFunction + }); +} + +
+
+ +   +
+
+

Batch API

+ +

+ The Apache Fineract Batch API enables a consumer to access significant amounts of data in a single call or to make changes to several objects at once. + Batching allows a consumer to pass instructions for several operations in a single HTTP request. A consumer can also specify dependencies between related operations. Once all operations have been completed, a consolidated response will be passed back and the HTTP connection will be closed. +

+ +

+ The Batch API takes in an array of logical HTTP requests represented as JSON arrays - each request has a requestId (the id of a request used to specify the sequence and as a dependency between requests), a method (corresponding to HTTP method GET/PUT/POST/DELETE etc.), a relativeUrl (the portion of the URL after https://example.org/api/v2/), optional headers array (corresponding to HTTP headers), optional reference parameter if a request is dependent on another request and an optional body (for POST and PUT requests). + The Batch API returns an array of logical HTTP responses represented as JSON arrays - each response has a requestId, a status code, an optional headers array and an optional body (which is a JSON encoded string). +

+ +

+ Batch API uses Json Path to handle dependent + parameters. For example, if request '2' is referencing request '1' and in the "body" or in "relativeUrl" of request '2', there is a dependent parameter (which will look like "$.parameter_name"), then Batch API will internally substitute this dependent parameter from the response body of request '1'. +

+ +

+ Batch API is able to handle deeply nested dependent requests as well nested parameters. As shown in the example, requests are dependent on each other as, 1<--2<--6, i.e a nested dependency, where request '6' is not directly dependent on request '1' but still it is one of the nested child of request '1'. + In the same way Batch API could handle a deeply nested dependent value, such as {..[..{..,$.parameter_name,..}..]}. +

+ +
+
+ +POST https://DomainName/api/v1/batches + + +POST batches +Content-Type: application/json Request Body: +[ + { + "requestId":1, + "relativeUrl":"clients", + "method":"POST", + "headers":[ + { + "name":"Content-type", + "value":"text/html" + } + ], + "body":"{ + \"officeId\": 1, + \"firstname\": \"Petra\", + \"lastname\": \"Yton\", + \"externalId\": \"ex_externalId1\", + \"dateFormat\": \"dd MMMM yyyy\", + \"locale\": \"en\", + \"active\": true, + \"activationDate\": \"04 March 2009\", + \"submittedOnDate\": \"04 March 2009\" + }" + }, + { + "requestId":2, + "relativeUrl":"loans", + "method":"POST", + "headers":[ + { + "name":"Content-type", + "value":"text/html" + } + ], + "reference":1, + "body":"{ \"dateFormat\": \"dd MMMM yyyy\", + \"locale\": \"en_GB\", + \"clientId\": \"$.clientId\", + \"productId\": 26, + \"principal\": \"10,000.00\", + \"loanTermFrequency\": 12, + \"loanTermFrequencyType\": 2, + \"loanType\": \"individual\", + \"numberOfRepayments\": 10, + \"repaymentEvery\": 1, + \"repaymentFrequencyType\": 2, + \"interestRatePerPeriod\": 10, + \"amortizationType\": 1, + \"interestType\": 0, + \"interestCalculationPeriodType\": 1, + \"transactionProcessingStrategyId\": 1, + \"expectedDisbursementDate\": \"10 Jun 2013\", + \"submittedOnDate\": \"10 Jun 2013\" + }" + }, + { + "requestId":3, + "relativeUrl":"loans/$.loanId/charges", + "method":"POST", + "reference":2, + "headers":[ + { + "name":"Content-type", + "value":"text/html" + } + ], + "body":"{ + \"chargeId\": \"2\", + \"locale\": \"en\", + \"amount\": \"100\", + \"dateFormat\": \"dd MMMM yyyy\", + \"dueDate\": \"29 April 2013\" + }" + }, + { + "requestId":4, + "relativeUrl":"loans/$.loanId/charges", + "method":"GET", + "reference":2, + "headers":[ + { + "name":"Content-type", + "value":"text/html" + } + ], + "body":"{}" + } +] + + +[ + { + "requestId":1, + "statusCode":200, + "headers":[ + { + "name":"Content-type", + "value":"text/html" + }, + { + "name":"X-Mifos-Platform-TenantId", + "value":"text/html" + } + ], + "body":"{\"officeId\":1,\"clientId\":909,\"resourceId\":909}" + }, + { + "requestId":2, + "statusCode":200, + "headers":[ + { + "name":"Content-type", + "value":"text/html" + } + ], + "body":"{\"officeId\":1,\"clientId\":909,\"loanId\":212,\"resourceId\":212}" + }, + { + "requestId":3, + "statusCode":200, + "headers":[ + { + "name":"Content-type", + "value":"text/html" + } + ], + "body":"{\"officeId\":1,\"clientId\":909,\"loanId\":212,\"resourceId\":155}" + }, + { + "requestId":4, + "statusCode":200, + "headers":[ + { + "name":"Content-type", + "value":"text/html" + } + ], + "body":"[ + { + \"id\":155, + \"chargeId\":2, + \"name\":\"Charge_Loans_GEQJC5\", + \"chargeTimeType\":{ + \"id\":1, + \"code\":\"chargeTimeType.disbursement\", + \"value\":\"Disbursement\" + }, + \"chargeCalculationType\":{ + \"id\":2, + \"code\":\"chargeCalculationType.percent.of.amount\", + \"value\":\"% Amount\" + }, + \"percentage\":100.000000, + \"amountPercentageAppliedTo\":10000.000000, + \"currency\":{ + \"code\":\"USD\", + \"name\":\"USDollar\", + \"decimalPlaces\":2, + \"displaySymbol\":\"$\", + \"nameCode\":\"currency.USD\", + \"displayLabel\":\"US Dollar ($)\" + }, + \"amount\":10000.000000, + \"amountPaid\":0, + \"amountWaived\":0, + \"amountWrittenOff\":0, + \"amountOutstanding\":10000.000000, + \"amountOrPercentage\":100.000000, + \"penalty\":false, + \"chargePaymentMode\":{ + \"id\":0, + \"code\":\"chargepaymentmode.regular\", + \"value\":\"Regular\" + }, + \"paid\":false, + \"waived\":false, + \"chargePayable\":false + } + ]" + } +] + +
+ +
+ +   +
+
+

Batch requests in a single transaction

+ +

+ The Apache Fineract Batch API is also capable of executing all the requests in a single transaction, by setting a Query Parameter, "enclosingTransaction=true". So, if one or more of the requests in a batch returns an erroneous response all of the Data base transactions made by other successful requests will be rolled back. +

+ +

+ If there has been a rollback in a transaction then a single response will be provided, with a '400' status code and a body consisting of the error details of the first failed request. +

+ +
+
+ +POST https://DomainName/api/v1/batches?enclosingTransaction=true + + +POST batches +Content-Type: application/json Request Body: +[ + { + "requestId":1, + "relativeUrl":"clients", + "method":"POST", + "headers":[ + { + "name":"Content-type", + "value":"text/html" + }, + { + "name":"X-Mifos-Platform-TenantId", + "value":"text/html" + } + ], + "body":"{ + \"officeId\": 1, + \"firstname\": \"Petra\", + \"lastname\": \"Yton\", + \"externalId\": \"externalId_4\", + \"dateFormat\": \"dd MMMM yyyy\", + \"locale\": \"en\", \"active\": true, + \"activationDate\": \"04 March 2009\", + \"submittedOnDate\": \"04 March 2009\" + }" + }, + { + "requestId":2, + "relativeUrl":"savingsaccounts", + "method":"POST", + "reference":1, + "headers":[ + { + "name":"Content-type", + "value":"text/html" + } + ], + "body":"{ + \"clientId\": \"$.clientId\", + \"productId\": 1, + \"locale\": \"en\", + \"dateFormat\": \"dd MMMM yyyy\", + \"submittedOnDate\": \"01 March 2011\" + }" + } +] + + +Successful transaction response: +[ + { + "requestId":1, + "statusCode":200, + "headers":[ + { + "name":"Content-type", + "value":"text/html" + }, + { + "name":"X-Mifos-Platform-TenantId", + "value":"text/html" + } + ], + "body":"{\"officeId\":1,\"clientId\":922,\"resourceId\":922}" + }, + { + "requestId":2, + "statusCode":200, + "headers":[ + { + "name":"Content-type", + "value":"text/html" + } + ], + "body":"{\"officeId\":1,\"clientId\":922,\"savingsId\":116,\"resourceId\":116}" + } +] + + +
+ +
+ +   +
+
+

Batch API Errors

+ +

+ In Batch API without "enclosingTransaction=true", if one of the response is erroneous, then an appropriate status code will be set for that request and the error message will be returned in it's "body", while all other requests will return successful response with a status code of "200". +

+ +
+
+ +   +
+
+

Available Command Strategies

+ +

+ These are the currently available command strategies within the Mifos Batch API. So, these listed operations can be executed using a Batch Request. +

+ +
+ +
+ +   +
+
+

Errors

+ +

All errors are returned in JSON.

+ +
+
+
HTTP Status Code Summary
+
    +
  • 200 OK - Everything Worked.
  • +
  • 400 Bad Request - Invalid Parameter or + Data Integrity Issue.
  • +
  • 401 Authentication Error.
  • +
  • 403 Unauthorized Request.
  • +
  • 404 Resource Not Found
  • +
  • 500 Platform Internal Server Error.
  • +
+
+
+ +Error Message returned when attempting to create an Office without passing any parameters +{ +"developerMessage": "The request was invalid. This typically will happen due to validation errors which are provided.", +"developerDocLink": "https://github.com/openMF/mifosx/wiki/HTTP-API-Error-codes", +"httpStatusCode": "400", +"defaultUserMessage": "Validation errors exist.", +"userMessageGlobalisationCode": "validation.msg.validation.errors.exist", +"errors": [ + { + "developerMessage": "The parameter name cannot be blank.", + "defaultUserMessage": "The parameter name cannot be blank.", + "userMessageGlobalisationCode": "validation.msg.office.name.cannot.be.blank", + "parameterName": "name", + "value": null, + "args": [] + }, + { + "developerMessage": "The parameter openingDate cannot be blank.", + "defaultUserMessage": "The parameter openingDate cannot be blank.", + "userMessageGlobalisationCode": "validation.msg.office.openingDate.cannot.be.blank", + "parameterName": "openingDate", "value": null, "args": [] + }, + { + "developerMessage": "The parameter parentId cannot be blank.", + "defaultUserMessage": "The parameter parentId cannot be blank.", + "userMessageGlobalisationCode": + "validation.msg.office.parentId.cannot.be.blank", "parameterName": + "parentId", "value": null, "args": [] + } +] +} + +
+
+   +
+
+

Self Service API Overview

+

+ Self Service APIs are a set of APIs with restricted data scope. Functional specifications and design can be viewed + here. +

+ +

+ While creating an user, user can be tagged as self service user. Also you can associate + clients that this user has access to. Data scope is restricted to these linked clients. +

+

+ A self service user shall have access to only self service APIs. Self service APIs cannot be accessed by non-self service user. Vice-versa is also true. +

+
+
+ +
+
+ +   +
+
+

Clients

+

Clients are people and businesses that have applied (or may apply) to an MFI for loans.

+

Clients can be created in Pending or straight into Active state.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
accountNo
If provided during client creation, its + value is set as account no. for client account, otherwise an + auto generated account no. is put in place based on the + configured strategy.
externalId
A place to put an external reference for + this client e.g. The ID another system uses.
If + provided, it must be unique. +
active
Indicates whether this client is to be created as active client. If active=true, then activationDate must be provided. If active=false, then the client is created as pending. +
activationDate
The date on which the client became active. +
firstname
Facility to break up name into parts + suitable for humans.
middlename
Facility to break up name into parts + suitable for humans.
lastname
Facility to break up name into parts + suitable for humans.
fullname
Facility to set name of a client or + business that doesn't suit the firstname,middlename,lastname + structure.
mobileNo
Optional: unique mobile number that is used by SMS or Mobile Money functionality. +
staffId
The staffId of the staff member dealing with the client office. The staff member is not specifically the loan officer.
savingsProductId
Optional: Default overdraft savings account of client +
+
+
+ +   +
+
+

Retrieve Client Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+
Arguments
+
+
officeId
+
+ Integer optional +
+
staffInSelectedOfficeOnly
+
+ Boolean optional +
+
Defaults to false if not provided. If staffInSelectedOfficeOnly=true only staff + who are associated with the selected branch are returned.
+
commandParam
+
+ String optional +
+
If commandParam=close retrieves all closureReasons which are associated with + "ClientClosureReason" value.
+
+

Example Request:

+
clients/template
+
+
+ +GET https://DomainName/api/v1/clients/template + + +{ + "activationDate":[2014,3,4], + "officeId":1, + "officeOptions":[{ + "id":1, + "name":"Head Office", + "nameDecorated":"Head Office" + }], + "staffOptions":[{ + "id":1, + "firstname":"xyz", + "lastname":"sjs", + "displayName":"sjs, xyz", + "officeId":1, + "officeName":"Head Office", + "isLoanOfficer":true, + "isActive":true + }], + "savingProductOptions":[{ + "id":4, + "name":"account overdraft", + "withdrawalFeeForTransfers":false, + "allowOverdraft":false + }] +} + +
+
+ +   +
+
+

Create a Client

+

+ Note: You can enter either:
+ firstname/middlename/lastname - for a person (middlename is + optional) OR
fullname - for a business or organisation + (or person known by one name).
+

+ + + + + + + +
Mandatory Fields
firstname and lastname OR fullname,
officeId,
active=true and activationDate OR active=false,
+
+
+ + + + + + + +
Optional Fields
groupId, externalId, accountNo, staffId, mobileNo, savingsProductId, genderId, clientTypeId, clientClassificationId
+
+
+ +POST https://DomainName/api/v1/clients + + +POST clients +Content-Type: application/json Request Body: +{ + "officeId": 1, + "firstname": "Petra", + "lastname": "Yton", + "externalId": "786YYH7", + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "active": true, + "activationDate": "04 March 2009", + "submittedOnDate":"04 March 2009", + "savingsProductId" : 4 +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 1, + "savingsId": 10 +} + +
+
+ +POST clients +Content-Type: application/json +Request Body: +{ + "officeId": 1, + "fullname": "Client of group", + "groupId": 1, + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "active": true, + "activationDate": "04 March 2009" +} + + +{ + "officeId": 1, + "groupId": 1, + "clientId": 2, + "resourceId": 2 +} + +
+
+ +   +
+
+

Activate a Client

+

Clients can be created in a Pending state. This API exists to enable client activation (for when a client becomes an approved member of the financial Institution).

+

If the client happens to be already active this API will result in an error.

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=activate + POST clients/1?command=activate +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "activationDate": "01 March 2011" +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Close a Client

+

Clients can be closed if they do not have any non-closed loans/savingsAccount. This API exists to close a client .

+

If the client have any active loans/savingsAccount this API will result in an error.

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=close + POST clients/1?command=close +Content-Type: application/json +Request Body: +{ + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closureDate":"25 June 2013", + "closureReasonId":"11" +} + + +{ + "clientId":15, + "resourceId":15 +} + +
+
+ +   +
+
+

Reject a Client

+

Clients can be rejected when client is in pending for activation status.

+

If the client is any other status, this API throws an error.

+ + + + + + + +
Mandatory Fields
rejectionDate, rejectionReasonId
+
+
+ +
+ POST https://Domain Name/api/v1/clients/{clientId}?command=reject + POST clients/1?command=reject +Content-Type: application/json +Request Body: +{ +"rejectionDate":"28 November 2014", +"rejectionReasonId":16, +"locale":"en", +"dateFormat":"dd MMMM yyyy" +} + + +{ + "clientId":15, + "resourceId":15 +} + +
+
+ +   +
+
+

Withdraw a Client

+

Client applications can be withdrawn when client is in a pending for activation status.

+

If the client is any other status, this API throws an error.

+ + + + + + + +
Mandatory Fields
withdrawalDate, withdrawalReasonId
+
+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=withdraw + POST clients/1?command=withdraw +Content-Type: application/json +Request Body: +{ +"withdrawalDate":"28 November 2014", +"withdrawalReasonId":17, +"locale":"en", +"dateFormat":"dd MMMM yyyy" +} + + +{ + "officeId":1, + "clientId":15, + "resourceId":15 +} + +
+
+ + +   +
+
+

Reactivate a Client

+

Clients can be reactivated after they have been closed.

+

Trying to reactivate a client in any other state throws an error.

+ + + + + + + +
Mandatory Fields
reactivationDate
+
+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=reactivate + POST clients/1?command=reactivate +Content-Type: application/json +Request Body: +{ +"reactivationDate":"28 November 2014", +"locale":"en", +"dateFormat":"dd MMMM yyyy" +} + + +{ + + "clientId":15, + "resourceId":15 +} + +
+
+   +
+
+

Assign a Staff

+

Allows you to assign a Staff for existed Client.

+

The selected Staff should belong to the same office (or an officer higher up in the hierarchy) + as the Client he manages.

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=assignStaff + POST clients/1?command=assignStaff +Content-Type: application/json +Request Body: +{ + "staffId": "1" +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 1, + "changes": {"staffId":1} +} + +
+
+ +   +
+
+

Unassign a Staff

+

Allows you to unassign the Staff assigned to a Client.

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=unassignStaff + POST clients/1?command=unassignStaff +Content-Type: application/json +Request Body: +{ + "staffId":"1" +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 1, + "changes": {"staffId":1} +} + +
+
+ +   +
+
+

Update Default Savings Account

+

Allows you to modify or assign a default savings account for an existing Client.

+

The selected savings account should be one among the existing savings account for a particular customer.

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=updateSavingsAccount + POST clients/1?command=updateSavingsAccount +Content-Type: application/json +Request Body: +{ + "savingsAccountId": "22" +} + + +{ + "officeId":1, + "clientId":1, + "resourceId":1 + ,"changes":{ + "savingsAccountId":22 + } +} + +
+
+ +   +
+
+

Propose a Client Transfer

+

Allows you to propose the transfer of a Client to a different Office.

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=proposeTransfer + POST clients/1?command=proposeTransfer +Content-Type: application/json +Request Body: +{ + "destinationOfficeId":"2", + "note":"Client Relocating to Bangalore" +} + + +{ + "clientId": 2, + "resourceId": 2 +} + + + +
+
+ +   +
+
+

Withdraw a Client Transfer

+

Allows you to withdraw the proposed transfer of a Client to a different Office.

+

Withdrawal can happen only if the destination Branch (to which the transfer was + proposed) has not already + accepted the transfer proposal

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=withdrawTransfer + POST clients/1?command=withdrawTransfer +Content-Type: application/json +Request Body: +{ + "note":"Sorry, data entry error" +} + + +{ + "clientId": 2, + "resourceId": 2 +} + + + +
+
+ +   +
+
+

Reject a Client Transfer

+

Allows the Destination Branch to reject the proposed Client Transfer.

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=rejectTransfer + POST clients/1?command=rejectTransfer +Content-Type: application/json +Request Body: +{ + "note":"We cannot accept tranfers of clients having loans with less than 1 repayment left" +} + + +{ + "clientId": 2, + "resourceId": 2 +} + + + +
+
+ +   +
+
+

Accept a Client Transfer

+

Allows the Destination Branch to accept the proposed Client Transfer.

+

The destination branch may also choose to link this client to a group (in which case, any existing active JLG loan of the client is rescheduled to match the meeting frequency of the group) and loan Officer at the time of accepting + the transfer

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=acceptTransfer + POST clients/1?command=acceptTransfer +Content-Type: application/json +Request Body: +{ + "destinationGroupId":"13", + "staffId":"1", + "note":"Due Diligence done and all documents received" +} + + +{ + "clientId": 2, + "resourceId": 2 +} + + + +
+
+ + +   +
+
+

Propose and Accept a Client Transfer

+

Abstraction over the Propose and Accept Client Transfer API's which enable a user with Data Scope over both the Target and Destination Branches to directly + transfer a Client to the destination Office.

+
+
+ POST https://Domain Name/api/v1/clients/{clientId}?command=proposeAndAcceptTransfer + POST clients/1?command=proposeTransfer +Content-Type: application/json +Request Body: +{ + "destinationOfficeId":"2", + "destinationGroupId":"13", + "staffId":"1", + "note":"Client Relocating to Bangalore" +} + + +{ + "clientId": 2, + "resourceId": 2 +} + + + +
+
+ + +   +
+
+

Retrieve a Client

+

Example Requests:

+
clients/1
+
+
+
clients/1?template=true
+
+
+
clients/1?fields=id,displayName,officeName
+
+
+ +GET https://DomainName/api/v1/clients/{clientId} + + +{ + "id": 27, + "accountNo": "000000027", + "status": { + "id": 300, + "code": "clientStatusType.active", + "value": "Active" + }, + "active": true, + "activationDate": [ + 2013, + 1, + 1 + ], + "firstname": "savings", + "lastname": "test", + "displayName": "savings test", + "officeId": 1, + "officeName": "Head Office", + "timeline": { + "submittedOnDate": [ + 2013, + 1, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "activatedOnDate": [ + 2013, + 1, + 1 + ], + "activatedByUsername": "mifos", + "activatedByFirstname": "App", + "activatedByLastname": "Administrator" + }, + "savingsProductId": 4, + "savingsProductName": "account overdraft", + "groups": [] +} + +
+
+ +   +
+
+

List Clients

+

The list capability of clients can support pagination and sorting.

+
Optional Arguments
+
+
offset
+
+ Integer optional, defaults to 0 +
+
Indicates the result from which pagination starts
+ +
limit
+
+ Integer optional, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
orderBy
+
+ String optional, one of displayName, accountNo, officeId, officeName +
+
Orders results by the indicated field.
+ +
sortBy
+
+ String optional, one of ASC, DESC +
+
Indicates what way to order results if orderBy is used.
+ +
officeId
+
+ Integer optional +
+
Provides the ability to restrict list of clients returned based on the office they are associated with.
+
underHierarchy
+
+ String optional +
+
Use the office hierarchy string to return all clients under a given hierarchy.
+ +
displayName
+
+ String optional +
+
Use displayName of clients to restrict results.
+ +
firstName
+
+ String optional +
+
Use firstName of clients to restrict results.
+ +
lastName
+
+ String optional +
+
Use lastName of clients to restrict results.
+ +
externalId
+
+ String optional +
+
Use externalId of clients to restrict results.
+ +
sqlSearch
+
+ String optional +
+
Use an sql fragment valid for the underlying client schema to filter results. e.g. display_name like %K%
+
orphansOnly
+
+ Boolean optional, defaults to false +
+
Use orphansOnly as true to list clients which are not associated to any group/parent.
+
+

Example Requests:

+
clients
+
+
clients?fields=displayName,officeName,timeline
+
+
clients?offset=10&limit=50
+
+
clients?orderBy=displayName&sortOrder=DESC
+
+
+ +GET https://DomainName/api/v1/clients + + +{ + "totalFilteredRecords": 2, + "pageItems": [ + { + "id": 1, + "accountNo": "000000001", + "status": { + "id": 300, + "code": "clientStatusType.active", + "value": "Active" + }, + "active": true, + "activationDate": [ + 2013, + 3, + 1 + ], + "fullname": "Small shop", + "displayName": "Small shop", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 2, + "accountNo": "000000002", + "status": { + "id": 100, + "code": "clientStatusType.pending", + "value": "Pending" + }, + "active": false, + "fullname": "Home Farm Produce", + "displayName": "Home Farm Produce", + "officeId": 1, + "officeName": "Head Office" + } + ] +} + +
+
+ +   +
+
+

Update a Client

+

Note:You can update any of the basic attributes of a client (but not its associations) using this API.

+

Changing the relationship between a client and its office is not supported through this API. An API specific to handling transfers of clients between offices is available for the same.

+

The relationship between a client and a group must be removed through the Groups API.

+
+
+ +PUT https://DomainName/api/v1/clients/{clientId} + + +PUT clients/1 +Content-Type: application/json +Request Body: +{ + "externalId": "786444UUUYYH7" +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 1, + "changes": { + "externalId": "786444UUUYYH7" + } +} + +
+
+ +   +
+
+

Delete a Client

+

If a client is in Pending state, you are allowed to Delete it. The delete is a 'hard delete' and cannot be recovered from. Once clients become active or have loans or savings associated with them, you cannot delete the client but you may Close the client if they have left the program.

+
+
+ +DELETE https://DomainName/api/v1/clients/{clientId} + + +DELETE clients/3 +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 3, + "resourceId": 3 +} + +
+
+ +   +
+
+

Retrieve client accounts overview

+

+ An example of how a loan portfolio summary can be provided. This + is requested in a specific use case of the community application.
It is quite reasonable to add resources like this to simplify User Interface development. +

+

Example Requests:

+
clients/1/accounts
+
+
+
clients/1/accounts?fields=loanAccounts,savingsAccounts
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/accounts + + +{ + "loanAccounts": [ + { + "id": 1, + "accountNo": "000000001", + "externalId": "456", + "productId": 1, + "productName": "TestOne", + "status": { + "id": 300, + "code": "loanStatusType.active", + "value": "Active", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": true, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "loanType": { + "id": 1, + "code": "loanType.individual", + "value": "Individual" + }, + "loanCycle": 1 + } + ], + "savingsAccounts": [ + { + "id": 7, + "accountNo": "000000007", + "productId": 2, + "productName": "Other product", + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + { + "id": 6, + "accountNo": "000000006", + "productId": 1, + "productName": "Passbook Savings", + "status": { + "id": 300, + "code": "savingsAccountStatusType.active", + "value": "Active", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": true, + "closed": false + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountBalance": 1828.03 + }, + { + "id": 5, + "accountNo": "000000005", + "productId": 1, + "productName": "Passbook Savings", + "status": { + "id": 400, + "code": "savingsAccountStatusType.withdrawn.by.applicant", + "value": "Withdrawn by applicant", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": true, + "active": false, + "closed": true + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ] +} + +
+
+ + +   +
+
+

Client Identifiers

+

Client Identifiers refer to documents that are + used to uniquely identify a customer
+ Ex: Drivers License, Passport, Ration card etc +

+ + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
documentKey
Number/String used to uniquely identify a particular + document (Driving License number for a driving license etc)
documentType
Type of the identification document + (License, Passport Etc)
description
Any user comments to be associated + with the Client Identifier
+
+
+ +   +
+
+

List all Identifiers for a Client

+

Example Requests:

+
clients/1/identifiers
+
+
+
clients/1/identifiers?fields=documentKey,documentType,description
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/identifiers + + +[ + { + "id": 2, + "clientId": 1, + "documentType": { + "id": 3, + "name": "Drivers License" + }, + "documentKey": "12345", + "description": "Issued in the year 2--7" + } +] + +
+
+ +   +
+
+

Retrieve Client Identifier Details Template

+

This is a convenience resource useful for + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
clients/1/identifiers/template
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/identifiers/template + + +{ + "allowedDocumentTypes": [ + { + "id": 1, + "name": "Passport", + "position": 0 + }, + { + "id": 2, + "name": "Id", + "position": 0 + }, + { + "id": 3, + "name": "Drivers License", + "position": 0 + }, + { + "id": 4, + "name": "Any Other Id Type", + "position": 0 + } + ] +} + +
+
+ + +   +
+
+

Retrieve a Client Identifier

+

Example Requests:

+
clients/1/identifier/2
+
+
+
clients/1/identifier/2?template=true
+
+
+
clients/1/identifiers/2?fields=documentKey,documentType,description
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/identifiers/{identifierId} + + +{ + "id": 2, + "clientId": 1, + "documentType": { + "id": 3, + "name": "Drivers License" + }, + "documentKey": "12345", + "description": "Issued in 2007" +} + +
+
+ +   +
+
+

Create an Identifier for a Client

+ + + + + + + +
Mandatory Fields
documentKey, documentTypeId +
+
+
+ +POST https://DomainName/api/v1/clients/{clientId}/identifiers + + +POST clients/1/identifiers +Content-Type: application/json +Request Body: +{ +"documentTypeId":"1", +"documentKey":"KA-54677", +"description":"Document has been verified" +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 3 +} + +
+
+ +   +
+
+

Update a Client Identifier

+
+
+ +PUT https://DomainName/api/v1/clients/{clientId}/identifiers/{identifierId} + + +PUT clients/1/identifiers/3 +Content-Type: application/json +Request Body: +{ +"documentTypeId":"4", +"documentKey":"KA-94667", +"description":"Document has been updated" +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 3, + "changes": { + "documentTypeId": 4, + "documentKey": "KA-94667", + "description": "Document has been updated" + } +} + +
+
+ +   +
+
+

Delete a Client Identifier

+
+
+ +DELETE https://DomainName/api/v1/clients/{clientId}/identifiers/{identifierId} + + +DELETE clients/1/identifiers/3 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 3 +} + +
+
+ + + +   +
+
+

Images

+

The current API provides support for the addition of a single + image for entities like Client (URL pattern /clients) and Staff (URL pattern /staff)
+ Allowed formats: JPEG (.jpg or .jpeg), GIF (.gif) and PNG (.png) +

+

The API supports two different Approaches for manipulating Images +

    +
  • Data URI's: + For easier manipulation by Javascript clients etc in supported Browsers. +
  • +
  • + Multi-part form data: + Images can be uploaded using Multi part forms and downloaded as regular binary files +
  • +
    +
+
+ +   +
+
+

Get Entity Image (DATA URI)

+

Optional arguments are identical to those of Get Image associated with an Entity (Binary file)

+

Example Requests:

+
clients/1/images
+
staff/1/images
+
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/images +Accept: text/plain + + + +data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ +bWFnZVJlYWR5ccllPAAAAJ1JREFUeNpi+P//PwMIA4E9EG8E4idQDGLbw+WhiiqA+D8OXAFVAzbp +DxBvB2JLIGaGYkuoGEjOhhFIHAbij0BdPgxYACMj42ogJQpifwBiXSDeC8JIbt4LxSC5DyxQjTeB ++BeaYb+Q5EBOAVutCzMJHUNNPADzzDokiYdAfAmJvwLkGeTgWQfyKZICS6hYBTwc0QL8ORSjBDhA +gAEAOg13B6R/SAgAAAAASUVORK5CYII= + +
+
+ +   +
+
+

Get Image associated with an Entity (Binary file)

+
Optional Arguments
+
+
output
+
+ String optional one of octet or inline_octet +
+
The query parameter overrides the "Accept" Header and sets the Media Type to "application/octet-stream"
+ octet : Returns the image binary file as an attachment. The Content-Disposition header is set to attachment;filename=somefile.ext
+ inline_octet :The Content-Disposition header is set to inline;filename=somefile.ext +
+
maxWidth
+
+ Integer optional +
+
Triggers resizing of the image to the defined width
+ +
maxHeight
+
+
+ Integer optional +
+ +
Triggers resizing of the image to the defined height
+ + +
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/images +Accept: application/octet-stream + + +GET clients/1/images +Accept: application/octet-stream + + +Not shown: The corresponding binary (image) file + +
+
+ +   +
+
+

Upload an Image for an Entity (Data URI)

+
+
+ +POST https://DomainName/api/v1/clients/{clientId}/images + + +POST clients/1/images +Content-Type: text/plain +Request Body: +data:image/png;base64,iVBORw0KGgoAA +AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l +EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6 +P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC + + +{ + "resourceId": 1, + "changes": {}, + "resourceIdentifier": "1" +} + +
+
+ +   +
+
+

Upload an Image for an Entity (Multi-part Form data)

+ + + + + + + +
Mandatory Fields
file +
+

+ The form should contain a required named body part with the + name "file".

+ If you are using a HTML form, a snippet like + <input type="file" name="file"></input> + can be used for uploading the image file +

+
+
+ +POST https://DomainName/api/v1/clients/{clientId}/images + + +POST clients/1/images +Content-Type: multipart/form-data +Request Body: Not shown + + +{ + "resourceId": 1, + "changes": {}, + "resourceIdentifier": "1" +} + +
+
+ +   +
+
+

Update a Image associated with an Entity (Data URI)

+
+
+ +PUT https://DomainName/api/v1/clients/{clientId}/images + + +PUT clients/1/images +Content-Type: text/plain +Request Body: +data:image/png;base64,iVBORw0KGgoAA +AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l +EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6 +P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC + + +{ + "resourceId": 1, + "changes": {}, + "resourceIdentifier": "1" +} + +
+
+ +   +
+
+

Update an Entity's Image (Multi-part Form data)

+ + + + + + + +
Mandatory Fields
file +
+

+ The form should contain a required named body part with the + name "file".

+ If you are using a HTML form, a snippet like + <input type="file" name="file"></input> + can be used for uploading the image file +

+
+
+ +PUT https://DomainName/api/v1/clients/{clientId}/images + + +PUT clients/1/images +Content-Type: multipart/form-data +Request Body: Not shown + +
+
+ +   +
+
+

Delete an Entity's Image

+
+
+ +DELETE https://DomainName/api/v1/clients/{clientId}/images + + +DELETE clients/1/images +Content-Type: application/json +No Request Body: + + +{ + "resourceId": 1, + "changes": {}, + "resourceIdentifier": "1" +} + +
+
+ + +   +
+
+

Centers

+

Centers along with Groups are used to provided a distinctive banking distribution channel used in microfinance. Its common in areas such as Southern Asia to use Centers and Group as administrative units in grameen style lending. Typically groups will contain one to five people and centers themselves will be made of anywhere between 2-10 groups. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
externalId
A place to put an external reference for this center e.g. The ID another system uses. If provided, it must be unique. +
name
Name given to the Center.
active
Indicates whether this center is to be created as active. If active=true, then activationDate must be provided. If active=false, then the center is created as pending. +
activationDate
The date on which the center became active. +
officeId
The officeId of the office/branch this center is administrated through.
staffId
The staffId of the staff member dealing with this center. The staff member is not specifically the loan officer.
groupMembers
The array of groupIds to indicate what groups are part of this center.
+
+
+ +   +
+
+

Retrieve a Center Template

+

Example Requests:

+
centers/template
+
+
centers/template?officeId=2
+
+
+ +GET https://DomainName/fineract-provider/api/v1/centers/template + + +{ + "active": false, + "activationDate": [ + 2013, + 4, + 18 + ], + "officeId": 1, + "officeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + }, + { + "id": 2, + "name": "Branch Office 1", + "nameDecorated": "....Branch Office 1" + } + ], + "staffOptions": [ + { + "id": 1, + "displayName": "C, Mike" + } + ], + "groupMembersOptions": [ + { + "id": 1, + "name": "First Group", + "externalId": "000-1A", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".1." + }, + { + "id": 2, + "name": "Pending Group", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".2." + } + ] +} + +
+
+ +GET https://DomainName/fineract-provider/api/v1/centers/template?officeId=2 + + +{ + "active": false, + "activationDate": [ + 2013, + 4, + 18 + ], + "officeId": 2, + "officeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + }, + { + "id": 2, + "name": "Branch Office 1", + "nameDecorated": "....Branch Office 1" + } + ], + "staffOptions": [ + { + "id": 2, + "displayName": "D, Mary" + }, + { + "id": 3, + "displayName": "P, Paul" + } + ] +} + +
+
+ +   +
+
+

Create a Center

+ + + + + + + +
Mandatory Fields
name, officeId, active, activationDate (if active=true)
+
+ + + + + + + +
Optional Fields
externalId, staffId, groupMembers
+
+
+

Create a center as pending with no association to groupMembers.

+ +POST https://DomainName/fineract-provider/api/v1/centers + + +POST centers +Content-Type: application/json Request Body: +{ + "name": "First Center (No groups)", + "officeId": 1, + "active": false +} + + +{ + "officeId": 1, + "groupId": 8, + "resourceId": 8 +} + +
+ +
+

Create a center as active with no association to groupMembers.

+ +POST https://DomainName/fineract-provider/api/v1/centers + + +POST centers +Content-Type: application/json Request Body: +{ + "name": "centerwithgroup", + "officeId": 1, + "groupMembers": ["7"], + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "active": true, + "activationDate": "01 March 2011" +} + + +{ + "officeId": 1, + "groupId": 9, + "resourceId": 9 +} + +
+
+ +   +
+
+

Activate a Center

+

Centers can be created in a Pending state. This API exists to enable center activation.

+

If the center happens to be already active, this API will result in an error.

+
+
+ POST https://Domain Name/api/v1/centers/{centerId}?command=activate + POST centers/1?command=activate +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "activationDate": "01 March 2011" +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Close a Center

+

Centers can be closed if they don't have any non-closed groups or saving accounts.

+

If the Center has any active groups or savings accounts, this API will result in an error.

+
+
+ POST https://Domain Name/api/v1/centers/{centerId}?command=close + POST centers/1?command=close +Content-Type: application/json +Request Body: +{ + "closureReasonId": 32, + "closureDate": "05 May 2014", + "locale": "en", + "dateFormat": "dd MMMM yyyy" +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Associate Groups

+

This API allows associating existing groups to a center.

+

The groups are listed from the office to which the center is associated.

+

If group(s) is already associated with a center, this API will result in an error.

+
+ +
+ POST https://Domain Name/api/v1/centers/{centerId}?command=associateGroups + POST centers/1?command=associateGroups +Content-Type: application/json +Request Body: +{ + "grouptMembers":[1,2] +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1, + "grouptMembers": [1,2] +} + +
+
+ +   +
+
+

Disassociate Groups

+

This API allows to disassociate groups from a center.

+
+ +
+ POST https://Domain Name/api/v1/centers/{centerId}?command=disassociateGroups + POST center/1?command=disassociateGroups +Content-Type: application/json +Request Body: +{ + "grouptMembers":[1,2] +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1, + "grouptMembers": [1,2] +} + +
+
+ +   +
+
+

Retrieve Center accounts overview

+

+ An example of how a savings summary for a Center can be provided. This + is requested in a specific use case of the reference application.
It is quite reasonable to add resources like this to simplify User Interface development. +

+

Example Requests:

+
centers/9/accounts
+
+
+ +GET https://DomainName/api/v1/centers/{centerId}/accounts + + +{ + "savingsAccounts": [{ + "id": 16, + "accountNo": "000000016", + "productId": 1, + "productName": "Voluntary savings", + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false, + "prematureClosed": false, + "transferInProgress": false, + "transferOnHold": false + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountType": { + "id": 2, + "code": "accountType.group", + "value": "Group" + }, + "timeline": { + "submittedOnDate": [2014,5,1], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator" + }, + "depositType": { + "id": 100, + "code": "depositAccountType.savingsDeposit", + "value": "Savings" + } + }] +} + +
+
+ +   +
+
+

Generate Collection Sheet

+

This Api retrieves repayment details of all jlg loans under a center as on a specified meeting date.

+
+
+ POST https://Domain Name/api/v1/centers/{centerId}?command=generateCollectionSheet + POST centers/10?command=generateCollectionSheet +Content-Type: application/json +Request Body: +{ + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "calendarId":6, + "transactionDate":"04 May 2014" +} + + +{ + "dueDate": [2014,5,4], + "loanProducts": [{ + "id": 1, + "name": "IGL", + "includeInBorrowerCycle": false, + "useBorrowerCycle": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principalVariationsForBorrowerCycle": [], + "interestRateVariationsForBorrowerCycle": [], + "numberOfRepaymentVariationsForBorrowerCycle": [] + }], + "groups": [{ + "groupId": 1, + "groupName": "Group 1", + "staffId": 1, + "staffName": "A, Aliya", + "levelId": 2, + "levelName": "Group", + "clients": [{ + "clientId": 10, + "clientName": "saving acc", + "loans": [{ + "loanId": 10, + "accountId": "000000010", + "accountStatusId": 300, + "productShortName": "IGL", + "productId": 1, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principalDue": 1200.000000, + "principalPaid": 0.000000, + "interestDue": 21.360000, + "interestPaid": 0.000000, + "totalDue": 1221.360000 + }], + "attendanceType": { + "id": 0, + "code": "attendanceType.invalid", + "value": "Invalid" + } + }] + }], + "attendanceTypeOptions": [{ + "id": 1, + "code": "attendanceType.present", + "value": "Present" + }, + { + "id": 2, + "code": "attendanceType.absent", + "value": "Absent" + }, + { + "id": 3, + "code": "attendanceType.approved", + "value": "Approved" + }, + { + "id": 4, + "code": "attendanceType.leave", + "value": "Leave" + }, + { + "id": 5, + "code": "attendanceType.late", + "value": "Late" + }] +} + +
+
+ +   +
+
+

Generate Individual Collection Sheet

+

This Api retrieves repayment details of all individual loans under a office as on a specified meeting date.

+
+
+ POST https://Domain Name/api/v1/collectionsheet?command=generateCollectionSheet + POST collectionsheet?command=generateCollectionSheet +Content-Type: application/json +Request Body: +{ + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "transactionDate":"15 January 2015", + "officeId":3 +} + + +{ + "dueDate": [ + 2015, + 1, + 15 + ], + "clients": [ + { + "clientId": 74, + "clientName": "guarantee test", + "loans": [ + { + "loanId": 307, + "accountId": "000000307", + "accountStatusId": 300, + "productShortName": "pr", + "productId": 60, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principalDue": 1126.23, + "principalPaid": 8873.77, + "interestDue": 0, + "interestPaid": 504.95, + "totalDue": 1126.23 + } + ], + "savings": [ + { + "savingsId": 213, + "accountId": "000000213", + "accountStatusId": 300, + "productName": "11", + "productId": 30, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "dueAmount": 2000 + } + ] + } + ], + "paymentTypeOptions": [ + { + "id": 19, + "name": "receipt", + "position": 1, + "description": "rec" + }, + { + "id": 20, + "name": "check", + "position": 2, + "description": "che" + } + ] +} + +
+
+ + +   +
+
+

Save Collection Sheet

+

This Api allows the loan officer to perform bulk repayments of JLG loans for a center on a given meeting date.

+
+
+ POST https://Domain Name/api/v1/centers/{centerId}?command=saveCollectionSheet + POST centers/10?command=saveCollectionSheet +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "calendarId": 6, + "transactionDate": "04 May 2014", + "actualDisbursementDate": "04 May 2014", + "clientsAttendance": [], + "bulkDisbursementTransactions": [], + "bulkRepaymentTransactions": [{ + "loanId": 10, + "transactionAmount": 1221.36 + }] +} + + +{ + "groupId": 10, + "resourceId": 10, + "changes": { + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "loanTransactions": [10], + "SavingsTransactions": [] + } +} + +
+
+ +   +
+
+

Save Collection Sheet

+

This Api allows the loan officer to perform bulk repayments of individual loans and deposit of mandatory savings on a given meeting date.

+
+
+ POST https://Domain Name/api/v1/collectionsheet?command=saveCollectionSheet + POST collectionsheet?command=saveCollectionSheet +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "transactionDate": "04 May 2014", + "actualDisbursementDate": "04 May 2014", + "bulkDisbursementTransactions": [], + "bulkRepaymentTransactions": [{ + "loanId": 10, + "transactionAmount": 1221.36, + "paymentTypeId":19, + "receiptNumber":"1245356" + }], + "bulkSavingsDueTransactions":[] +} + + +{ + "groupId": 10, + "resourceId": 10, + "changes": { + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "loanTransactions": [15], + "SavingsTransactions": [] + + } +} + +
+
+ + +   +
+
+

Update a Center

+
+
+ +PUT https://DomainName/fineract-provider/api/v1/centers/{centerId} + + +PUT centers/8 +Content-Type: application/json +Request Body: +{ + "name": "First Center (No groups)" +} + + +{ + "officeId": 1, + "groupId": 8, + "resourceId": 8, + "changes": { + "name": "First Center (No groups) - modified" + } +} + +
+
+ +   +
+
+

Delete a Center

+

A Center can be deleted if it is in pending state and has no association - groups, loans or savings

+
+
+ +POST https://DomainName/fineract-provider/api/v1/centers/{centerId} + + +DELETE centers/8 + + +{ + "resourceId":1, + "changes":{} +} + +
+
+ +   +
+
+

Retrieve a Center

+

Example Requests:

+
centers/1
+
+
centers/1?associations=groupMembers
+
+
+

Retrieve an existing center with no groups information.

+ +GET https://DomainName/fineract-provider/api/v1/centers/8 + + +{ + "id": 8, + "status": { + "id": 100, + "code": "groupingStatusType.pending", + "value": "Pending" + }, + "active": false, + "name": "First Center (No groups)", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".8." +} + +
+
+

Retrieve an existing center without the details of group associations.

+ +GET https://DomainName/fineract-provider/api/v1/centers/9 + + +{ + "id": 9, + "status": { + "id": 300, + "code": "groupingStatusType.active", + "value": "Active" + }, + "active": true, + "activationDate": [ + 2011, + 3, + 1 + ], + "name": "centerwithgroup", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".9." +} + +
+
+ +   +
+
+

List Centers

+

The default implementation supports pagination and sorting with the default pagination size set to 200 records. The parameter limit with value -1 will return all entries.

+
Optional Arguments
+
+
paged
+
+ Boolean optional, defaults to false +
+
If paged is true then results will be paginated.
+
offset
+
+ Integer optional, defaults to 0 +
+
Indicates from what result to start from.
+ +
limit
+
+ Integer optional, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
orderBy
+
+ String optional, one of displayName, accountNo, officeId, officeName +
+
Orders the results by the field indicated.
+ +
sortBy
+
+ String optional, one of ASC, DESC +
+
Indicates what way to order results if orderBy is used.
+ +
officeId
+
+ Integer optional +
+
Provides ability to restrict list of centers returned based on the office there associated with.
+
underHierarchy
+
+ String optional +
+
Use the office hierarchy string to return all centers under a given hierarchy.
+ +
name
+
+ String optional +
+
Use name of centers to restrict results.
+ +
externalId
+
+ String optional +
+
Use externalId of center to restrict results.
+ +
sqlSearch
+
+ String optional +
+
Use an sql fragment valid for the underlying center schema to filter results. e.g. display_name like %K%
+
+

Example Requests:

+
centers
+
+
centers?fields=name,officeName,joinedDate
+
+
centers?offset=10&limit=50
+
+
centers?orderBy=name&sortOrder=DESC
+
+
+ +GET https://DomainName/fineract-provider/api/v1/centers?paged=true + + +{ + "totalFilteredRecords": 2, + "pageItems": [ + { + "id": 2, + "status": { + "id": 100, + "code": "groupingStatusType.pending", + "value": "Pending" + }, + "active": false, + "name": "Center 1", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".2." + }, + { + "id": 3, + "status": { + "id": 100, + "code": "groupingStatusType.pending", + "value": "Pending" + }, + "active": false, + "name": "Center 2", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".3." + } + ] +} + +
+
+ + + +   +
+
+

Groups

+

Groups are used to provide a distinctive banking distribution channel used in microfinances throughout the world. The Group is an administrative unit. It can contain as few as 5 people or as many as 40 depending on how its used.

+ +

Different styles of group lending - Joint-Liability Group, Grameen Model (Center-Group), Self-Help Groups, Village/Communal Banks)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name given to the Group.
externalId
A place to put an external reference for this group e.g. The ID another system uses. If provided, it must be unique. +
officeId
The officeId of the office/branch this group is administrated through.
active
Indicates whether this group is to be created as active. If active=true, then activationDate must be provided. If active=false, then the group is created as pending. +
activationDate
The date on which the group became active. +
staffId
The staffId of the staff member dealing with this group. The staff member is not specifically the loan officer. The staff member must be assigned to the same office as this group.
clientMembers
The individual client members that make up the group. The clients must be assigned to the same office as this group.
calendarId
The identifier of the calendar to which the transaction is linked with.
transactionDate
The date on which the transaction took place.
role
The role to be assigned to a client.
actualDisbursementDate
The date on which the actual disbursement took place.
clientsAttendance
The clients attendance.
bulkRepaymentTransaction
The details of any bulk repayment transactions.
bulkDisbursementTransactions
The details of any bulk disbursement transactions.
+
+
+ +   +
+
+

Retrieve Group Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+
Arguments
+
+
officeId
+
+ Integer optional +
+
centerId
+
+ Integer optional +
+
staffInSelectedOfficeOnly
+
+ Boolean optional +
+
Defaults to false if not provided. If staffInSelectedOfficeOnly=true only staff + who are associated with the selected branch are returned.
+
+ +

Example Requests:

+
groups/template
+
+
groups/template?officeId=2
+
+
groups/template?centerId=1
+
+
groups/template?centerId=1&staffInSelectedOfficeOnly=true
+
+
+
+

Template to create a standard group

+ +GET https://DomainName/fineract-provider/api/v1/groups/template + + +{ + "officeId": 1, + "officeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + }, + { + "id": 2, + "name": "Branch Office 1", + "nameDecorated": "....Branch Office 1" + } + ], + "staffOptions": [ + { + "id": 1, + "displayName": "C, Mike" + } + ], + "clientOptions": [ + { + "id": 1, + "displayName": "Petra Yton", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 2, + "displayName": "Small shop business", + "officeId": 1, + "officeName": "Head Office" + } + ] +} + +
+
+

Template to create a standard group with specific office known. This will return only staffOptions and clientMembersOptions relevant for the chosen office.

+ +GET https://DomainName/fineract-provider/api/v1/groups/template?officeId=2 + + +{ + "officeId": 2, + "officeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + }, + { + "id": 2, + "name": "Branch Office 1", + "nameDecorated": "....Branch Office 1" + } + ], + "staffOptions": [ + { + "id": 2, + "displayName": "D, Mary" + }, + { + "id": 3, + "displayName": "P, Paul" + } + ] +} + +
+
+

Template to create a group for an existing center. As an existing center will be assigned to an office, this will return only staffOptions and clientMembersOptions relevant for the chosen center/office.

+ +GET https://DomainName/fineract-provider/api/v1/groups/template?centerId=1 + + + + +
+
+ +   +
+
+

Create a Group

+ + + + + + + +
Mandatory Fields
name, officeId, active, activationDate (if active=true)
+
+ + + + + + + +
Optional Fields
externalId, staffId, clientMembers
+
+
+ +POST https://DomainName/fineract-provider/api/v1/groups + + +POST groups +Content-Type: application/json Request Body: +{ + "officeId":"1", + "name":"Pending Group", + "active": false +} + + +{ + "officeId": 1, + "groupId": 2, + "resourceId": 2 +} + + +POST groups +Content-Type: application/json Request Body: +{ + "officeId":"1", + "name":"First Group", + "externalId": "000-1A", + "clientMembers": ["1"], + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "active": true, + "activationDate": "04 March 2009", + "submittedOnDate":"04 March 2009" +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Activate a Group

+

Groups can be created in a Pending state. This API exists to enable group activation.

+

If the group happens to be already active this API will result in an error.

+ + + + + + + +
Mandatory Fields
activationDate
+
+
+
+ POST https://Domain Name/api/v1/groups/{groupId}?command=activate + POST groups/1?command=activate +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "activationDate": "01 March 2011" +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Associate Clients

+

This API allows to associate existing clients to a group.

+

The clients are listed from the office to which the group is associated.

+

If client(s) is already associated with group then API will result in an error.

+ + + + + + + +
Mandatory Fields
clientMembers
+
+
+ +
+ POST https://Domain Name/api/v1/groups/{groupId}?command=associateClients + POST groups/1?command=associateClients +Content-Type: application/json +Request Body: +{ + "clientMembers":[1,2] +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1, + "clientMembers": [1,2] +} + +
+
+   +
+
+

Disassociate Clients

+

This API allows to disassociate clients from a group.

+

Disassociating a client with active joint liability group loans results in an error.

+ + + + + + + +
Mandatory Fields
clientMembers
+
+
+ +
+ POST https://Domain Name/api/v1/groups/{groupId}?command=disassociateClients + POST groups/1?command=disassociateClients +Content-Type: application/json +Request Body: +{ + "clientMembers":[1,2] +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1, + "clientMembers": [1,2] +} + +
+
+ +   +
+
+

Transfer Clients across groups

+

This API allows to transfer clients from one group to another

+ + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
destinationGroupId
The identifier of the group to which the clients are to be transferred ( + has to be in the same branch as the source Group).
clients
Identifiers of all clients who need to be transferred +
inheritDestinationGroupLoanOfficer
Flag specifies if the transferred clients (and all their active loans) + should be linked to the assigned loan officer for the group +
+
+ + + + + + + +
Mandatory Fields
destinationGroupId, clients
+
+ + + + + + + +
Optional Fields
inheritDestinationGroupLoanOfficer (defaults to true), transferActiveLoans (defaults to true)
+
+ + +
+ + POST https://Domain Name/api/v1/groups/{groupId}?command=transferClients + POST groups/1?command=transferClients +Content-Type: application/json +Request Body: +{ + destinationGroupId:2, + clients:[{id:1}] +} + + +{ + "resourceId": 1 +} + + + +
+
+ +   +
+
+

Generate Collection Sheet

+

This API retrieves repayment details of all jlg loans of all members of a group on a specified meeting date.

+
+ + + + + + + +
Mandatory Fields
calendarId, transactionDate
+
+
+ POST https://Domain Name/api/v1/groups/{groupId}?command=generateCollectionSheet + POST groups/1?command=generateCollectionSheet +Content-Type: application/json +Request Body: +{ + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "calendarId":6, + "transactionDate":"04 May 2014" +} + + +{ + "dueDate": [2014,5,4], + "loanProducts": [{ + "id": 1, + "name": "IGL", + "includeInBorrowerCycle": false, + "useBorrowerCycle": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principalVariationsForBorrowerCycle": [], + "interestRateVariationsForBorrowerCycle": [], + "numberOfRepaymentVariationsForBorrowerCycle": [] + }], + "groups": [{ + "groupId": 1, + "groupName": "Group 1", + "staffId": 1, + "staffName": "A, Aliya", + "levelId": 2, + "levelName": "Group", + "clients": [{ + "clientId": 10, + "clientName": "saving acc", + "loans": [{ + "loanId": 10, + "accountId": "000000010", + "accountStatusId": 300, + "productShortName": "IGL", + "productId": 1, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principalDue": 1200.000000, + "principalPaid": 0.000000, + "interestDue": 21.360000, + "interestPaid": 0.000000, + "totalDue": 1221.360000 + }], + "attendanceType": { + "id": 0, + "code": "attendanceType.invalid", + "value": "Invalid" + } + }] + }], + "attendanceTypeOptions": [{ + "id": 1, + "code": "attendanceType.present", + "value": "Present" + }, + { + "id": 2, + "code": "attendanceType.absent", + "value": "Absent" + }, + { + "id": 3, + "code": "attendanceType.approved", + "value": "Approved" + }, + { + "id": 4, + "code": "attendanceType.leave", + "value": "Leave" + }, + { + "id": 5, + "code": "attendanceType.late", + "value": "Late" + }] +} + +
+
+ +   +
+
+

Save Collection Sheet

+

This api allows the loan officer to perform bulk repayments of JLG loans for a group on its meeting date.

+ + + + + + + +
Mandatory Fields
calendarId, transactionDate, actualDisbursementDate
+
+ + + + + + + +
Optional Fields
clientsAttendance, bulkRepaymentTransaction, bulkDisbursementTransactions
+
+
+ POST https://Domain Name/api/v1/groups/{groupId}?command=saveCollectionSheet + POST groups/1?command=saveCollectionSheet +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "calendarId": 6, + "transactionDate": "04 May 2014", + "actualDisbursementDate": "04 May 2014", + "clientsAttendance": [], + "bulkDisbursementTransactions": [], + "bulkRepaymentTransactions": [{ + "loanId": 10, + "transactionAmount": 1221.36 + }] +} + + +{ + "groupId": 1, + "resourceId": 1, + "changes": { + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "bulkTransations": { + "loanId": 10, + "transactionAmount": 1221.36, + "transactionDate": [2014,5,4] + } + } +} + +
+
+ +   +
+
+

Unassign a Staff

+

Allows you to unassign the Staff.

+ + + + + + + +
Mandatory Fields
staffId
+
+
+ POST https://Domain Name/api/v1/groups/{groupId}?command=unassignStaff + POST groups/1?command=unassignStaff +Content-Type: application/json +Request Body: +{ + "staffId":"1" +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1, + "changes": {} +} + +
+
+ +   +
+
+

Assign a Staff

+

Allows you to assign Staff to an existing Group.

+

The selected Staff should be belong to the same office (or an office higher up in the hierarchy) as this group

+ + + + + + + +
Mandatory Fields
staffId
+ + + + + + + + + + +
Optional Fields
inheritStaffForClientAccounts
Optional: Boolean if true all members of the group (i.e all clients with active loans and savings ) will inherit the staffId
+
+
+ POST https://Domain Name/api/v1/groups/{groupId}?command=assignStaff + POST groups/1?command=assignStaff +Content-Type: application/json +Request Body: +{ + "staffId": "1" +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1, + "changes": {"staffId":1} +} + +
+
+ +   +
+
+

Close a Group

+

This API exists to close a group. Groups can be closed if they don't have any non-closed clients/loans/savingsAccounts.

+

If the group has any active clients/loans/savingsAccount, this API will result in an error.

+
+
+ POST https://Domain Name/api/v1/groups/{groupId}?command=close + POST groups/1?command=close +Content-Type: application/json +Request Body: +{ + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closureDate":"25 June 2013", + "closureReasonId":"30" +} + + +{ + "groupId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Assign a Role

+

Allows you to assign a Role to an existing member of a group.

+

We can define the different roles applicable to group members by adding code values to the pre-defined system code GROUPROLE. Example:Group leader etc.

+ + + + + + + +
Mandatory Fields
clientId, role
+
+
+ POST https://Domain Name/api/v1/groups/{groupId}?command=assignRole + POST groups/1?command=assignRole +Content-Type: application/json +Request Body: +{ + "clientId": "1", + "role":30 +} + + +{ + "clientId": 1, + "groupId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Unassign a Role

+

Allows you to unassign Roles associated tp Group members.

+
+
+ POST https://Domain Name/api/v1/groups/{groupId}?command=unassignRole&roleId=1 + POST groups/1?command=unassignRole&roleId=1 +Content-Type: application/json +Request Body: +{} + + +{ + "clientId": 1, + "groupId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Update a Role

+

Allows you to update the member Role.

+ + + + + + + +
Mandatory Fields
role
+
+
+ POST https://Domain Name/api/v1/groups/{groupId}?command=updateRole&roleId=2 + POST groups/1?command=updateRole&roleId=2 +Content-Type: application/json +Request Body: +{ + "role":"31" +} + + +{ + "groupId": 1, + "resourceId": 2, + "changes":{"role":31} +} + +
+
+ +   +
+
+

Retrieve a Group

+

Retrieve group information.

+
+
associations
+
+ String optional +
+
+ One of, or comma separated of clientMembers, activeClientMembers, groupRoles, calendars, collectionMeetingCalendar +
+ or all for all associations. +
+
staffInSelectedOfficeOnly
+
+ Boolean optional, defaults to false +
+
If staffInSelectedOfficeOnly=true only staff + who are associated with the selected branch are returned.
+
roleId
+
+ Long optional +
+
If present, will retrieve group role information
+
+

Example Requests:

+
groups/1
+
+
groups/1?associations=clientMembers
+
+
+

Group without any associations.

+ +GET https://DomainName/fineract-provider/api/v1/groups/1 + + +{ + "id": 1, + "name": "First Group", + "externalId": "000-1A", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".1.", + "timeline": { + "activatedOnDate": [ + 2013, + 11, + 14 + ], + "activatedByUsername": "mifos", + "activatedByFirstname": "App", + "activatedByLastname": "Administrator" + } +} + +
+
+

Group along with all its Clients.

+ +GET https://DomainName/fineract-provider/api/v1/groups/1?associations=clientMembers + + +{ + "id": 1, + "name": "First Group", + "externalId": "000-1A", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".1.", + "timeline": { + "activatedOnDate": [ + 2013, + 11, + 14 + ], + "activatedByUsername": "mifos", + "activatedByFirstname": "App", + "activatedByLastname": "Administrator" + }, + "clientMembers": [ + { + "id": 1, + "accountNo": "000000001", + "externalId": "786YYH7", + "activationDate": [ + 2009, + 3, + 4 + ], + "firstname": "Petra", + "lastname": "Yton", + "displayName": "Petra Yton", + "officeId": 1, + "officeName": "Head Office" + } + ] +} + +
+
+ + +   +
+
+

Retrieve Group accounts overview

+

+ Retrieves details of all Loan and Savings accounts associated with this group. +

+

Example Requests:

+
groups/1/accounts
+
+
+
groups/1/accounts?fields=loanAccounts,savingsAccounts,memberLoanAccounts,
memberSavingsAccounts
+
+
+ +GET https://DomainName/api/v1/groups/{groupId}/accounts + + +{ + "loanAccounts": [ + { + "id": 3, + "accountNo": "000000003", + "productId": 3, + "productName": "daily product", + "status": { + "id": 100, + "code": "loanStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "pendingApproval": true, + "waitingForDisbursal": false, + "active": false, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "loanType": { + "id": 2, + "code": "accountType.group", + "value": "Group" + } + } + ], + "savingsAccounts": [ + { + "id": 9, + "accountNo": "000000009", + "productId": 1, + "productName": "p_sav", + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountType": { + "id": 2, + "code": "accountType.group", + "value": "Group" + } + }, + { + "id": 4, + "accountNo": "000000004", + "productId": 1, + "productName": "p_sav", + "status": { + "id": 300, + "code": "savingsAccountStatusType.active", + "value": "Active", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": true, + "closed": false + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountType": { + "id": 2, + "code": "accountType.group", + "value": "Group" + } + } + ], + "memberLoanAccounts": [ + { + "id": 4, + "accountNo": "000000004", + "productId": 1, + "productName": "testLoan", + "status": { + "id": 200, + "code": "loanStatusType.approved", + "value": "Approved", + "pendingApproval": false, + "waitingForDisbursal": true, + "active": false, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "loanType": { + "id": 3, + "code": "accountType.jlg", + "value": "JLG" + } + }, + { + "id": 7, + "accountNo": "000000007", + "productId": 2, + "productName": "weekly product", + "status": { + "id": 100, + "code": "loanStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "pendingApproval": true, + "waitingForDisbursal": false, + "active": false, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "loanType": { + "id": 3, + "code": "accountType.jlg", + "value": "JLG" + } + } + ], + "memberSavingsAccounts": [ + { + "id": 3, + "accountNo": "000000003", + "productId": 1, + "productName": "p_sav", + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountType": { + "id": 3, + "code": "accountType.jlg", + "value": "JLG" + } + }, + { + "id": 10, + "accountNo": "000000010", + "productId": 1, + "productName": "p_sav", + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountType": { + "id": 3, + "code": "accountType.jlg", + "value": "JLG" + } + } + ] +} + +
+
+ + +   +
+
+

Update a Group

+
+
+ +PUT https://DomainName/fineract-provider/api/v1/groups/{groupid} + + +PUT groups/1 +Content-Type: application/json +Request Body: +{ + "name": "First Group (changed)" +} + + +{ + "officeId": 1, + "groupId": 1, + "resourceId": 1, + "changes": { + "name": "First Group (changed)" + } +} + +
+
+ +   +
+
+

Delete a Group

+

A group can be deleted if it is in pending state and has no associations - clients, loans or savings

+
+
+ +POST https://DomainName/fineract-provider/api/v1/groups/{groupid} + + +DELETE groups/2 + + +{ + "officeId": 1, + "groupId": 2, + "resourceId": 2 +} + +
+
+ +   +
+
+

List Groups

+

The default implementation of listing Groups returns 200 entries with support for pagination and sorting. Using the parameter limit with value -1 returns all entries.

+
Optional Arguments
+
+
paged
+
+ Boolean optional, defaults to false +
+
If paged is true then results will be paginated.
+
offset
+
+ Integer optional, defaults to 0 +
+
Indicates from what result to start from.
+ +
limit
+
+ Integer optional, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
orderBy
+
+ String optional, one of displayName, accountNo, officeId, officeName +
+
Orders the results by the field indicated.
+ +
sortBy
+
+ String optional, one of ASC, DESC +
+
Indicates what way to order results if orderBy is used.
+ +
officeId
+
+ Integer optional +
+
Provides ability to restrict list of groups returned based on the office there associated with.
+
underHierarchy
+
+ String optional +
+
Use the office hierarchy string to return all groups under a given hierarchy.
+ +
name
+
+ String optional +
+
Use name of groups to restrict results.
+ +
externalId
+
+ String optional +
+
Use externalId of groups to restrict results.
+ +
sqlSearch
+
+ String optional +
+
Use an sql fragment valid for the underlying group schema to filter results. e.g. display_name like %K%
+
orphansOnly
+
+ Boolean optional, defaults to false +
+
Use orphansOnly as true to list groups which are not associated to any center/parent.
+
+

Example Requests:

+
groups
+
+
groups?fields=name,officeName,joinedDate
+
+
groups?offset=10&limit=50
+
+
groups?orderBy=name&sortOrder=DESC
+
+
+ +GET https://DomainName/fineract-provider/api/v1/groups?paged=true + + +{ + "totalFilteredRecords": 2, + "pageItems": [ + { + "id": 4, + "name": "AnotherGroup", + "status": { + "id": 100, + "code": "clientStatusType.pending", + "value": "Pending" + }, + "active": false, + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".4." + } + ] +} + +
+
+ + + +   +
+
+

Loans

+

The API concept of loans models the loan application process and the loan contract/monitoring process.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
accountNo
The account no. associated with this loan. Is auto generated if not provided at loan application creation time.
externalId
A place to put an external reference for + this loan e.g. The ID another system uses.
If provided, + it must be unique. +
fundId
Optional: For associating a loan with a given fund.
loanOfficerId
Optional: For associating a loan with a given staff member who is a loan officer.
loanPurposeId
Optional: For marking a loan with a given loan purpose option. Loan purposes are configurable and can be setup by system admin through code/code values screens.
principal
The loan amount to be disbursed to through loan.
loanTermFrequency
The length of loan term
Used like: + loanTermFrequency loanTermFrequencyType
e.g. 12 Months +
loanTermFrequencyType
The loan term period to use. Used like: + loanTermFrequency loanTermFrequencyType
e.g. 12 Months + Example Values: 0=Days, 1=Weeks, 2=Months, 3=Years +
numberOfRepayments
Number of installments to repay.
+ Used like: numberOfRepayments Every repaymentEvery + repaymentFrequencyType
e.g. 10 (repayments) Every 12 Weeks +
repaymentEvery
Used like: numberOfRepayments Every + repaymentEvery repaymentFrequencyType
e.g. 10 + (repayments) Every 12 Weeks +
repaymentFrequencyType
Used like: numberOfRepayments Every + repaymentEvery repaymentFrequencyType
e.g. 10 + (repayments) Every 12 Weeks
+ Example Values: 0=Days, 1=Weeks, 2=Months +
interestRatePerPeriod
Interest Rate.
Used like: + interestRatePerPeriod % interestRateFrequencyType - interestType
+ e.g. 12.0000% Per year - Declining Balance +
interestRateFrequencyType
Used like: interestRatePerPeriod% + interestRateFrequencyType - interestType
e.g. 12.0000% + Per year - Declining Balance
+ Example Values: 2=Per month, 3=Per year +
graceOnPrincipalPayment
Optional: Integer - represents the number of repayment periods that grace should apply to the principal component of a repayment period. +
graceOnInterestPayment
Optional: Integer - represents the number of repayment periods that grace should apply to the interest component of a repayment period. Interest is still calculated but offset to later repayment periods. +
graceOnInterestCharged
Optional: Integer - represents the number of repayment periods that should be interest-free. +
graceOnArrearsAgeing
Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue. +
interestChargedFromDate
Optional: Date - The date from with interest is to start being charged.
expectedDisbursementDate
The proposed disbursement date of the loan so a proposed repayment schedule can be provided.
submittedOnDate
The date the loan application was submitted by applicant.
linkAccountId
The Savings Account id for linking with loan account for payments.
amortizationType
Example Values: 0=Equal + principle payments, 1=Equal installments
interestType
Used like: interestRatePerPeriod% + interestRateFrequencyType - interestType
e.g. 12.0000% + Per year - Declining Balance
+ Example Values: 0=Declining Balance, 1=Flat +
interestCalculationPeriodType
Example Values: 0=Daily, 1=Same as repayment period
allowPartialPeriodInterestCalcualtion
This value will be supported along with interestCalculationPeriodType as Same as repayment period to calculate interest for partial periods. + Example: Interest charged from is 5th of April , Principal is 10000 and interest is 1% per month then the interest will be (10000 * 1%)* (25/30) , it calculates for the month first then calculates exact periods between start date and end date(can be a decimal) +
inArrearsTolerance
The amount that can be 'waived' at end + of all loan payments because it is too small to worry about.
+ This is also the tolerance amount assessed when determining if a + loan is in arrears. +
transactionProcessingStrategyId
+An enumeration that indicates the type of transaction processing strategy to be used. This relates to functionality that is also known as Payment Application Logic. + +

A number of out of the box approaches exist, some are custom to specific MFIs, some are more general and indicate the order in which payments are processed.

+ +

Refer to the Payment Application Logic / Transaction Processing Strategy section in the appendix for more detailed overview of each available payment application logic provided out of the box.

+ +List of current approaches:
+
    +
  • 1 = Mifos style (Similar to Old Mifos)
  • +
  • 2 = Heavensfamily (Custom MFI approach)
  • +
  • 3 = Creocore (Custom MFI approach)
  • +
  • 4 = RBI (India)
  • +
  • 5 = Principal Interest Penalties Fees Order
  • +
  • 6 = Interest Principal Penalties Fees Order
  • +
  • 7 = Early Payment Strategy
  • +
+ + +
loanType
To represent different type of loans.
+ At present there are three type of loans are supported. +
Available loan types: +
    +
  1. individual: Loan given to individual member
  2. +
  3. group: Loan given to group as a whole
  4. +
  5. jlg: Joint liability group loan given to members in a group on individual basis. JLG loan can be given to one or more members in a group.
  6. +
+
recalculationRestFrequencyDate
Specifies rest frequency start date for interest recalculation. This date must be before or equal to disbursement date +
recalculationCompoundingFrequencyDate
Specifies compounding frequency start date for interest recalculation. This date must be equal to disbursement date +
+
+
+ +   +
+
+

Retrieve Loan Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+
Arguments
+
+
templateType
+
+ String mandatory, allowed values are individual, group, jlg, jlgbulk +
+
+
templateType value decides the required template data for creating a new loan application. + +
+
+
'individual': Loan template data for creating individual loans. +
+
+ 'group': Loan template data for creating a group loan (loan given to group as a whole). +
+
+ 'jlg': Loan template data for creating a Joint liability group loan for a client. +
+
+ 'jlgbulk': Loan template data for creating a Joint liability group loan for multiple clients at a time in a group. +
+
clientId
+
+ Integer mandatory +
+
+
Optional Arguments
+
+
productId
+
+ Integer optional +
+
If entered, productId, productName and selectedProduct + fields are returned.
+ +
staffInSelectedOfficeOnly
+
+ Boolean optional +
+
Defaults to false if not provided. If staffInSelectedOfficeOnly=true only loan officers + who are associated with the selected branch are returned.
+
activeOnly
+
+ Boolean optional +
+
Defaults to false if not provided. If activeOnly=true only active loan products are returned.
+
+

Example Requests:

+
loans/template?templateType=individual&clientId=1
+
+
+
loans/template?templateType=individual&clientId=1&productId=1
+
+
+ +GET https://DomainName/api/v1/loans/template?templateType=individual&clientId=1 + + +{ + "clientId": 1, + "clientName": "Kampala first Client", + "clientOfficeId": 2, + "timeline": { + "expectedDisbursementDate": [ + 2013, + 3, + 8 + ] + }, + "productOptions": [ + { + "id": 1, + "name": "Kampala Product (with cash accounting)" + } + ] +} + + +GET https://DomainName/api/v1/loans/template?templateType=individual&clientId=1&productId=1 + + +{ + "clientId": 1, + "clientName": "Kampala first Client", + "clientOfficeId": 2, + "loanProductId": 1, + "loanProductName": "Kampala Product (with cash accounting)", + "loanProductDescription": "Typical Kampala loan product with cash accounting enabled for testing.", + "currency": { + "code": "UGX", + "name": "Uganda Shilling", + "decimalPlaces": 2, + "displaySymbol": "USh", + "nameCode": "currency.UGX", + "displayLabel": "Uganda Shilling (USh)" + }, + "principal": 1000000, + "termFrequency": 12, + "termPeriodFrequencyType": { + "id": 2, + "code": "repaymentFrequency.periodFrequencyType.months", + "value": "Months" + }, + "numberOfRepayments": 12, + "repaymentEvery": 1, + "repaymentFrequencyType": { + "id": 2, + "code": "repaymentFrequency.periodFrequencyType.months", + "value": "Months" + }, + "interestRatePerPeriod": 24, + "interestRateFrequencyType": { + "id": 3, + "code": "interestRateFrequency.periodFrequencyType.years", + "value": "Per year" + }, + "annualInterestRate": 24, + "amortizationType": { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + "interestType": { + "id": 1, + "code": "interestType.flat", + "value": "Flat" + }, + "interestCalculationPeriodType": { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + }, + "transactionProcessingStrategyId": 2, + "timeline": { + "expectedDisbursementDate": [ + 2013, + 3, + 8 + ] + }, + "daysInMonthType": { + "id": 30, + "code": "DaysInMonthType.days360", + "value": "30 Days" + }, + "daysInYearType": { + "id": 360, + "code": "DaysInYearType.days360", + "value": "360 Days" + }, + "isInterestRecalculationEnabled": true, + "interestRecalculationData": { + "interestRecalculationCompoundingType": { + "id": 2, + "code": "interestRecalculationCompoundingMethod.fee", + "value": "Fee" + }, + "recalculationCompoundingFrequencyType": { + "id":1, + "code":"interestRecalculationFrequencyType.same.as.repayment.period", + "value":"Same as repayment period" + }, + "rescheduleStrategyType": { + "id": 2, + "code": "loanRescheduleStrategyMethod.reduce.number.of.installments", + "value": "Reduce number of installments" + }, + "recalculationRestFrequencyType": { + "id":1, + "code":"interestRecalculationFrequencyType.same.as.repayment.period", + "value":"Same as repayment period" + } + } + "charges": [], + "productOptions": [ + { + "id": 1, + "name": "Kampala Product (with cash accounting)" + } + ], + "loanOfficerOptions": [ + { + "id": 2, + "firstname": "Kampala", + "lastname": "LoanOfficer", + "displayName": "LoanOfficer, Kampala", + "officeId": 2, + "officeName": "Uganda (Kampala)", + "isLoanOfficer": true + } + ], + "loanPurposeOptions": [ + { + "id": 20, + "name": "option.Agriculture", + "position": 1 + }, + { + "id": 21, + "name": "option.Manufacturing", + "position": 20 + }, + { + "id": 22, + "name": "option.HousingImprovement", + "position": 21 + } + ], + "termFrequencyTypeOptions": [ + { + "id": 0, + "code": "loanTermFrequency.periodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "loanTermFrequency.periodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "loanTermFrequency.periodFrequencyType.months", + "value": "Months" + }, + { + "id": 3, + "code": "loanTermFrequency.periodFrequencyType.years", + "value": "Years" + } + ], + "repaymentFrequencyTypeOptions": [ + { + "id": 0, + "code": "repaymentFrequency.periodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "repaymentFrequency.periodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "repaymentFrequency.periodFrequencyType.months", + "value": "Months" + } + ], + "interestRateFrequencyTypeOptions": [ + { + "id": 2, + "code": "interestRateFrequency.periodFrequencyType.months", + "value": "Per month" + }, + { + "id": 3, + "code": "interestRateFrequency.periodFrequencyType.years", + "value": "Per year" + } + ], + "amortizationTypeOptions": [ + { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + { + "id": 0, + "code": "amortizationType.equal.principal", + "value": "Equal principle payments" + } + ], + "interestTypeOptions": [ + { + "id": 1, + "code": "interestType.flat", + "value": "Flat" + }, + { + "id": 0, + "code": "interestType.declining.balance", + "value": "Declining Balance" + } + ], + "interestCalculationPeriodTypeOptions": [ + { + "id": 0, + "code": "interestCalculationPeriodType.daily", + "value": "Daily" + }, + { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + } + ], + "transactionProcessingStrategyOptions": [ + { + "id": 2, + "code": "heavensfamily-strategy", + "name": "Heavensfamily" + } + ], + "chargeOptions": [ + { + "id": 1, + "name": "Bank Fee (per installment)", + "active": true, + "penalty": false, + "currency": { + "code": "UGX", + "name": "Uganda Shilling", + "decimalPlaces": 2, + "displaySymbol": "USh", + "nameCode": "currency.UGX", + "displayLabel": "Uganda Shilling (USh)" + }, + "amount": 1500, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + } + } + ], + "loanCollateralOptions": [ + { + "id": 17, + "name": "option.House", + "position": 1 + }, + { + "id": 18, + "name": "option.Television", + "position": 17 + }, + { + "id": 19, + "name": "option.Gold", + "position": 18 + } + ], + "accountLinkingOptions":[ + { + "id":1, + "accountNo":"000000001", + "clientId":1, + "clientName":"pramod nuthakki", + "productId":1, + "productName":"pramod sav", + "fieldOfficerId":0, + "currency":{"code":"USD","name":"US Dollar","decimalPlaces":2,"displaySymbol":"$","nameCode":"currency.USD","displayLabel":"US Dollar ($)"} + } + ] +} + +
+
+ +   +
+
+

Retrieve a Loan

+

+ Note: template=true parameter doesn't apply to this resource. +

+
Arguments
+
+
associations
+
+ optional, Either 'all' or a comma separated list of + loan 'associations' (itemised below). +
+
exclude
+
+ optional, 'all' and a comma separated list of + loan associations (itemised below) as 'exclude'. +
+
+
Associations are just extra pieces of data that you + might or might not want to retrieve.
+
+
+
+ 'all': Gets all association data. +
+
+ 'repaymentSchedule': Loan schedule data. +
+
+ 'originalSchedule': Loan schedule data without interest recalculations. +
+
+ 'futureSchedule': Loan schedule data from today date(will be displayed only for interest first repayment strategy processors) +
+
+ 'transactions': Loan transactions data. +
+
+ 'charges': Loan charges data. +
+
+ 'guarantors': Loan guarantors data. +
+
+ 'collateral': Loan collateral data. +
+
+

Example Requests:

+
loans/1
+
+
+
loans/1?fields=id,principal,annualInterestRate
+
+
+
loans/1?associations=all
+
+
loans/1?associations=all&exclude=guarantors
+
+
+
loans/1?fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions
+
+
+ +GET https://DomainName/api/v1/loans/{loanId} + + +{ + "id": 1, + "accountNo": "000000001", + "status": { + "id": 300, + "code": "loanStatusType.active", + "value": "Active", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": true, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "clientId": 1, + "clientName": "Kampala first Client", + "clientOfficeId": 2, + "loanProductId": 1, + "loanProductName": "Kampala Product (with cash accounting)", + "loanProductDescription": "Typical Kampala loan product with cash accounting enabled for testing.", + "loanPurposeId": 22, + "loanPurposeName": "option.HousingImprovement", + "loanOfficerId": 2, + "loanOfficerName": "LoanOfficer, Kampala", + "loanType": { + "id": 1, + "code": "loanType.individual", + "value": "Individual" + }, + "currency": { + "code": "UGX", + "name": "Uganda Shilling", + "decimalPlaces": 2, + "displaySymbol": "USh", + "nameCode": "currency.UGX", + "displayLabel": "Uganda Shilling (USh)" + }, + "principal": 1000000, + "termFrequency": 12, + "termPeriodFrequencyType": { + "id": 2, + "code": "termFrequency.periodFrequencyType.months", + "value": "Months" + }, + "numberOfRepayments": 12, + "repaymentEvery": 1, + "repaymentFrequencyType": { + "id": 2, + "code": "repaymentFrequency.periodFrequencyType.months", + "value": "Months" + }, + "interestRatePerPeriod": 24, + "interestRateFrequencyType": { + "id": 3, + "code": "interestRateFrequency.periodFrequencyType.years", + "value": "Per year" + }, + "annualInterestRate": 24, + "amortizationType": { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + "interestType": { + "id": 1, + "code": "interestType.flat", + "value": "Flat" + }, + "interestCalculationPeriodType": { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + }, + "transactionProcessingStrategyId": 2, + "timeline": { + "submittedOnDate": [ + 2012, + 4, + 3 + ], + "submittedByUsername": "admin", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "approvedOnDate": [ + 2012, + 4, + 3 + ], + "approvedByUsername": "admin", + "approvedByFirstname": "App", + "approvedByLastname": "Administrator", + "expectedDisbursementDate": [ + 2012, + 4, + 10 + ], + "actualDisbursementDate": [ + 2012, + 4, + 10 + ], + "disbursedByUsername": "admin", + "disbursedByFirstname": "App", + "disbursedByLastname": "Administrator", + "expectedMaturityDate": [ + 2013, + 4, + 10 + ] + }, + "summary": { + "currency": { + "code": "UGX", + "name": "Uganda Shilling", + "decimalPlaces": 2, + "displaySymbol": "USh", + "nameCode": "currency.UGX", + "displayLabel": "Uganda Shilling (USh)" + }, + "principalDisbursed": 1000000, + "principalPaid": 0, + "principalWrittenOff": 0, + "principalOutstanding": 1000000, + "principalOverdue": 833333.3, + "interestCharged": 240000, + "interestPaid": 0, + "interestWaived": 0, + "interestWrittenOff": 0, + "interestOutstanding": 240000, + "interestOverdue": 200000, + "feeChargesCharged": 18000, + "feeChargesDueAtDisbursementCharged": 0, + "feeChargesPaid": 0, + "feeChargesWaived": 0, + "feeChargesWrittenOff": 0, + "feeChargesOutstanding": 18000, + "feeChargesOverdue": 15000, + "penaltyChargesCharged": 0, + "penaltyChargesPaid": 0, + "penaltyChargesWaived": 0, + "penaltyChargesWrittenOff": 0, + "penaltyChargesOutstanding": 0, + "penaltyChargesOverdue": 0, + "totalExpectedRepayment": 1258000, + "totalRepayment": 0, + "totalExpectedCostOfLoan": 258000, + "totalCostOfLoan": 0, + "totalWaived": 0, + "totalWrittenOff": 0, + "totalOutstanding": 1258000, + "totalOverdue": 1048333.3, + "overdueSinceDate": [ + 2012, + 5, + 10 + ], + "linkedAccount":{ + "id":1, + "accountNo":"000000001" + }, + "disbursementDetails":[{"id":71,"expectedDisbursementDate":[2013,11,1],"principal":22000.000000,"approvedPrincipal":22000.000000}], + "fixedEmiAmount":1100.000000, + "maxOutstandingLoanBalance":35000, + "canDisburse":false, + "emiAmountVariations": [], + "inArrears": true, + "isNPA":false, + "overdueCharges": [ + { + "id": 20, + "name": "overdraft penality", + "active": true, + "penalty": true, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 3.000000, + "chargeTimeType": { + "id": 9, + "code": "chargeTimeType.overdueInstallment", + "value": "overdue fees" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + }, + "feeInterval": 2, + "feeFrequency": { + "id": 1, + "code": "feeFrequencyperiodFrequencyType.weeks", + "value": "Weeks" + } + } + ] + } +} + +
+
+ +   +
+
+

List Loans

+

The list capability of loans can support pagination and sorting.

+
Optional Arguments
+
+
offset
+
+ Integer optional, defaults to 0 +
+
Indicates from what result to start from.
+ +
limit
+
+ Integer optional, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
orderBy
+
+ String optional, one of displayName, accountNo, officeId, officeName +
+
Orders the results by the field indicated.
+ +
sortBy
+
+ String optional, one of ASC, DESC +
+
Indicates what way to order results if orderBy is used.
+ +
officeId
+
+ Integer optional +
+
Provides ability to restrict list of loans returned based on the office there associated with.
+ +
underHierarchy
+
+ String optional +
+
Use the office hierarchy string to return all loans under a given hierarchy.
+ +
accountNo
+
+ String optional +
+
Use account no. of loans to restrict results.
+ +
externalId
+
+ String optional +
+
Use externalId of loan to restrict results.
+ +
sqlSearch
+
+ String optional +
+
Use an sql fragment valid for the underlying loan schema to filter results. e.g. display_name like %K%
+
+

Example Requests:

+
loans
+
+
loans?fields=accountNo
+
+
loans?offset=10&limit=50
+
+
loans?orderBy=accountNo&sortOrder=DESC
+
+
+ +GET https://DomainName/fineract-provider/api/v1/loans + + +{ + "totalFilteredRecords": 1, + "pageItems": [ + { + "id": 1, + "accountNo": "000000001", + "status": { + "id": 300, + "code": "loanStatusType.active", + "value": "Active", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": true, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "clientId": 1, + "clientName": "Change To IndividualName", + "clientOfficeId": 1, + "loanProductId": 1, + "loanProductName": "AgriCredit", + "loanProductDescription": "test", + "loanType": { + "id": 1, + "code": "loanType.individual", + "value": "Individual" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principal": 10000, + "termFrequency": 12, + "termPeriodFrequencyType": { + "id": 2, + "code": "termFrequency.periodFrequencyType.months", + "value": "Months" + }, + "numberOfRepayments": 12, + "repaymentEvery": 1, + "repaymentFrequencyType": { + "id": 2, + "code": "repaymentFrequency.periodFrequencyType.months", + "value": "Months" + }, + "interestRatePerPeriod": 2, + "interestRateFrequencyType": { + "id": 2, + "code": "interestRateFrequency.periodFrequencyType.months", + "value": "Per month" + }, + "annualInterestRate": 24, + "amortizationType": { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + "interestType": { + "id": 0, + "code": "interestType.declining.balance", + "value": "Declining Balance" + }, + "interestCalculationPeriodType": { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + }, + "transactionProcessingStrategyId": 2, + "timeline": { + "submittedOnDate": [ + 2012, + 6, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "approvedOnDate": [ + 2012, + 6, + 1 + ], + "approvedByUsername": "mifos", + "approvedByFirstname": "App", + "approvedByLastname": "Administrator", + "expectedDisbursementDate": [ + 2012, + 6, + 1 + ], + "actualDisbursementDate": [ + 2012, + 6, + 1 + ], + "disbursedByUsername": "mifos", + "disbursedByFirstname": "App", + "disbursedByLastname": "Administrator", + "expectedMaturityDate": [ + 2013, + 6, + 1 + ] + }, + "linkedAccount":{ + "id":1, + "accountNo":"000000001" + }, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principalDisbursed": 10000, + "principalPaid": 3073.07, + "principalWrittenOff": 0, + "principalOutstanding": 6926.93, + "principalOverdue": 5999.92, + "interestCharged": 1347.15, + "interestPaid": 709.33, + "interestWaived": 0, + "interestWrittenOff": 0, + "interestOutstanding": 637.82, + "interestOverdue": 619.28, + "feeChargesCharged": 0, + "feeChargesDueAtDisbursementCharged": 0, + "feeChargesPaid": 0, + "feeChargesWaived": 0, + "feeChargesWrittenOff": 0, + "feeChargesOutstanding": 0, + "feeChargesOverdue": 0, + "penaltyChargesCharged": 0, + "penaltyChargesPaid": 0, + "penaltyChargesWaived": 0, + "penaltyChargesWrittenOff": 0, + "penaltyChargesOutstanding": 0, + "penaltyChargesOverdue": 0, + "totalExpectedRepayment": 11347.15, + "totalRepayment": 3782.4, + "totalExpectedCostOfLoan": 1347.15, + "totalCostOfLoan": 709.33, + "totalWaived": 0, + "totalWrittenOff": 0, + "totalOutstanding": 7564.75, + "totalOverdue": 6619.2, + "overdueSinceDate": [ + 2012, + 11, + 1 + ] + }, + "feeChargesAtDisbursementCharged": 0, + "inArrears":false, + "isNPA":false + } + ] +} + +
+
+ +   +
+
+

Modify a loan application

+

Loan application can only be modified when in 'Submitted and pending approval' state. Once the application is approved, the details cannot be changed using this method.

+
+
+ PUT https://Domain Name/api/v1/loans/{loanId} + PUT loans/1 +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "productId": 1, + "principal": "5000", + "loanTermFrequency": 10, + "loanTermFrequencyType": 0, + "numberOfRepayments": 10, + "repaymentEvery": 1, + "repaymentFrequencyType": 0, + "interestRatePerPeriod": 2, + "interestType": 0, + "interestCalculationPeriodType": 0, + "amortizationType": 1, + "expectedDisbursementDate": "04 March 2014", + "transactionProcessingStrategyId": 1 +} + + +{ + "officeId": 2, + "clientId": 1, + "loanId": 1, + "resourceId": 1, + "changes": { + "principal": 5000, + "locale": "en" + } +} + +
+
+ +   +
+
+

Calculate loan repayment schedule

+ + + + + + + +
Mandatory Fields
productId, principal, loanTermFrequency, + loanTermFrequencyType, numberOfRepayments, repaymentEvery, + repaymentFrequencyType, interestRatePerPeriod, + amortizationType, interestType, + interestCalculationPeriodType, expectedDisbursementDate, + transactionProcessingStrategyId
+
+
+ +POST https://DomainName/api/v1/loans?command=calculateLoanSchedule + + +POST loans?command=calculateLoanSchedule +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en_GB", + "productId": 1, + "principal": "100,000.00", + "loanTermFrequency": 12, + "loanTermFrequencyType": 2, + "numberOfRepayments": 12, + "repaymentEvery": 1, + "repaymentFrequencyType": 2, + "interestRatePerPeriod": 2, + "amortizationType": 1, + "interestType": 0, + "interestCalculationPeriodType": 1, + "expectedDisbursementDate": "20 September 2011", + "transactionProcessingStrategyId": 2 +} + + +{ + "currency": { + "code": "UGX", + "name": "Uganda Shilling", + "decimalPlaces": 2, + "displaySymbol": "USh", + "nameCode": "currency.UGX", + "displayLabel": "Uganda Shilling (USh)" + }, + "loanTermInDays": 366, + "totalPrincipalDisbursed": 100000, + "totalPrincipalExpected": 100000, + "totalPrincipalPaid": 0, + "totalInterestCharged": 13471.52, + "totalFeeChargesCharged": 0, + "totalPenaltyChargesCharged": 0, + "totalWaived": 0, + "totalWrittenOff": 0, + "totalRepaymentExpected": 113471.52, + "totalRepayment": 0, + "totalOutstanding": 0, + "periods": [ + { + "period": 0, + "dueDate": [ + 2011, + 9, + 20 + ], + "principalDisbursed": 100000, + "principalLoanBalanceOutstanding": 100000, + "feeChargesDue": 0, + "feeChargesOutstanding": 0, + "totalOriginalDueForPeriod": 0, + "totalDueForPeriod": 0, + "totalOutstandingForPeriod": 0, + "totalOverdue": 0, + "totalActualCostOfLoanForPeriod": 0 + }, + { + "period": 1, + "fromDate": [ + 2011, + 9, + 20 + ], + "dueDate": [ + 2011, + 10, + 20 + ], + "daysInPeriod": 30, + "principalOriginalDue": 7455.96, + "principalDue": 7455.96, + "principalOutstanding": 7455.96, + "principalLoanBalanceOutstanding": 92544.04, + "interestOriginalDue": 2000, + "interestDue": 2000, + "interestOutstanding": 2000, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 9455.96, + "totalDueForPeriod": 9455.96, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 9455.96, + "totalOverdue": 9455.96, + "totalActualCostOfLoanForPeriod": 2000 + }, + ... + ... + { + "period": 12, + "fromDate": [ + 2012, + 8, + 20 + ], + "dueDate": [ + 2012, + 9, + 20 + ], + "daysInPeriod": 31, + "principalOriginalDue": 9270.56, + "principalDue": 9270.56, + "principalOutstanding": 9270.56, + "principalLoanBalanceOutstanding": 0, + "interestOriginalDue": 185.4, + "interestDue": 185.4, + "interestOutstanding": 185.4, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 9455.96, + "totalDueForPeriod": 9455.96, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 9455.96, + "totalOverdue": 9455.96, + "totalActualCostOfLoanForPeriod": 185.4 + } + ] +} + +
+
+ +   +
+
+

Submit a new Loan Application

+ + + + + + + +
Mandatory Fields
clientId, productId, principal, loanTermFrequency, + loanTermFrequencyType, loanType, numberOfRepayments, repaymentEvery, + repaymentFrequencyType, interestRatePerPeriod, + amortizationType, interestType, + interestCalculationPeriodType, transactionProcessingStrategyId, + expectedDisbursementDate, submittedOnDate, loanType
+
+ + + + + + + +
Additional Mandatory Fields if interest recalculation is enabled for product and Rest frequency not same as repayment period
recalculationRestFrequencyDate
+ + + + + + + +
Additional Mandatory Fields if interest recalculation with interest/fee compounding is enabled for product and compounding frequency not same as repayment period
recalculationCompoundingFrequencyDate
+
+ + + + + + + +
Optional Fields
graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId, allowPartialPeriodInterestCalcualtion, + fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAgeing, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true) +
+
+
+ +POST https://DomainName/api/v1/loans + + +POST loans +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en_GB", + "clientId": 1, + "productId": 1, + "principal": "10,000.00", + "loanTermFrequency": 12, + "loanTermFrequencyType": 2, + "loanType": "individual", + "numberOfRepayments": 10, + "repaymentEvery": 1, + "repaymentFrequencyType": 2, + "interestRatePerPeriod": 10, + "amortizationType": 1, + "interestType": 0, + "interestCalculationPeriodType": 1, + "transactionProcessingStrategyId": 1, + "expectedDisbursementDate": "10 Jun 2013", + "submittedOnDate": "10 Jun 2013", + "linkAccountId" : "1", + "fixedEmiAmount":1100, + "maxOutstandingLoanBalance":"35000", + "disbursementData":[{"expectedDisbursementDate":"01 November 2013", + "principal":22000,"approvedPrincipal":22000}] +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Approve Loan Application

+ + + + + + + +
Mandatory Fields
approvedOnDate
+
+ + + + + + + + + + +
Optional Fields
approvedLoanAmount
expectedDisbursementDate
+
+
+ +POST https://DomainName/api/v1/loans/{loanId}?command=approve + + +POST loans/1?command=approve +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "20 September 2011", + "expectedDisbursementDate" : "20 September 2011", + "note": "Loan approval note", + "disbursementData" : [{ id=226, principal="5", expectedDisbursementDate="20 September 2011"}, + { id=227, principal="91", expectedDisbursementDate="21 September 2011"}] +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 200, + "code": "loanStatusType.approved", + "value": "Approved", + "pendingApproval": false, + "waitingForDisbursal": true, + "active": false, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "20 September 2011", + "note": "Loan approval note" + } +} + +
+
+ + +   +
+
+

Recover Loan Guarantee

+
+
+ +POST https://DomainName/api/v1/loans/{loanId}?command=recoverGuarantees + + +POST loans/1?command=approve +Content-Type: application/json +No Request Body: + + +{ + + "loanId": 1 +} + +
+
+ +   +
+
+

Undo Loan Application Approval

+
+
+ +POST https://DomainName/api/v1/loans/{loanId}?command=undoApproval + + +POST loans/1?command=undoApproval +Content-Type: application/json +Request Body: +{ + "note": "Loan undo approval note" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 100, + "code": "loanStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "pendingApproval": true, + "waitingForDisbursal": false, + "active": false, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "approvedOnDate": "" + } +} + +
+
+ +   +
+
+

Assign a Loan Officer

+

Allows you to assign Loan Officer for existing Loan.

+
+
+ POST https://Domain Name/api/v1/loans/{loanId}?command=assignLoanOfficer + POST loans/1?command=assignLoanOfficer +Content-Type: application/json +Request Body: +{ + "toLoanOfficerId":2, + "assignmentDate":"02 September 2014", + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "fromLoanOfficerId":"" +} + + +{ + "officeId": 2, + "clientId": 6, + "loanId" : 3, + "resourceId": 3 +} + +
+
+ +   +
+
+

Unassign a Loan Officer

+

Allows you to unassign the Loan Officer.

+
+
+ POST https://Domain Name/api/v1/loans/{loanId}?command=unassignLoanOfficer + POST clients/1?command=unassignLoanOfficer +Content-Type: application/json +Request Body: +{ + "unassignedDate":"15 September 2014", + "locale":"en", + "dateFormat":"dd MMMM yyyy" +} + + +{ + "officeId":2, + "clientId":6, + "loanId":3, + "resourceId":3 +} + +
+
+ +   +
+
+

Reject Loan Application

+ + + + + + + +
Mandatory Fields
rejectedOnDate
+
+
+ +POST https://DomainName/api/v1/loans/{loanId}?command=reject + + +POST loans/1?command=reject +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "20 September 2011", + "note": "Loan rejection reason." +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 500, + "code": "loanStatusType.rejected", + "value": "Rejected", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": false, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "20 September 2011", + "closedOnDate": "20 September 2011" + } +} + +
+
+ +   +
+
+

Applicant Withdraws from Loan Application

+ + + + + + + +
Mandatory Fields
withdrawnOnDate
+
+
+ +POST https://DomainName/api/v1/loans/{loanId}?command=withdrawnByApplicant + + +POST loans/1?command=withdrawnByApplicant +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "withdrawnOnDate": "20 September 2011", + "note": "Reason loan applicant withdrew from application." +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 2, + "resourceId": 2, + "changes": { + "status": { + "id": 400, + "code": "loanStatusType.withdrawn.by.client", + "value": "Withdrawn by applicant", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": false, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "withdrawnOnDate": "20 September 2011", + "closedOnDate": "20 September 2011" + } +} + +
+
+ +   +
+
+

Disburse Loan

+ + + + + + + +
Mandatory Fields
actualDisbursementDate
+
+ + + + + + + +
Optional Fields
transactionAmount,fixedEmiAmount
+
+
+ +POST https://DomainName/api/v1/loans/{loanId}?command=disburse + + +POST loans/1?command=disburse +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "transactionAmount":10000, + "fixedEmiAmount""1100, + "actualDisbursementDate": "14 May 2013", + "paymentTypeId": "12", + "note": "", + "accountNumber": "accno123", + "checkNumber": "chec123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 1, + "changes": { + "accountNumber": "accno123", + "checkNumber": "chec123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123", + "status": { + "id": 300, + "code": "loanStatusType.active", + "value": "Active", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": true, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "actualDisbursementDate": "14 May 2013", + "transactionAmount":10000 + } +} + +
+
+ +   +
+
+

Disburse Loan To Savings Account

+ + + + + + + +
Mandatory Fields
actualDisbursementDate
+
+ + + + + + + +
Optional Fields
transactionAmount,fixedEmiAmount
+
+
+ +POST https://DomainName/api/v1/loans/{loanId}?command=disburseToSavings + + +POST loans/1?command=disburse +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "transactionAmount":10000, + "fixedEmiAmount""1100, + "actualDisbursementDate": "14 May 2013", + "note": "" + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 300, + "code": "loanStatusType.active", + "value": "Active", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": true, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "actualDisbursementDate": "14 May 2013", + "transactionAmount":10000 + } +} + +
+
+ +  +
+
+

Undo Loan Disbursal

+
+
+ +POST https://DomainName/api/v1/loans/{loanId}?command=undoDisbursal + + +POST loans/1?command=undoDisbursal +Content-Type: application/json +{ + "note": "Some comment" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 200, + "code": "loanStatusType.approved", + "value": "Approved", + "pendingApproval": false, + "waitingForDisbursal": true, + "active": false, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "actualDisbursementDate": "" + } +} + +
+
+ +   +
+
+

Delete a Loan Application

+

+ Note: Only loans in "Submitted and awaiting approval" + status can be deleted. +

+
+
+ +DELETE https://DomainName/api/v1/loans/{loanId} + + +DELETE loans/1 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 1 +} + +
+
+ + +   +
+
+

Loan Transactions

+

Capabilities include loan repayment's, interest waivers and the ability to 'adjust' an existing transaction. An 'adjustment' of a transaction is really a 'reversal' of existing transaction followed by creation of a new transaction with the provided details.

+ + + + + + + + + + + + + + + + +
Field Descriptions
transactionAmount
The amount of the transaction.
transactionDate
The date of the transaction.
+
+
+ +   +
+
+

Retrieve Loan Transaction Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+
Arguments
+
+
command
+
+ String mandatory, case-insensitive +
+
+ 'repayment'
"date" is set to the date of the + first outstanding installment.
"total" "amount" is set + to the amount outstanding. +
+
+ 'waiver'
"date" is set to the current date.
+ "total" "amount" is set to the remaining loan principal + outstanding. The amount that can be waived is limited to the + loan's inArrearsTolerance +
+
+ 'refundbycash'
"date" is set to the current date
+ "total" "amount" is set + to the total amount paid in advance. +
+
+

Example Request:

+
loans/1/transactions/template?command=repayment
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/transactions/template" + + +{ + "transactionType": { + "id": 2, + "code": "loanTransactionType.repayment", + "value": "Repayment" + }, + "date": [ + 2009, + 8, + 1 + ], + "total": { + "currencyCode": "XOF", + "digitsAfterDecimal": 0, + "inMultiplesOf": 0, + "amount": 471, + "defaultName": "CFA Franc BCEAO", + "nameCode": "currency.XOF", + "displaySymbol": "CFA", + "zero": false, + "greaterThanZero": true, + "displaySymbolValue": "471 CFA" + } +} + +
+
+ +   +
+
+

Make a Repayment

+
+
+ +POST https://DomainName/api/v1/loans/{loanId}/transactions?command=repayment + + +POST loans/5/transactions?command=repayment +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "transactionDate": "14 May 2013", + "transactionAmount": "500.00", + "paymentTypeId": "12", + "note": "check payment", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 5, + "resourceId": 564, + "changes": { + "transactionDate": "14 May 2013", + "transactionAmount": "500.00", + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "note": "check payment", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ +   +
+
+

Make a Refund of an Active Loan by Cash

+
+
+ +POST https://DomainName/api/v1/loans/{loanId}/transactions?command=refundByCash + + +POST loans/5/transactions?command=refundByCash +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "transactionDate": "14 May 2013", + "transactionAmount": "500.00", + "paymentTypeId": "12" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 5, + "resourceId": 564, + "changes": { + "transactionDate": "14 May 2013", + "transactionAmount": "500.00", + "locale": "en", + "dateFormat": "dd MMMM yyyy + } +} + +
+
+ + +   +
+
+

Waive Interest

+
+
+ +POST https://DomainName/api/v1/loans/{loanId}/transactions?command=waiveInterest + + +POST loans/5/transactions?command=waiveInterest +Content-Type: application/json +Request Body: +{ + "locale": "en_GB", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "14 May 2012", + "transactionAmount": "400", + "note": "Optional note related to the waiving of interest." +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 5, + "resourceId": 5, + "changes": { + "transactionDate": "14 May 2012", + "transactionAmount": "400", + "locale": "en_GB", + "dateFormat": "dd MMMM yyyy", + "note": "Optional note related to the interest waiver." + } +} + +
+
+ + +   +
+
+

Write-off Loan

+
+
+ + POST https://DomainName/api/v1/loans/{loanId}/transactions?command=writeoff + + + POST loans/70/transactions?command=writeoff + Content-Type: application/json + Request Body: + { + "locale": "en_GB", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "14 May 2012", + "note": "Write-off note" + } + + + { + "officeId": 1, + "clientId": 7, + "loanId": 70, + "resourceId": 442, + "changes": { + "transactionDate": "1 March 2012", + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "status": { + "id": 601, + "code": "loanStatusType.closed.written.off", + "value": "Closed (written off)", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": false, + "closedObligationsMet": false, + "closedWrittenOff": true, + "closedRescheduled": false, + "closed": true, + "overpaid": false + }, + "closedOnDate": "1 March 2012", + "writtenOffOnDate": "1 March 2012", + "note": "Write-off note" + } + } + + +
+
+ +   +
+
+

Make Recovery Payment

+

This API allows collecting recovery payments for written-off loans

+
+
+ +POST https://DomainName/api/v1/loans/{loanId}/transactions?command=recoverypayment + + +POST loans/5/transactions?command=recoverypayment +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "transactionDate": "14 May 2013", + "transactionAmount": "500.00", + "paymentTypeId": "12", + "note": "check payment", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 5, + "resourceId": 564, + "changes": { + "transactionDate": "14 May 2013", + "transactionAmount": "500.00", + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "note": "check payment", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ + + + +   +
+
+

Undo Loan Write-off Transaction

+
+
+ + POST https://DomainName/api/v1/loans/{loanId}/transactions?command=undowriteoff + + + POST loans/70/transactions?command=undowriteoff + Content-Type: application/json + Request Body: + { } + + + + { + "officeId": 1, + "clientId": 1, + "loanId": 22 + } + +
+
+ + +   +
+
+

Pre-Close template

+

This Api retrieves pre closure details of loan

+
+
+ + POST https://DomainName/api/v1/loans/{loanId}/transactions?command=prepayLoan or
+ + https://DomainName/api/v1/loans/{loanId}/transactions?command=prepayLoan&dateFormat=dd+MMMM+yyyy&locale=en&transactionDate=02+April+2015 +
+ + POST loans/70/transactions?command=prepayLoan + Content-Type: application/json + Request Body: + { } + + + + { + "amount":7765.28, + "principalPortion":7573.76, + "interestPortion":191.52, + "feeChargesPortion":0.00, + "penaltyChargesPortion":0.00 + } + +
+
+ +   +
+
+

Retrieve a Transaction Details

+

Example Request:

+
loans/5/transactions/3
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/transactions/{transactionId} + + +{ + "id": 3, + "type": { + "id": 2, + "code": "loanTransactionType.repayment", + "value": "Repayment", + "disbursement": false, + "repaymentAtDisbursement": false, + "repayment": true, + "contra": false, + "waiveInterest": false, + "waiveCharges": false, + "writeOff": false, + "recoveryRepayment": false + }, + "date": [ + 2012, + 5, + 14 + ], + "manuallyReversed": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 559.88, + "interestPortion": 559.88 +} + +
+
+ +   +
+
+

Adjust a Transaction

+

Note: there is no need to specify command={transactionType} parameter.

+ + + + + + + +
Mandatory Fields
transactionDate, transactionAmount
+
+
+ +POST https://DomainName/api/v1/loans/{loanId}/transactions/{transactionId} + + +POST loans/1/transactions/2 +Content-Type: application/json +Request Body: +{ + "locale": "en_GB", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "25 May 2012", + "transactionAmount": "50,000.00", + "note": "An optional note about why your adjusting or changing the transaction." +} + + +{ + "resourceId": 16 +} + +
+
+ + + +   +
+
+

Guarantors

+

A person who guarantees to pay for someone else's debt + if he or she should default on a loan obligation. A guarantor acts as a co-signor of sorts. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
guarantorType
Identifies if the guarantor is + an existing Client, Staff member or an external + individual
+ Refer Retrieve + Guarantor Details Template for complete + details +
entityId
The identifier for guarantors + who are an existing Client of Staff member. +
firstname
Guarantors first name +
lastname
Guarantors last name +
officeName
Name of the office with which the internal guarantors are associated +
addressLine1, addressLine2, city, state, zip, + country, mobileNumber, housePhoneNumber, comment, + dob
Address, contact and date of + birth details of an external guarantor +
savingsId
Guarantors Savings Account on which Amount will be blocked +
amount
Guarantee amount which will be blocked on savings account. +
+
+
+ +   +
+
+

List Guarantors

+

Example Requests:

+
loans/1/guarantors
+
+
+
loans/1/guarantors?fields=firstname,lastname
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/guarantors + + +[ + { + "id": 1, + "loanId": 1, + "guarantorType": { + "id": 1, + "code": "guarantor.existing.customer", + "value": "CUSTOMER" + }, + "firstname": "Declan", + "lastname": "Browne", + "officeName": "Head Office", + "joinedDate": [ + 2009, + 1, + 4 + ] + } +] + +
+
+ +   +
+
+

Retrieve Guarantors Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
loans/1/guarantors/template
+
loans/1/guarantors/accounts/template?clientId=1
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/guarantors/template + + +{ + "guarantorType": { + "id": 1, + "code": "guarantor.existing.customer", + "value": "CUSTOMER" + }, + "guarantorTypeOptions": [ + { + "id": 1, + "code": "guarantor.existing.customer", + "value": "CUSTOMER" + }, + { + "id": 2, + "code": "guarantor.staff", + "value": "STAFF" + }, + { + "id": 3, + "code": "guarantor.external", + "value": "EXTERNAL" + } + ] +} + + +GET https://DomainName/api/v1/loans/{loanId}/guarantors/accounts/template?clientId={clientId} + + +{ + "guarantorType": { + "id": 1, + "code": "guarantor.existing.customer", + "value": "CUSTOMER" + }, + "status": false, + "accountLinkingOptions": [ + { + "id": 1, + "accountNo": "000000001", + "clientId": 3, + "clientName": "Client_FirstName_UUV18 Client_LastName_9T2D", + "productId": 1, + "productName": "FIXED_DEPOSIT_PRODUCT_U0NS9T", + "fieldOfficerId": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 4, + "inMultiplesOf": 100, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ] +} + +
+
+ +   +
+
+

Retrieve a Guarantor

+

Example Requests:

+
/loans/1/guarantors/1
+
+
+
/loans/1/guarantors/1
+
+
+
/loans/1/guarantors/1?fields=firstname
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/guarantors/{guarantorId} + + +{ + "id": 1, + "loanId": 1, + "guarantorType": { + "id": 1, + "code": "guarantor.existing.customer", + "value": "CUSTOMER" + }, + "firstname": "Declan", + "officeName": "Head Office", + "joinedDate": [ + 2009, + 1, + 4 + ] +} + +
+
+ +   +
+
+

Create a Guarantor

+

+ Note: You may associate any number of Guarantors + to a Loan. The mandatory fields would vary based + on the "guarantorType"
+

+ + + + + + + + + + + + + +
Mandatory Fields + for "internal" guarantors
guarantorTypeId, entityId
Mandatory Fields for "external" guarantors
guarantorTypeId, firstname, lastname
+ + + + + + + +
Optional Fields + for "internal" guarantors
savingsId, amount
+
+
+ +POST https://DomainName/api/v1//loans/{loanId}}/guarantors + + +POST /loans/1/guarantors +Content-Type: application/json +Request Body: +{ + guarantorTypeId:3, + firstname:Lyndon, + lastname:Johnson +} + + +{ + "officeId": 2, + "loanId": 1, + "resourceId": 9 +} + + +POST /loans/1/guarantors +Content-Type: application/json +Request Body: +{ + guarantorTypeId:1, + entityId:2 +} + + +{ + "officeId": 2, + "loanId": 1, + "resourceId": 10 +} + +
+
+ +   +
+
+

Update a Guarantor

+
+
+ +PUT https://DomainName/api/v1/loans/{loanId}/guarantors/{guarantorId} + + +PUT loans/1/guarantors/1 +Content-Type: application/json +Request Body: +{ + entityId:1 +} + + +{ + "officeId": 1, + "resourceId": 1, + "changes": { + "entityId": 1 + } +} + +
+
+ +   +
+
+

Remove a Guarantor

+

+ Note: A guarantor can be removed only from loans that are not yet approved. +

+
+
+ +DELETE https://DomainName/api/v1/loans/{loanId}/guarantors/{guarantorId} +DELETE https://DomainName/api/v1/loans/{loanId}/guarantors/{guarantorId}?guarantorFundingId={guarantorFundingId} + + + +DELETE loans/1/guarantors/1 +DELETE loans/1/guarantors/1?guarantorFundingId=1 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 2, + "loanId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Loan Collateral

+

In lending agreements, collateral is a borrower's pledge of specific property to a lender, + to secure repayment of a loan. The collateral serves as protection for a lender against a + borrower's default - that is, any borrower failing to pay the principal and interest under + the terms of a loan obligation. If a borrower does default on a loan (due to insolvency + or other event), that borrower forfeits (gives up) the property pledged as collateral + - and the lender then becomes the owner of the collateral +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
type
Identifies the type of a collateral
+ Ex: Gold, property etc (permitted types can be configured using + Code Values for + the Code LoanCollateral)
+ Refer Retrieve + Collateral Details Template for complete + details +
value
The market value of a Collateral. +
description
Description for the collateral +
currency
Details of the currency used + to estimate the value of a Collateral. + The currency defaults to the currency of the + Loan for which this Collateral serves as a + guarantee +
+
+
+ +   +
+
+

List Loan Collaterals

+

Example Requests:

+
loans/1/collaterals
+
+
+
loans/1/collaterals?fields=value,description
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/collaterals + + +[ + { + "id": 12, + "type": { + "id": 8, + "name": "Gold" + }, + "value": 50000, + "description": "24 Carat Gold chain weighing 12 grams", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } +] + +
+
+ +   +
+
+

Retrieve Collateral Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
loans/1/collaterals/template
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/collaterals/template + + +{ + "allowedCollateralTypes": [ + { + "id": 9, + "name": "Silver", + "position": 0 + }, + { + "id": 8, + "name": "Gold", + "position": 0 + }, + { + "id": 10, + "name": "Property", + "position": 0 + } + ] +} + +
+
+ +   +
+
+

Retrieve a Collateral

+

Example Requests:

+
/loans/1/collaterals/1
+
+
+
/loans/1/collaterals/1?fields=value,description
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/collaterals/{guarantorId} + + +{ + "id": 12, + "type": { + "id": 8, + "name": "Gold" + }, + "value": 50000, + "description": "24 Carat Gold chain weighing 12 grams", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } +} +
+
+ +   +
+
+

Create a Collateral

+

+ Note: Currently, Collaterals may be added only before a Loan + is approved
+

+ + + + + + + +
Mandatory Fields + for "internal" collaterals
collateralTypeId
+
+
+ +POST https://DomainName/api/v1//loans/{loanId}/collaterals + + +POST /loans/1/collaterals +Content-Type: application/json +Request Body: +{ + collateralTypeId:9, +} + + +{ + "loanId": 1, + "resourceId": 12 +} + + +POST /loans/1/collaterals +Content-Type: application/json +Request Body: +{ + "collateralTypeId":"8", + "value": "50000", + "dateFormat":"dd MMMM yyyy", + "locale": "en", + "description": "24 Carat Gold chain weighing 12 grams" +} + + +{ + "loanId": 1, + "resourceId": 13 +} + +
+
+ +   +
+
+

Update a Collateral

+
+
+ +PUT https://DomainName/api/v1/loans/{loanId}/collaterals/{collateralId} + + +PUT loans/1/collaterals/12 +Content-Type: application/json +Request Body: +{ +"description": "22 Carat Gold chain weighing 12 grams" +} + + +{ + "loanId": 1, + "resourceId": 12, + "changes": { + "description": "22 Carat Gold chain weighing 12 grams" + } +} + +
+
+ +   +
+
+

Remove a Collateral

+

+ Note: A collateral can only be removed from Loans that are not yet approved. +

+
+
+ +DELETE https://DomainName/api/v1/loans/{loanId}/collaterals/{collateralId} + + +DELETE loans/1/collaterals/13 +Content-Type: application/json +No Request Body: + + +{ + "loanId": 1, + "resourceId": 13 +} + +
+
+ + +   +
+
+

Loan Charges

+

Its typical for MFIs to add extra costs for their loan products. They + can be either Fees or Penalties.

+

Loan Charges are instances of Charges and + represent either fees and penalties for loan products. Refer Charges + for documentation of the various properties of a charge, Only additional properties ( + specific to the context of a Charge being associated with a Loan) are + described here

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
amountPaid
The Total amount which has been paid for this Charge +
amountWaived
The Total amount that has been waived for this Charge +
amountWrittenOff
Total amount written off from this Charge +
amountOutstanding
The Total outstanding amount for this Charge +
+
+
+ +   +
+
+

List Loan Charges

+

Example Requests:

+
loans/1/charges
+
+
+
loans/1/charges?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/charges + + +[ + { + "id": 1, + "chargeId": 1, + "name": "Loan Processing fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + }, + { + "id": 7, + "chargeId": 2, + "name": "Collection Fee", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2013, + 3, + 29 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + } +] + +
+
+ +   +
+
+

Retrieve Loan Charges Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
loans/1/charges/template
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/charges/template + + +{ + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "chargeOptions": [ + { + "id": 2, + "name": "Collection Fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + } + }, + { + "id": 3, + "name": "Late payment penalty", + "active": true, + "penalty": true, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 1, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + } + }, + { + "id": 1, + "name": "Loan Processing fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + } + } + ], + "penalty": false +} + +
+
+ +   +
+
+

Retrieve a Loan Charge

+

Example Requests:

+
/loans/1/charges/1
+
+
+
/loans/1/charges/1?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/loans/{loanId}/charges/{chargeId} + + +{ + "id": 1, + "chargeId": 1, + "name": "Loan Processing fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false +} +
+
+ +   +
+
+

Create a Loan Charge

+ + + + + + + +
Mandatory Fields + for Loan Charges
chargeId, amount, dueDate
+
+
+ +POST https://DomainName/api/v1/loans/{loanId}/charges + + +POST /loans/1/charges +Content-Type: application/json +Request Body: +{ + "chargeId": "2", + "locale": "en", + "amount": "100", + "dateFormat": "dd MMMM yyyy", + "dueDate": "29 April 2013" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 31 +} + +
+
+ +   +
+
+

Update a Loan Charge

+

Currently Loan Charges may be updated only if the Loan + is not yet approved +

+
+
+ +PUT https://DomainName/api/v1/loans/{loanId}/charges/{chargeId} + + +PUT loans/1/charges/12 +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "amount": "60", + "dueDate": "27 March 2013" +} + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 6, + "changes": { + "dueDate": "27 March 2013", + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "amount": 60.0 + } +} + +
+
+ +   +
+
+

Pay Loan Charge

+

Loan Charge will be paid if the loan is linked with a savings account +

+
+
+ +POST https://DomainName/api/v1/loans/{loanId}/charges/{chargeId}?command=pay + + +POST loans/1/charges/12?command=pay +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "transactionDate": "19 September 2013" +} + + + + + { + "officeId": 1, + "clientId": 1, + "loanId": 6, + "savingsId": 1, + "resourceId": 12 + } + + +
+
+   +
+
+

Delete a Loan Charge

+

+ Note:Currently, A Loan Charge may only be removed from Loans that are not + yet approved. +

+
+
+ +DELETE https://DomainName/api/v1/loans/{loanId}/charges/{chargeId} + + +DELETE loans/1/charges/2 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "loanId": 1, + "resourceId": 2 +} + +
+
+ + +  +
+
+

Loan Rescheduling

+

Loan rescheduling provides the ability to give clients extra grace periods, extend loan term by adding extra installments and adjust the interest rate of a loan.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
loanId
The ID of the loan to be rescheduled.
rescheduleFromDate
Due date of the start point (installment) of the rescheduling.
graceOnPrincipal
Number of installments to be added with zero principal.
graceOnInterest
Number of installments to be added with zero interest.
extraTerms
Number of installments to be added after the last loan repayment schedule installment.
recalculateInterest
If recalculateInterest="true", the total interest amount of the loan is recalculated. If recalculateInterest="false", the total interest amount remains the same.
newInterestRate
New interest rate to be used in calculating the interest amount for each rescheduled period/installment.
adjustedDueDate
New due date for the start point (installment) of the rescheduling.
rescheduleReasonId
The ID of the code value that indicates the reason for rescheduling the loan.
rescheduleReasonComment
Text provided as extra reason for the rescheduling of the loan.
submittedOnDate
The date on which the loan reschedule request was made.
+
+
+ +   +
+
+

Create a Loan Reschedule Request

+ + + + + + + +
Mandatory Fields
loanId, rescheduleFromDate, rescheduleReasonId, submittedOnDate,
+ graceOnPrincipal OR graceOnInterest OR extraTerms OR newInterestRate OR adjustedDueDate +
+
+ + + + + + + +
Optional Fields
recalculateInterest, rescheduleReasonComment
+
+
+ +POST https://DomainName/api/v1/rescheduleloans + + +POST rescheduleloans +Content-Type: application/json Request Body: +{ + "loanId": 1, + "graceOnPrincipal": 2, + "graceOnInterest": 3, + "extraTerms": 2, + "rescheduleFromDate": "04 December 2014", + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "recalculateInterest": true, + "submittedOnDate": "04 September 2014", + "newInterestRate" : 28, + "rescheduleReasonId": 1 +} + + +{ + "loanId": 1, + "resourceId": 1 +} + +
+
+ +POST rescheduleloans +Content-Type: application/json Request Body: +{ + "loanId": 1, + "graceOnPrincipal": 2, + "rescheduleFromDate": "04 December 2014", + "adjustedDueDate": "20 December 2014", + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "submittedOnDate": "04 September 2014", + "rescheduleReasonComment" : "Client has gone AWOL", + "rescheduleReasonId": 1 +} + + +{ + "loanId": 1, + "resourceId": 1 +} + +
+
+   +
+
+

Retrieve a Loan Reschedule Request

+

Example Requests:

+
rescheduleloans/1
+
+
+ +GET https://DomainName/api/v1/rescheduleloans/{requestId} + + +{ + "id": 2, + "loanId": 17, + "clientId": 4, + "clientName": "Fernando Michael Torres", + "loanAccountNumber": "000000017", + "statusEnum": { + "id": 500, + "code": "loanStatusType.rejected", + "value": "Rejected", + "pendingApproval": false, + "approved": false, + "rejected": true + }, + "rescheduleFromInstallment": 5, + "graceOnPrincipal": 3, + "rescheduleFromDate": [ + 2013, + 12, + 6 + ], + "recalculateInterest": false, + "rescheduleReasonCodeValue": { + "id": 239, + "name": "client cannot pay on time" + }, + "timeline": { + "submittedOnDate": [ + 2014, + 8, + 4 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "rejectedOnDate": [ + 2014, + 8, + 5 + ], + "rejectedByUsername": "mifos", + "rejectedByFirstname": "App", + "rejectedByLastname": "Administrator" + }, + "rescheduleReasonComment": "" +} + +
+
+   +
+
+

Retrieve a Preview of The New Loan Repayment Schedule

+

Example Requests:

+
rescheduleloans/1?command=previewLoanReschedule
+
+
+ +GET https://DomainName/api/v1/rescheduleloans/{requestId}?command=previewLoanReschedule + + + + "currency": { + "code": "KES", + "name": "Kenyan Shilling", + "decimalPlaces": 0, + "inMultiplesOf": 10, + "displaySymbol": "KSh", + "nameCode": "currency.KES", + "displayLabel": "Kenyan Shilling (KSh)" + }, + "loanTermInDays": 182, + "totalPrincipalDisbursed": 10000, + "totalPrincipalExpected": 10000, + "totalPrincipalPaid": 900.000000, + "totalInterestCharged": 960, + "totalFeeChargesCharged": 0.000000, + "totalPenaltyChargesCharged": 2500.000000, + "totalRepaymentExpected": 13460, + "totalOutstanding": 12060.000000, + "periods": [ + { + "period": 1, + "fromDate": [ + 2013, + 11, + 8 + ], + "dueDate": [ + 2013, + 11, + 8 + ], + "daysInPeriod": 0, + "principalOriginalDue": 0, + "principalDue": 0, + "principalOutstanding": 0, + "principalLoanBalanceOutstanding": 10000, + "interestOriginalDue": 0, + "interestDue": 0, + "interestOutstanding": 0, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 0, + "totalDueForPeriod": 0, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 0, + "totalOverdue": 0, + "totalActualCostOfLoanForPeriod": 0 + }, + ... + ... + { + "period": 30, + "fromDate": [ + 2014, + 5, + 23 + ], + "dueDate": [ + 2014, + 5, + 30 + ], + "daysInPeriod": 7, + "principalOriginalDue": 300, + "principalDue": 300, + "principalOutstanding": 300, + "principalLoanBalanceOutstanding": 0, + "interestOriginalDue": 130, + "interestDue": 130, + "interestOutstanding": 130, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 430, + "totalDueForPeriod": 430, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 430, + "totalOverdue": 430, + "totalActualCostOfLoanForPeriod": 130 + } + ] +} + +
+
+   +
+
+

Reject a Loan Reschedule Request

+
+
+ POST https://DomainName/api/v1/rescheduleloans/{requestId}?command=reject + POST rescheduleloans/1?command=reject +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "11 September 2014" +} + + +{ + "loanId": 1, + "resourceId": 1, + "changes": { + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "11 September 2014", + "rejectedByUserId": 1 + } +} + +
+
+   +
+
+

Approve a Loan Reschedule Request

+

Rescheduling of a loan happens once a loan reschedule request is approved.

+
+
+ POST https://DomainName/api/v1/rescheduleloans/{requestId}?command=approve + POST rescheduleloans/1?command=approve +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "11 September 2014" +} + + +{ + "loanId": 1, + "resourceId": 1, + "changes": { + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "11 September 2014", + "approvedByUserId": 1 + } +} + +
+
+ + + +  +
+
+

Loan Rescheduling

+

Loan Term Variations provides the ability to change due dates, amounts and number of instalments before loan approval.

+ + + + + + + + + + + + + + + + + +
Field Descriptions
loanId
The ID of the loan to be modified.
exceptions
contains exception data for variations(modifiedinstallments,newinstallments and deletedinstallments described below)
+

Exception object fields

+

Modifiedinstallments Array fields

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
dueDate
Schedule dueDate for which this exception should be applied.
modifiedDueDate
this is the exception data to move the due date to specified date for a instalment
installmentAmount
new instalment amount(principal+interest) for the specified instalment. supported only for interest method declining with equal instalments Amortization
principal
new Principal amount for the specified instalment. supported only for interest method declining with equal instalments Amortization and for Flat loans.
+

newinstallments Array fields

+ + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
dueDate
Schedule dueDate for inserting new instalment.
installmentAmount
new instalment amount(principal+interest) for the new instalment. supported only for interest method declining with equal instalments Amortization
principal
new Principal amount for the new instalment. supported only for interest method declining with equal instalments Amortization and for Flat loans.
+

deletedinstallments Array fields

+ + + + + + + + + + +
Field Descriptions
dueDate
Schedule dueDate for removing specific instalment.
+
+
+ + + + +   +
+
+

Calculate loan repayment schedule based on Loan term variations

+ + + + + + + +
Mandatory Fields
exceptions,locale,dateFormat
+
+
+ +POST https://DomainName/api/v1/loans/1/schedule?command=calculateLoanSchedule + + +POST loans/{loanIdd}/schedule?command=calculateLoanSchedule +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "exceptions": { + "modifiedinstallments": [{ + "dueDate": '01 April 2016', + "modifiedDueDate": '05 April 2016' + }, + { + "dueDate": '05 January 2016', + "modifiedDueDate": '01 January 2016' + }], + "deletedinstallments": [{ + "dueDate": "01 October 2016" + }], + newinstallments: [{ + dueDate: '10 October 2016', + installmentAmount: '1000' +}] + } +} + + +{ + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "loanTermInDays": 12, + "totalPrincipalDisbursed": 10000, + "totalPrincipalExpected": 10000, + "totalInterestCharged": 1340.98, + "totalFeeChargesCharged": 0, + "totalPenaltyChargesCharged": 0, + "totalRepaymentExpected": 11340.98, + "periods": [{ + "period": 1, + "fromDate": [2015, + 11, + 1], + "dueDate": [2015, + 12, + 1], + "daysInPeriod": 30, + "principalOriginalDue": 745.6, + "principalDue": 745.6, + "principalOutstanding": 745.6, + "principalLoanBalanceOutstanding": 9254.4, + "interestOriginalDue": 200, + "interestDue": 200, + "interestOutstanding": 200, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 945.6, + "totalDueForPeriod": 945.6, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 945.6, + "totalOverdue": 945.6, + "totalActualCostOfLoanForPeriod": 200 + }, + { + "period": 2, + "fromDate": [2015, + 12, + 1], + "dueDate": [2016, + 1, + 1], + "daysInPeriod": 31, + "principalOriginalDue": 814.91, + "principalDue": 814.91, + "principalOutstanding": 814.91, + "principalLoanBalanceOutstanding": 8439.49, + "interestOriginalDue": 185.09, + "interestDue": 185.09, + "interestOutstanding": 185.09, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 1000, + "totalDueForPeriod": 1000, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 1000, + "totalActualCostOfLoanForPeriod": 185.09 + }, + { + "period": 3, + "fromDate": [2016, + 1, + 1], + "dueDate": [2016, + 2, + 1], + "daysInPeriod": 31, + "principalOriginalDue": 770.75, + "principalDue": 770.75, + "principalOutstanding": 770.75, + "principalLoanBalanceOutstanding": 7668.74, + "interestOriginalDue": 168.79, + "interestDue": 168.79, + "interestOutstanding": 168.79, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.54, + "totalDueForPeriod": 939.54, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.54, + "totalActualCostOfLoanForPeriod": 168.79 + }, + { + "period": 4, + "fromDate": [2016, + 2, + 1], + "dueDate": [2016, + 3, + 5], + "daysInPeriod": 33, + "principalOriginalDue": 786.17, + "principalDue": 786.17, + "principalOutstanding": 786.17, + "principalLoanBalanceOutstanding": 6882.57, + "interestOriginalDue": 153.37, + "interestDue": 153.37, + "interestOutstanding": 153.37, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.54, + "totalDueForPeriod": 939.54, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.54, + "totalActualCostOfLoanForPeriod": 153.37 + }, + { + "period": 5, + "fromDate": [2016, + 3, + 5], + "dueDate": [2016, + 4, + 5], + "daysInPeriod": 31, + "principalOriginalDue": 801.89, + "principalDue": 801.89, + "principalOutstanding": 801.89, + "principalLoanBalanceOutstanding": 6080.68, + "interestOriginalDue": 137.65, + "interestDue": 137.65, + "interestOutstanding": 137.65, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.54, + "totalDueForPeriod": 939.54, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.54, + "totalActualCostOfLoanForPeriod": 137.65 + }, + { + "period": 6, + "fromDate": [2016, + 4, + 5], + "dueDate": [2016, + 5, + 1], + "daysInPeriod": 26, + "principalOriginalDue": 817.93, + "principalDue": 817.93, + "principalOutstanding": 817.93, + "principalLoanBalanceOutstanding": 5262.75, + "interestOriginalDue": 121.61, + "interestDue": 121.61, + "interestOutstanding": 121.61, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.54, + "totalDueForPeriod": 939.54, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.54, + "totalActualCostOfLoanForPeriod": 121.61 + }, + { + "period": 7, + "fromDate": [2016, + 5, + 1], + "dueDate": [2016, + 6, + 1], + "daysInPeriod": 31, + "principalOriginalDue": 834.28, + "principalDue": 834.28, + "principalOutstanding": 834.28, + "principalLoanBalanceOutstanding": 4428.47, + "interestOriginalDue": 105.26, + "interestDue": 105.26, + "interestOutstanding": 105.26, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.54, + "totalDueForPeriod": 939.54, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.54, + "totalActualCostOfLoanForPeriod": 105.26 + }, + { + "period": 8, + "fromDate": [2016, + 6, + 1], + "dueDate": [2016, + 7, + 1], + "daysInPeriod": 30, + "principalOriginalDue": 850.97, + "principalDue": 850.97, + "principalOutstanding": 850.97, + "principalLoanBalanceOutstanding": 3577.5, + "interestOriginalDue": 88.57, + "interestDue": 88.57, + "interestOutstanding": 88.57, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.54, + "totalDueForPeriod": 939.54, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.54, + "totalActualCostOfLoanForPeriod": 88.57 + }, + { + "period": 9, + "fromDate": [2016, + 7, + 1], + "dueDate": [2016, + 8, + 1], + "daysInPeriod": 31, + "principalOriginalDue": 867.99, + "principalDue": 867.99, + "principalOutstanding": 867.99, + "principalLoanBalanceOutstanding": 2709.51, + "interestOriginalDue": 71.55, + "interestDue": 71.55, + "interestOutstanding": 71.55, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.54, + "totalDueForPeriod": 939.54, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.54, + "totalActualCostOfLoanForPeriod": 71.55 + }, + { + "period": 10, + "fromDate": [2016, + 8, + 1], + "dueDate": [2016, + 9, + 1], + "daysInPeriod": 31, + "principalOriginalDue": 885.35, + "principalDue": 885.35, + "principalOutstanding": 885.35, + "principalLoanBalanceOutstanding": 1824.16, + "interestOriginalDue": 54.19, + "interestDue": 54.19, + "interestOutstanding": 54.19, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.54, + "totalDueForPeriod": 939.54, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.54, + "totalActualCostOfLoanForPeriod": 54.19 + }, + { + "period": 11, + "fromDate": [2016, + 9, + 1], + "dueDate": [2016, + 10, + 10], + "daysInPeriod": 39, + "principalOriginalDue": 903.05, + "principalDue": 903.05, + "principalOutstanding": 903.05, + "principalLoanBalanceOutstanding": 921.11, + "interestOriginalDue": 36.48, + "interestDue": 36.48, + "interestOutstanding": 36.48, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.53, + "totalDueForPeriod": 939.53, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.53, + "totalActualCostOfLoanForPeriod": 36.48 + }, + { + "period": 12, + "fromDate": [2016, + 10, + 10], + "dueDate": [2016, + 11, + 1], + "daysInPeriod": 22, + "principalOriginalDue": 921.11, + "principalDue": 921.11, + "principalOutstanding": 921.11, + "principalLoanBalanceOutstanding": 0, + "interestOriginalDue": 18.42, + "interestDue": 18.42, + "interestOutstanding": 18.42, + "feeChargesDue": 0, + "penaltyChargesDue": 0, + "totalOriginalDueForPeriod": 939.53, + "totalDueForPeriod": 939.53, + "totalPaidForPeriod": 0, + "totalOutstandingForPeriod": 939.53, + "totalActualCostOfLoanForPeriod": 18.42 + }] +} + +
+
+ +   +
+
+

Updates loan repayment schedule based on Loan term variations

+ + + + + + + +
Mandatory Fields
exceptions,locale,dateFormat
+
+
+ +POST https://DomainName/api/v1/loans/1/schedule?command=addVariations + + +POST loans/{loanIdd}/schedule?command=addVariations +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "exceptions": { + "modifiedinstallments": [{ + "dueDate": '01 April 2016', + "modifiedDueDate": '05 April 2016' + }, + { + "dueDate": '05 January 2016', + "modifiedDueDate": '01 January 2016' + }], + "deletedinstallments": [{ + "dueDate": "01 October 2016" + }], + newinstallments: [{ + dueDate: '10 October 2016', + installmentAmount: '1000' +}] + } +} + + +{ + "loanId": 1, + "changes": { + "loanTermVariations": [{ + "id": 21, + "termType": { + "id": 4, + "code": "loanTermType.dueDate", + "value": "dueDate" + }, + "termVariationApplicableFrom": [2016, + 1, + 1], + "dateValue": [2016, + 1, + 10], + "isSpecificToInstallment": true + }, + { + "id": 22, + "termType": { + "id": 3, + "code": "loanTermType.principalAmount", + "value": "principalAmount" + }, + "termVariationApplicableFrom": [2016, + 1, + 10], + "decimalValue": 1100, + "isSpecificToInstallment": true + }, + { + "id": 23, + "termType": { + "id": 3, + "code": "loanTermType.principalAmount", + "value": "principalAmount" + }, + "termVariationApplicableFrom": [2016, + 8, + 1], + "decimalValue": 1000, + "isSpecificToInstallment": true + }, + { + "id": 24, + "termType": { + "id": 5, + "code": "loanTermType.dueDate", + "value": "insertInstallment" + }, + "termVariationApplicableFrom": [2016, + 8, + 15], + "decimalValue": 900, + "isSpecificToInstallment": true + }] + } +} + +
+
+ + +   +
+
+

Updates loan repayment schedule by removing Loan term variations

+ + + + + + + +
Mandatory Fields
+
+
+ +POST https://DomainName/api/v1/loans/1/schedule?command=deleteVariations + + +POST loans/{loanIdd}/schedule?command=deleteVariations +Content-Type: application/json +Request Body: +{} + + +{ + "loanId": 1, + "changes": { + "removedEntityIds": [{ + 21,22}] + } +} + +
+
+ + + + +   +
+
+

Offices

+

Offices are used to model an MFIs structure. A hierarchical + representation of offices is supported. There will always be at + least one office (which represents the MFI or an MFIs head + office). All subsequent offices added must have a parent office.

+ + + + + + + + + + + + + + + + +
Field Descriptions
externalId
A place to put an external reference for + this office e.g. The ID another system uses for it.
If + provided, it must be unique. +
hierarchy
This field is a system generated + convenience field. It can't be set.
It uses "dot + notation" to define where an office stands in the office + hierarchy.
For example, the system default office (id = + 1) has a hierarchy value of '.'
An office (id = 12) + placed directly underneath this default office has a hierarchy + value of '.12.'
And if a further office (id = 78) is + placed directly under office (id = 12) its hierarchy value is + '.12.78.'
+
The hierarchy value is useful when you need to display + offices in 'hierarchy' order (perhaps indented in a drop down + list box). +
+
+
+ +   +
+
+

List Offices

+

Example Requests:

+
offices
+
+
+
offices?fields=id,name,openingDate
+
+
+ +GET https://DomainName/api/v1/offices + + +[ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office", + "externalId": "1", + "openingDate": [ + 2009, + 1, + 1 + ], + "hierarchy": "." + } +] + +
+
+ +   +
+
+

Retrieve Office Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
offices/template
+
+
+ +GET https://DomainName/api/v1/offices/template + + +{ + "openingDate": [ + 2013, + 2, + 4 + ], + "allowedParents": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + } + ] +} + +
+
+ +   +
+
+

Retrieve an Office

+

Example Requests:

+
offices/1
+
+
+
offices/1?template=true
+
+
+
offices/1?fields=id,name,parentName
+
+
+ +GET https://DomainName/api/v1/offices/1 + + +{ + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office", + "externalId": "1", + "openingDate": [ + 2009, + 1, + 1 + ], + "hierarchy": "." +} + +
+
+ +   +
+
+

Create an Office

+ + + + + + + +
Mandatory Fields
name, openingDate, parentId
+
+
+ +POST https://DomainName/api/v1/offices + + +POST offices +Content-Type: application/json +Request Body: +{ + "name": "Example New Branch", + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "openingDate": "01 July 2007", + "parentId": 2, + "externalId": "SYS54-88" +} + + +{ + "officeId": 3, + "resourceId": 3 +} + +
+
+ +   +
+
+

Update Office

+
+
+ +PUT https://DomainName/api/v1/offices/{officeId} + + +PUT offices/1 +Content-Type: application/json +Request Body: +{ + "name": "Name is updated" +} + + +{ + "officeId": 1, + "resourceId": 1, + "changes": { + "name": "Name is updated" + } +} + +
+
+ + + +   +
+
+

Loan Products

+

A Loan product is a template that is used when creating a + loan. Much of the template definition can be overridden during + loan creation.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name associated with loan product on system.
shortName
Short name associated with a loan product.
+ An abbreviated version of the name, used in reports or menus where space is limited, such as Collection Sheets. +
description
For providing helpful description of product offering.
fundId
For associating a loan product with a given fund by default.
includeInBorrowerCycle
It is a flag, Used to denote whether the loans should include in loan cycle counter or not.
useBorrowerCycle
It is a flag, Used to denote whether the loans should depend on
borrower loan cycle counter or not.
currencyCode
A three letter ISO code of currency.
digitsAfterDecimal
Override the currency default value for digitsAfterDecimal.
inMultiplesOf
Override the default value for rounding currency to multiples of value provided.
installmentAmountInMultiplesOf
Override the default value for rounding instalment amount to multiples of value provided.
principal
The loan amount to be disbursed to through loan.
numberOfRepayments
Number of installments to repay.
+ Used like: numberOfRepayments Every repaymentEvery + repaymentFrequencyType
e.g. 10 (repayments) Every 12 Weeks +
repaymentEvery
Used like: numberOfRepayments Every + repaymentEvery repaymentFrequencyType
e.g. 10 + (repayments) Every 12 Weeks +
repaymentFrequencyType
Used like: numberOfRepayments Every + repaymentEvery repaymentFrequencyType
e.g. 10 + (repayments) Every 12 Weeks
+ Example Values: 0=Days, 1=Weeks, 2=Months +
interestRatePerPeriod
Interest Rate.
Used like: + interestRatePerPeriod % interestRateFrequencyType - interestType
+ e.g. 12.0000% Per year - Declining Balance +
interestRateFrequencyType
Used like: interestRatePerPeriod% + interestRateFrequencyType - interestType
e.g. 12.0000% + Per year - Declining Balance
+ Example Values: 2=Per month, 3=Per year +
amortizationType
Example Values: 0=Equal + principle payments, 1=Equal installments
interestType
Used like: interestRatePerPeriod% + interestRateFrequencyType - interestType
e.g. 12.0000% + Per year - Declining Balance
+ Example Values: 0=Declining Balance, 1=Flat +
interestCalculationPeriodType
Example Values: 0=Daily, 1=Same as repayment period
allowPartialPeriodInterestCalcualtion
This value will be supported along with interestCalculationPeriodType as Same as repayment period to calculate interest for partial periods. + Example: Interest charged from is 5th of April , Principal is 10000 and interest is 1% per month then the interest will be (10000 * 1%)* (25/30) , it calculates for the month first then calculates exact periods between start date and end date(can be a decimal) +
inArrearsTolerance
The amount that can be 'waived' at end + of all loan payments because it is too small to worry about.
+ This is also the tolerance amount assessed when determining if a + loan is in arrears. +
principalVariationsForBorrowerCycle,interestRateVariationsForBorrowerCycle,
numberOfRepaymentVariationsForBorrowerCycle
Variations for loan, based on borrower cycle number +
minimumDaysBetweenDisbursalAndFirstRepayment
The minimum number of days allowed between a Loan disbursal and its first repayment. +
principalThresholdForLastInstalment
Field represents percentage of current instalment principal amount for comparing against principal outstanding to add another repayment instalment. If the outstanding principal amount is less then calculated amount, remaining outstanding amount will be added to current instalment. Default value for multi disburse loan is 50% and non-multi disburse loan is 0% +
canDefineInstallmentAmount
if provided as true, then fixed instalment amount can be provided from loan account. +
transactionProcessingStrategyId
+An enumeration that indicates the type of transaction processing strategy to be used. This relates to functionality that is also known as Payment Application Logic. + +

A number of out of the box approaches exist, some are custom to specific MFIs, some are more general and indicate the order in which payments are processed.

+ +

Refer to the Payment Application Logic / Transaction Processing Strategy section in the appendix for more detailed overview of each available payment application logic provided out of the box.

+ +List of current approaches:
+
    +
  • 1 = Mifos style (Similar to Old Mifos)
  • +
  • 2 = Heavensfamily (Custom MFI approach)
  • +
  • 3 = Creocore (Custom MFI approach)
  • +
  • 4 = RBI (India)
  • +
  • 5 = Principal Interest Penalties Fees Order
  • +
  • 6 = Interest Principal Penalties Fees Order
  • +
  • 7 = Early Payment Strategy
  • +
+
graceOnPrincipalPayment
Optional: Integer - represents the number of repayment periods that grace should apply to the principal component of a repayment period. +
graceOnInterestPayment
Optional: Integer - represents the number of repayment periods that grace should apply to the interest component of a repayment period. Interest is still calculated but offset to later repayment periods. +
graceOnInterestCharged
Optional: Integer - represents the number of repayment periods that should be interest-free. +
graceOnArrearsAgeing
Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue. +
overdueDaysForNPA
Optional: Integer - represents the maximum number of days a Loan may + be overdue before being classified as a NPA (non performing asset) +
accountMovesOutOfNPAOnlyOnArrearsCompletion
Optional: Boolean - if provided as true, Loan Account moves out of NPA state only when all arrears are cleared +
accountingRule
Specifies if accounting is enabled for the particular + product and the type of the accounting rule to be used + Example Values:1=NONE, 2=CASH_BASED, 3=ACCRUAL_PERIODIC, 4=ACCRUAL_UPFRONT
isInterestRecalculationEnabled
It is a flag, Used to denote whether interest recalculation is enabled or disabled for the particular product
daysInYearType
Specifies the number of days in a year.
+ Example Values:1=ACTUAL(Actual number of days in year), 360=360 DAYS, 364=364 DAYS(52 WEEKS), 365=365 DAYS
daysInMonthType
Specifies the number of days in a month.
+ Example Values:1=ACTUAL(Actual number of days in month), 30=30 DAYS
interestRecalculationCompoundingMethod
Specifies which amount portion should be added to principal for interest recalculation.
+ Example Values:0=NONE(Only on principal), 1=INTEREST(Principal+Interest), 2=FEE(Principal+Fee), 3=FEE And INTEREST (Principal+Fee+Interest)
rescheduleStrategyMethod
Specifies what action should perform on loan repayment schedule for advance payments.
+ Example Values:1=Reschedule next repayments, 2=Reduce number of installments, 3=Reduce EMI amount
recalculationCompoundingFrequencyType
Specifies effective date from which the compounding of interest or fee amounts will be considered in recalculation on late payment.
+ Example Values:1=Same as repayment period, 2=Daily, 3=Weekly, 4=Monthly
recalculationCompoundingFrequencyInterval
Specifies compounding frequency interval for interest recalculation.
+
recalculationCompoundingFrequencyDate
Specifies compounding frequency start date for interest recalculation.
+
recalculationRestFrequencyType
Specifies effective date from which the late or advanced payment amounts will be considered in recalculation.
+ Example Values:1=Same as repayment period, 2=Daily, 3=Weekly, 4=Monthly
recalculationRestFrequencyInterval
Specifies rest frequency interval for interest recalculation.
+
recalculationRestFrequencyDate
Specifies rest frequency start date for interest recalculation.
+
preClosureInterestCalculationStrategy
Specifies applicable days for interest calculation on pre closure of a loan.
+ Example Values:1=Calculate till pre closure date, 2=Calculate till rest frequency date
isArrearsBasedOnOriginalSchedule
If Specified as true, arrears will be identified based on original schedule.
+
allowAttributeOverrides
Specifies if select attributes may be overridden for individual loan accounts.
+
+
+
+ +   +
+
+

List Loan Products

+

Example Requests:

+
loanproducts
+
+
+
loanproducts?fields=name,description,interestRateFrequencyType,amortizationType
+
+
+ +GET https://DomainName/api/v1/loanproducts + + +[ + { + "id": 1, + "name": "personal loan product", + "shortName": "pe1", + "includeInBorrowerCycle": false, + "useBorrowerCycle": false, + "startDate": [ + 2013, + 9, + 2 + ], + "closeDate": [ + 2014, + 2, + 7 + ], + "status": "loanProduct.active", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principal": 10000.000000, + "minPrincipal": 5000.000000, + "maxPrincipal": 15000.000000, + "numberOfRepayments": 10, + "minNumberOfRepayments": 5, + "maxNumberOfRepayments": 15, + "repaymentEvery": 7, + "repaymentFrequencyType": { + "id": 0, + "code": "repaymentFrequency.periodFrequencyType.days", + "value": "Days" + }, + "interestRatePerPeriod": 15.000000, + "interestRateFrequencyType": { + "id": 3, + "code": "interestRateFrequency.periodFrequencyType.years", + "value": "Per year" + }, + "annualInterestRate": 15.000000, + "amortizationType": { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + "interestType": { + "id": 1, + "code": "interestType.flat", + "value": "Flat" + }, + "interestCalculationPeriodType": { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + }, + "transactionProcessingStrategyId": 1, + "transactionProcessingStrategyName": "Mifos style", + "principalVariationsForBorrowerCycle": [], + "interestRateVariationsForBorrowerCycle": [], + "numberOfRepaymentVariationsForBorrowerCycle": [], + "daysInMonthType": { + "id": 30, + "code": "DaysInMonthType.days360", + "value": "30 Days" + }, + "daysInYearType": { + "id": 360, + "code": "DaysInYearType.days360", + "value": "360 Days" + }, + "isInterestRecalculationEnabled": true, + "interestRecalculationData": { + "id": 3, + "productId": 1, + "interestRecalculationCompoundingType": { + "id": 2, + "code": "interestRecalculationCompoundingMethod.fee", + "value": "Fee" + }, + "recalculationCompoundingFrequencyType": { + "id":1, + "code":"interestRecalculationFrequencyType.same.as.repayment.period", + "value":"Same as repayment period" + }, + "rescheduleStrategyType": { + "id": 2, + "code": "loanRescheduleStrategyMethod.reduce.number.of.installments", + "value": "Reduce number of installments" + }, + "recalculationRestFrequencyType": { + "id":1, + "code":"interestRecalculationFrequencyType.same.as.repayment.period", + "value":"Same as repayment period" + }, + "preClosureInterestCalculationStrategy": { + "id":1, + "code":"loanPreClosureInterestCalculationStrategy.tillPreClosureDate", + "value":"Till preclose Date" + }, + "isArrearsBasedOnOriginalSchedule" : true + }, + "accountingRule": { + "id": 2, + "code": "accountingRuleType.cash", + "value": "CASH BASED" + }, + "principalThresholdForLastInstalment":0 + } +] + +
+
+ +   +
+
+

Retrieve Loan Product Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
loanproducts/template
+
+
+ +GET https://DomainName/api/v1/loanproducts/template + + +{ + "includeInBorrowerCycle": false, + "useBorrowerCycle": false, + "currency": { + "code": "", + "name": "", + "decimalPlaces": 0, + "inMultiplesOf": 0, + "displaySymbol": "", + "nameCode": "", + "displayLabel": " []" + }, + "repaymentFrequencyType": { + "id": 2, + "code": "repaymentFrequency.periodFrequencyType.months", + "value": "Months" + }, + "interestRateFrequencyType": { + "id": 2, + "code": "interestRateFrequency.periodFrequencyType.months", + "value": "Per month" + }, + "amortizationType": { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + "interestType": { + "id": 0, + "code": "interestType.declining.balance", + "value": "Declining Balance" + }, + "interestCalculationPeriodType": { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + }, + "principalVariationsForBorrowerCycle": [], + "interestRateVariationsForBorrowerCycle": [], + "numberOfRepaymentVariationsForBorrowerCycle": [], + "accountingRule": { + "id": 1, + "code": "accountingRuleType.none", + "value": "NONE" + }, + "daysInMonthType": { + "id": 1, + "code": "DaysInMonthType.actual", + "value": "Actual" + }, + "daysInYearType": { + "id": 1, + "code": "DaysInYearType.actual", + "value": "Actual" + }, + "isInterestRecalculationEnabled": false, + "interestRecalculationData": { + "interestRecalculationCompoundingType": { + "id": 0, + "code": "interestRecalculationCompoundingMethod.none", + "value": "None" + }, + "rescheduleStrategyType": { + "id": 3, + "code": "loanRescheduleStrategyMethod.reduce.emi.amount", + "value": "Reduce EMI amount" + },"preClosureInterestCalculationStrategy": { + "id":1, + "code":"loanPreClosureInterestCalculationStrategy.tillPreClosureDate", + "value":"Till preclose Date" + } + }, + "paymentTypeOptions": [ + { + "id": 10, + "name": "check", + "position": 1 + } + ], + "currencyOptions": [ + { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + ], + "repaymentFrequencyTypeOptions": [ + { + "id": 0, + "code": "repaymentFrequency.periodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "repaymentFrequency.periodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "repaymentFrequency.periodFrequencyType.months", + "value": "Months" + } + ], + "preClosureInterestCalculationStrategyOptions": [ + { + "id":1, + "code":"loanPreClosureInterestCalculationStrategy.tillPreClosureDate", + "value":"Till preclose Date" + }, + { + "id":2, + "code":"loanPreClosureInterestCalculationStrategy.tillRestFrequencyDate", + "value":"Till rest Frequency Date" + } + ], + "interestRateFrequencyTypeOptions": [ + { + "id": 2, + "code": "interestRateFrequency.periodFrequencyType.months", + "value": "Per month" + }, + { + "id": 3, + "code": "interestRateFrequency.periodFrequencyType.years", + "value": "Per year" + } + ], + "amortizationTypeOptions": [ + { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + { + "id": 0, + "code": "amortizationType.equal.principal", + "value": "Equal principal payments" + } + ], + "interestTypeOptions": [ + { + "id": 1, + "code": "interestType.flat", + "value": "Flat" + }, + { + "id": 0, + "code": "interestType.declining.balance", + "value": "Declining Balance" + } + ], + "interestCalculationPeriodTypeOptions": [ + { + "id": 0, + "code": "interestCalculationPeriodType.daily", + "value": "Daily" + }, + { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + } + ], + "transactionProcessingStrategyOptions": [ + { + "id": 1, + "code": "mifos-standard-strategy", + "name": "Penalties, Fees, Interest, Principal order" + }, + { + "id": 2, + "code": "heavensfamily-strategy", + "name": "HeavensFamily Unique" + }, + { + "id": 3, + "code": "creocore-strategy", + "name": "Creocore Unique" + }, + { + "id": 4, + "code": "rbi-india-strategy", + "name": "Overdue/Due Fee/Int,Principal" + }, + { + "id": 5, + "code": "principal-interest-penalties-fees-order-strategy", + "name": "Principal Interest Penalties Fees Order" + }, + { + "id": 6, + "code": "interest-principal-penalties-fees-order-strategy", + "name": "Interest Principal Penalties Fees Order" + } + ], + "chargeOptions": [ + { + "id": 5, + "name": "des charge", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100.000000, + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 1, + "name": "flat install", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 50.000000, + "chargeTimeType": { + "id": 8, + "code": "chargeTimeType.instalmentFee", + "value": "Instalment Fee" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 9, + "name": "install amt+int", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 5.000000, + "chargeTimeType": { + "id": 8, + "code": "chargeTimeType.instalmentFee", + "value": "Instalment Fee" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 3, + "code": "chargeCalculationType.percent.of.amount.and.interest", + "value": "% Loan Amount + Interest" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 10, + "name": "install int", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 5.000000, + "chargeTimeType": { + "id": 8, + "code": "chargeTimeType.instalmentFee", + "value": "Instalment Fee" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 4, + "code": "chargeCalculationType.percent.of.interest", + "value": "% Interest" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 2, + "name": "install per", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 5.000000, + "chargeTimeType": { + "id": 8, + "code": "chargeTimeType.instalmentFee", + "value": "Instalment Fee" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + }, + "chargePaymentMode": { + "id": 1, + "code": "chargepaymentmode.accounttransfer", + "value": "Account transfer" + } + }, + { + "id": 8, + "name": "spe int", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 5.000000, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 4, + "code": "chargeCalculationType.percent.of.interest", + "value": "% Interest" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 4, + "name": "specific acc transfer", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100.000000, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 1, + "code": "chargepaymentmode.accounttransfer", + "value": "Account transfer" + } + }, + { + "id": 7, + "name": "specific amt+int", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 5.000000, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 3, + "code": "chargeCalculationType.percent.of.amount.and.interest", + "value": "% Loan Amount + Interest" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 3, + "name": "specific per", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 5.000000, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 6, + "name": "xyz", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 50.000000, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 1, + "code": "chargepaymentmode.accounttransfer", + "value": "Account transfer" + } + } + ], + "accountingRuleOptions": [ + { + "id": 1, + "code": "accountingRuleType.none", + "value": "NONE" + }, + { + "id": 2, + "code": "accountingRuleType.cash", + "value": "CASH BASED" + }, + { + "id": 3, + "code": "accountingRuleType.accrual", + "value": "ACCRUAL BASED" + } + ], + "accountingMappingOptions": { + "liabilityAccountOptions": [ + { + "id": 11, + "name": "over payment", + "glCode": "13", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 2, + "code": "accountType.liability", + "value": "LIABILITY" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "over payment", + "tagId": { + "id": 0 + }, + "organizationRunningBalance": 0 + }, + ], + "assetAccountOptions": [ + { + "id": 1, + "name": "fund source", + "glCode": "01", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "fund source", + "tagId": { + "id": 0 + }, + "organizationRunningBalance": -60000 + }, + { + "id": 2, + "name": "Loan portfolio", + "glCode": "02", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "Loan portfolio", + "tagId": { + "id": 0 + }, + "organizationRunningBalance": 60000 + }, + { + "id": 3, + "name": "transfers", + "glCode": "03", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "transfers", + "tagId": { + "id": 0 + }, + "organizationRunningBalance": 0 + }, + ], + "expenseAccountOptions": [ + { + "id": 10, + "name": "loans written off 2", + "glCode": "12", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 5, + "code": "accountType.expense", + "value": "EXPENSE" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "loans written off 2", + "tagId": { + "id": 0 + }, + "organizationRunningBalance": 0 + } + ], + "incomeAccountOptions": [ + { + "id": 4, + "name": "income from interest", + "glCode": "04", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 4, + "code": "accountType.income", + "value": "INCOME" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "income from interest", + "tagId": { + "id": 0 + }, + "organizationRunningBalance": 19 + }, + { + "id": 8, + "name": "income from fees 2", + "glCode": "10", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 4, + "code": "accountType.income", + "value": "INCOME" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "income from fees 2", + "tagId": { + "id": 0 + }, + "organizationRunningBalance": 0 + }, + { + "id": 9, + "name": "income from penalities 2", + "glCode": "11", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 4, + "code": "accountType.income", + "value": "INCOME" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "income from penalities 2", + "tagId": { + "id": 0 + }, + "organizationRunningBalance": 0 + } + ] + }, + "valueConditionTypeOptions": [ + { + "id": 2, + "code": "LoanProductValueConditionType.equal", + "value": "equals" + }, + { + "id": 3, + "code": "LoanProductValueConditionType.greterthan", + "value": "greter than" + } + ], + "daysInMonthTypeOptions": [{ + "id": 1, + "code": "DaysInMonthType.actual", + "value": "Actual" + }, + { + "id": 30, + "code": "DaysInMonthType.days360", + "value": "30 Days" + }], + "daysInYearTypeOptions": [{ + "id": 1, + "code": "DaysInYearType.actual", + "value": "Actual" + }, + { + "id": 360, + "code": "DaysInYearType.days360", + "value": "360 Days" + }, + { + "id": 364, + "code": "DaysInYearType.days364", + "value": "364 Days" + }, + { + "id": 365, + "code": "DaysInYearType.days365", + "value": "365 Days" + }], + "interestRecalculationCompoundingTypeOptions": [{ + "id": 0, + "code": "interestRecalculationCompoundingMethod.none", + "value": "None" + }, + { + "id": 2, + "code": "interestRecalculationCompoundingMethod.fee", + "value": "Fee" + }, + { + "id": 1, + "code": "interestRecalculationCompoundingMethod.interest", + "value": "Interest" + }, + { + "id": 3, + "code": "interestRecalculationCompoundingMethod.interest.and.fee", + "value": "Fee and Interest" + }], + "rescheduleStrategyTypeOptions": [{ + "id": 3, + "code": "loanRescheduleStrategyMethod.reduce.emi.amount", + "value": "Reduce EMI amount" + }, + { + "id": 2, + "code": "loanRescheduleStrategyMethod.reduce.number.of.installments", + "value": "Reduce number of installments" + }, + { + "id": 1, + "code": "loanRescheduleStrategyMethod.reschedule.next.repayments", + "value": "Reschedule next repayments" + }], + "interestRecalculationFrequencyTypeOptions": [ + { + "id":1, + "code":"interestRecalculationFrequencyType.same.as.repayment.period", + "value":"Same as repayment period" + }, + { + "id":2, + "code":"interestRecalculationFrequencyType.daily", + "value":"Daily" + }, + { + "id":3, + "code":"interestRecalculationFrequencyType.weekly", + "value":"Weekly" + }, + { + "id":4, + "code":"interestRecalculationFrequencyType.monthly", + "value":"Monthly" + }] +} + +
+
+ +   +
+
+

Retrieve a Loan Product

+

Example Requests:

+
loanproducts/1
+
+
+
loanproducts/1?template=true
+
+
+
loanproducts/1?fields=name,description,numberOfRepayments
+
+
+ +GET https://DomainName/api/v1/loanproducts/{productId} + + +{ + "id": 11, + "name": "advanced accounting", + "shortName": "ad11", + "includeInBorrowerCycle": true, + "useBorrowerCycle": true, + "status": "loanProduct.active", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "principal": 10000.000000, + "minPrincipal": 2000.000000, + "maxPrincipal": 15000.000000, + "numberOfRepayments": 7, + "repaymentEvery": 7, + "repaymentFrequencyType": { + "id": 0, + "code": "repaymentFrequency.periodFrequencyType.days", + "value": "Days" + }, + "interestRatePerPeriod": 5.000000, + "interestRateFrequencyType": { + "id": 2, + "code": "interestRateFrequency.periodFrequencyType.months", + "value": "Per month" + }, + "annualInterestRate": 60.000000, + "amortizationType": { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + "interestType": { + "id": 0, + "code": "interestType.declining.balance", + "value": "Declining Balance" + }, + "interestCalculationPeriodType": { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + }, + "transactionProcessingStrategyId": 1, + "transactionProcessingStrategyName": "Mifos style", + "charges": [], + "principalVariationsForBorrowerCycle": [ + { + "id": 21, + "borrowerCycleNumber": 1, + "paramType": { + "id": 1, + "code": "LoanProductParamType.principal", + "value": "principal" + }, + "valueConditionType": { + "id": 2, + "code": "LoanProductValueConditionType.equal", + "value": "equals" + }, + "minValue": 2000.000000, + "maxValue": 20000.000000, + "defaultValue": 15000.000000 + }, + { + "id": 20, + "borrowerCycleNumber": 1, + "paramType": { + "id": 1, + "code": "LoanProductParamType.principal", + "value": "principal" + }, + "valueConditionType": { + "id": 3, + "code": "LoanProductValueConditionType.greterthan", + "value": "greter than" + }, + "minValue": 3000.000000, + "maxValue": 25000.000000, + "defaultValue": 20000.000000 + } + ], + "interestRateVariationsForBorrowerCycle": [], + "numberOfRepaymentVariationsForBorrowerCycle": [], + "accountingRule": { + "id": 2, + "code": "accountingRuleType.cash", + "value": "CASH BASED" + }, + "accountingMappings": { + "fundSourceAccount": { + "id": 1, + "name": "fund source", + "glCode": "01" + }, + "loanPortfolioAccount": { + "id": 2, + "name": "Loan portfolio", + "glCode": "02" + }, + "transfersInSuspenseAccount": { + "id": 3, + "name": "transfers", + "glCode": "03" + }, + "interestOnLoanAccount": { + "id": 4, + "name": "income from interest", + "glCode": "04" + }, + "incomeFromFeeAccount": { + "id": 8, + "name": "income from fees 2", + "glCode": "10" + }, + "incomeFromPenaltyAccount": { + "id": 9, + "name": "income from penalities 2", + "glCode": "11" + }, + "writeOffAccount": { + "id": 10, + "name": "loans written off 2", + "glCode": "12" + }, + "overpaymentLiabilityAccount": { + "id": 11, + "name": "over payment", + "glCode": "13" + } + }, + "paymentChannelToFundSourceMappings": [ + { + "paymentType": { + "id": 10, + "name": "check" + }, + "fundSourceAccount": { + "id": 1, + "name": "fund source", + "glCode": "01" + } + } + ], + "feeToIncomeAccountMappings": [ + { + "charge": { + "id": 1, + "name": "flat install", + "active": false, + "penalty": false + }, + "incomeAccount": { + "id": 8, + "name": "income from fees 2", + "glCode": "10" + } + }, + { + "charge": { + "id": 2, + "name": "install per", + "active": false, + "penalty": false + }, + "incomeAccount": { + "id": 4, + "name": "income from interest", + "glCode": "04" + } + }, + { + "charge": { + "id": 5, + "name": "des charge", + "active": false, + "penalty": false + }, + "incomeAccount": { + "id": 9, + "name": "income from penalities 2", + "glCode": "11" + } + }, + "multiDisburseLoan":true,"maxTrancheCount":3,"outstandingLoanBalance":36000.000000, + "overdueDaysForNPA":2, + "principalThresholdForLastInstalment":50 + ] +} + +
+
+ +   +
+
+

Create a Loan Product

+

Depending of the Accounting Rule (accountingRule) selected, + additional fields with details of the appropriate Ledger Account + identifiers would need to be passed in. +

+ +

Refer + MifosX Accounting Specs Draft for more details regarding the + significance of the selected accounting rule +

+ + + + + + + + +
Mandatory Fields
name, shortName, currencyCode, digitsAfterDecimal, inMultiplesOf, principal, + numberOfRepayments, repaymentEvery, repaymentFrequencyType, + interestRatePerPeriod, interestRateFrequencyType, amortizationType, interestType, + interestCalculationPeriodType, transactionProcessingStrategyId, + accountingRule, isInterestRecalculationEnabled, daysInYearType, daysInMonthType
+ + + + + + + +
Optional Fields
inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAgeing, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle, + useBorrowerCycle,principalVariationsForBorrowerCycle, + numberOfRepaymentVariationsForBorrowerCycle, + interestRateVariationsForBorrowerCycle, + multiDisburseLoan,maxTrancheCount, + outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalcualtion +
+ + + + + + + +
Additional Mandatory Fields for Cash(2) based accounting
fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, + incomeFromFeeAccountId, incomeFromPenaltyAccountId, + writeOffAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId
+ + + + + + + +
Additional Mandatory Fields for periodic (3) and upfront (4)accrual accounting
fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, + incomeFromFeeAccountId, incomeFromPenaltyAccountId, + writeOffAccountId, receivableInterestAccountId, receivableFeeAccountId, + receivablePenaltyAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId
+ + + + + + + +
Additional Mandatory Fields if interest recalculation is enabled(true)
interestRecalculationCompoundingMethod, rescheduleStrategyMethod, recalculationRestFrequencyType
+ + + + + + + +
Additional Optional Fields if interest recalculation is enabled(true)
isArrearsBasedOnOriginalSchedule, preClosureInterestCalculationStrategy
+ + + + + + + +
Additional Optional Fields if interest recalculation is enabled(true) and recalculationRestFrequencyType is not same as repayment period
recalculationRestFrequencyInterval, recalculationRestFrequencyDate
+ + + + + + + +
Additional Optional Fields if interest recalculation is enabled(true) and interestRecalculationCompoundingMethod is enabled
recalculationCompoundingFrequencyType
+ + + + + + + +
Additional Optional Fields if interest recalculation is enabled(true) and interestRecalculationCompoundingMethod is enabled and + recalculationCompoundingFrequencyType is not same as repayment period
recalculationCompoundingFrequencyInterval, recalculationCompoundingFrequencyDate
+ + + + + + + +
Additional Mandatory Fields if Hold Guarantee funds is enabled(true)
mandatoryGuarantee
+ + + + + + + +
Additional Optional Fields if Hold Guarantee funds is enabled(true)
minimumGuaranteeFromOwnFunds,minimumGuaranteeFromGuarantor
+
+
+ +POST https://DomainName/api/v1/loanproducts + + +POST loanproducts +Content-Type: application/json +Request Body: +{"currencyCode":"USD", +"includeInBorrowerCycle":"true", +"useBorrowerCycle":true, +"digitsAfterDecimal":"2", +"inMultiplesOf":"0", +"repaymentFrequencyType":0, +"interestRateFrequencyType":2, +"amortizationType":1, +"interestType":0, +"interestCalculationPeriodType":1, +"transactionProcessingStrategyId":1, +"principalVariationsForBorrowerCycle":[], +"interestRateVariationsForBorrowerCycle":[], +"numberOfRepaymentVariationsForBorrowerCycle":[ + { + "valueConditionType":2, + "borrowerCycleNumber":"1", + "minValue":"5", + "defaultValue":"10", + "maxValue":"15" + }, + { + "valueConditionType":3, + "borrowerCycleNumber":"1", + "minValue":"7", + "defaultValue":"15", + "maxValue":"20" + } +], +"allowAttributeOverrides": + {amortizationType : true, + interestType : true, + transactionProcessingStrategyId : false, + interestCalculationPeriodType : true, + inArrearsTolerance : false, + repaymentEvery : true, + graceOnPrincipalAndInterestPayment : true, + graceOnArrearsAgeing : true}, + +"accountingRule":"2", +"name":"product 5", +"shortName":"prd5", +"principal":"5000", +"numberOfRepayments":"7", +"repaymentEvery":"7", +"interestRatePerPeriod":"5", +"paymentChannelToFundSourceMappings":[], +"feeToIncomeAccountMappings":[], +"penaltyToIncomeAccountMappings":[], +"charges":[], +"overdueDaysForNPA":2, +"dateFormat":"dd MMMM yyyy", +"locale":"en", +"fundSourceAccountId":1, +"loanPortfolioAccountId":2, +"transfersInSuspenseAccountId":3, +"interestOnLoanAccountId":4, +"incomeFromFeeAccountId":8, +"incomeFromPenaltyAccountId":9, +"writeOffAccountId":10, +"overpaymentLiabilityAccountId":11, +"daysInMonthType":1, +"daysInYearType":1, +"isInterestRecalculationEnabled":"false", +"holdGuaranteeFunds":"false", +"principalThresholdForLastInstallment":20 +} + + +{ + "resourceId": 1 +} + + +POST loanproducts +Content-Type: application/json +Request Body: +{ + "name": "LP Cash Accounting", + "shortName": "LPCA", + "currencyCode": "USD", + "locale": "en_GB", + "digitsAfterDecimal": "2", + "inMultiplesOf": 0, + "principal": "100,000.00", + "numberOfRepayments": "12", + "repaymentEvery": "1", + "repaymentFrequencyType": 2, + "transactionProcessingStrategyId": 1, + "interestRatePerPeriod": "1.75", + "interestRateFrequencyType": 2, + "amortizationType": 1, + "interestType": 0, + "interestCalculationPeriodType": 1, + "daysInMonthType":1, + "daysInYearType":1, + "isInterestRecalculationEnabled":"true", + "interestRecalculationCompoundingMethod":"0", + "rescheduleStrategyMethod":"3", + "recalculationRestFrequencyType":"1", + "preClosureInterestCalculationStrategy":1, + "accountingRule":"2", + "fundSourceAccountId":"4", + "loanPortfolioAccountId":"8", + "interestOnLoanAccountId":"34", + "incomeFromFeeAccountId":"37", + "incomeFromPenaltyAccountId":"35", + "writeOffAccountId":"41", + "transfersInSuspenseAccountId":"4", + "overpaymentLiabilityAccountId":"2", + "paymentChannelToFundSourceMappings": [ + { + "paymentTypeId": "11", + "fundSourceAccountId": "11" + } + ], + "feeToIncomeAccountMappings": [ + { + "chargeId": "1", + "incomeAccountId": "5" + }, + { + "chargeId": "2", + "incomeAccountId": "8" + } + ], + "penaltyToIncomeAccountMappings": [ + { + "chargeId": "6", + "incomeAccountId": "9" + } + ] + +} + + +{ + "resourceId": 2 +} + + +POST loanproducts +Content-Type: application/json +Request Body: +{ + "name": "LP Accrual Accounting", + "shortName": "LPAA", + "currencyCode": "USD", + "locale": "en_GB", + "digitsAfterDecimal": "2", + "inMultiplesOf": 0, + "principal": "100,000.00", + "numberOfRepayments": "12", + "repaymentEvery": "1", + "repaymentFrequencyType": 2, + "transactionProcessingStrategyId": 1, + "interestRatePerPeriod": "1.75", + "interestRateFrequencyType": 2, + "amortizationType": 1, + "interestType": 0, + "interestCalculationPeriodType": 1, + "daysInMonthType":1, + "daysInYearType":1, + "isInterestRecalculationEnabled":"false", + "accountingRule":"3", + "fundSourceAccountId":"4", + "loanPortfolioAccountId":"8", + "receivableInterestAccountId":"9", + "receivableFeeAccountId":"11", + "receivablePenaltyAccountId":"10", + "interestOnLoanAccountId":"34", + "incomeFromFeeAccountId":"37", + "incomeFromPenaltyAccountId":"35", + "overpaymentLiabilityAccountId":"2", + "writeOffAccountId":"41" +} + + +{ + "resourceId": 3 +} + + +
+
+ +   +
+
+

Update a Loan Product

+
+
+ +PUT https://DomainName/api/v1/loanproducts/{loanId} + + +PUT loanproducts/1 +Content-Type: application/json +Request Body: +{ + "locale": "en_GB", + "principal": "70,000.00" +} + + +{ + "resourceId": 1, + "changes": { + "principal": 70000, + "locale": "en_GB" + } +} + + +PUT loanproducts/3 +Content-Type: application/json +Request Body: +{ + "locale": "en", + "isInterestRecalculationEnabled":"true", + "interestRecalculationCompoundingMethod":"0", + "rescheduleStrategyMethod":"3", + "recalculationRestFrequencyType":"1" +} + + +{ + "resourceId": 1, + "changes": { + "locale": "en", + "isInterestRecalculationEnabled":"true", + "interestRecalculationCompoundingMethod":"0", + "rescheduleStrategyMethod":"3", + "recalculationRestFrequencyType":"1" + } +} + +
+
+ + + +   +
+
+

Loan Products Mix

+

If you have the appropriate permissions, you can decide which types of products a given client or group can mix. In this way, you can restrict clients from having active loans accounts of different products at the same time.

+ + + + + + + + + + + +
Field Descriptions
restrictedProducts
List of productIds to create a product mix
+
+
+ +   +
+
+

List Loan Product Mix

+

Example Requests:

+
loanproducts?associations=productMixes
+
+
+ +GET https://DomainName/api/v1/loanproducts?associations=productMixes + + +[ + { + "productId": 1, + "productName": "Personal Loan", + "restrictedProducts": [ + { + "id": 2, + "name": "Joint Loan", + "includeInBorrowerCycle": false + }, + { + "id": 5, + "name": "Primary Loan", + "includeInBorrowerCycle": false + }, + { + "id": 3, + "name": "Daily Loan", + "includeInBorrowerCycle": false + } + ], + "allowedProducts": [ + { + "id": 1, + "name": "Personal Loan", + "includeInBorrowerCycle": false + }, + { + "id": 6, + "name": "Personal Loan -2", + "includeInBorrowerCycle": false + }, + { + "id": 4, + "name": "Weekly Loan", + "includeInBorrowerCycle": false + } + ] + }, + { + "productId": 2, + "productName": "Joint Loan", + "restrictedProducts": [ + { + "id": 1, + "name": "Personal Loan", + "includeInBorrowerCycle": false + }, + { + "id": 6, + "name": "Personal Loan -2", + "includeInBorrowerCycle": false + } + ], + "allowedProducts": [ + { + "id": 3, + "name": "Daily Loan", + "includeInBorrowerCycle": false + }, + { + "id": 2, + "name": "Joint Loan", + "includeInBorrowerCycle": false + }, + { + "id": 5, + "name": "Primary Loan", + "includeInBorrowerCycle": false + }, + { + "id": 4, + "name": "Weekly Loan", + "includeInBorrowerCycle": false + } + ] + } +] + +
+
+ +   +
+
+

Retrieve Product Mix Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+

This request gets all the products details for which productmix is not defined.

+
+
loanproducts/template?isProductMixTemplate=true
+

+

This request gets the productmix details for the specific loanproduct.

+
+
loanproducts/5/productmix
+
+
loanproducts/5/productmix?template=true
+ +
+
+ +GET https://DomainName/api/v1/loanproducts/template?isProductMixTemplate=true + + +{ + "productOptions": [ + { + "id": 5, + "name": "Primary Loan" + }, + { + "id": 4, + "name": "Weekly Loan" + } + ] +} + + +GET https://DomainName/api/v1/loanproducts/5/productmix + + +{ + "restrictedProducts": [ + { + "id": 1, + "name": "Personal Loan", + "includeInBorrowerCycle": false + } + ], + "allowedProducts": [ + { + "id": 3, + "name": "Daily Loan", + "includeInBorrowerCycle": false + }, + { + "id": 2, + "name": "Joint Loan", + "includeInBorrowerCycle": false + }, + { + "id": 6, + "name": "Personal Loan -2", + "includeInBorrowerCycle": false + }, + { + "id": 5, + "name": "Primary Loan", + "includeInBorrowerCycle": false + }, + { + "id": 4, + "name": "Weekly Loan", + "includeInBorrowerCycle": false + } + ] +} + +
+
+ +   +
+
+

Retrieve Loan Product Mix

+

Example Requests:

+
loanproducts/5/productmix
+
+
+ +GET https://DomainName/api/v1/loanproducts/5/productmix + + +{ + "restrictedProducts": [ + { + "id": 1, + "name": "Personal Loan", + "includeInBorrowerCycle": false + } + ], + "allowedProducts": [ + { + "id": 3, + "name": "Daily Loan", + "includeInBorrowerCycle": false + }, + { + "id": 2, + "name": "Joint Loan", + "includeInBorrowerCycle": false + }, + { + "id": 6, + "name": "Personal Loan -2", + "includeInBorrowerCycle": false + }, + { + "id": 5, + "name": "Primary Loan", + "includeInBorrowerCycle": false + }, + { + "id": 4, + "name": "Weekly Loan", + "includeInBorrowerCycle": false + } + ] +} + +
+
+ +   +
+
+

Create a Loan Product Mix

+ + + + + + + + +
Mandatory Fields
restrictedProducts
+
+
+ +POST https://DomainName/api/v1/loanproducts/5/productmix + + +POST loanproducts/{productId}/productmix +Content-Type: application/json +Request Body: +{"restrictedProducts":["1"]} + + +{ + "changes":{ + "restrictedProductsForMix":[1], + "removedProductsForMix":[] + }, + "productId":5 +} + +
+
+ +   +
+
+

Update a Loan Product Mix

+
+
+ +PUT https://DomainName/api/v1/loanproducts/{productId}/productmix + + +PUT loanproducts/5/productmix +Content-Type: application/json +Request Body: +{ + "restrictedProducts":["3"] +} + + +{ + "changes": { + "restrictedProductsForMix": [3], + "removedProductsForMix": [1] + }, + "productId": 5 +} + +
+
+ +   +
+
+

Delete a Loan Product Mix

+
+
+ +DELETE https://DomainName/api/v1/loanproducts/{productId}/productmix + + +DELETE loanproducts/5/productmix + + +{ + "changes": { + "removedProductsForMix": [3] + }, + "productId": 5 +} + +
+
+ + + +   +
+
+

Holidays

+

Some MFI's span large regions where different branch offices might observe different holidays. They need the ability to define holidays for specific branch offices and be able to set the repayment rule to follow during those holidays. +

+

+ The reschedule of repayments to repaymentsRescheduledTo date during defined holidays is turned on/off by enabling/disabling reschedule-repayments-on-holidays in Global configurations. +

+

Allow Repayment transactions on a defined holidays is turned on/off by enabling/disabling allow-transactions-on-holiday in Global configurations. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name of the holiday. +
fromDate
The date on holiday begins. +
toDate
The date on holiday ends. +
repaymentsRescheduledTo
Date to which repayments will be rescheduled when repayments date falls on a defined holiday. e.g. A holiday is defined on 25th of October 2013 with repaymentsRescheduledTo date to 26th of October 2013 and any loans with repayments date on 25th of October 2013 will be rescheduled to 26th of October 2013. +
officeId
The officeId represents the office to which holiday is applied. +
+
+
+ +   +
+
+

List Holidays

+

Example Requests:

+
holidays?officeId=1
+
+
+
+
+ +GET https://DomainName/api/v1/holidays?officeId=1 + + +[ +{ + "id": 1, + "name": "Good Friday", + "fromDate": [ + 2013, + 10, + 25 + ], + "toDate": [ + 2013, + 10, + 25 + ], + "repaymentsScheduleTo": [ + 2013, + 10, + 26 + ], + "status": { + "id": 100, + "code": "holidayStatusType.pending.for.activation", + "value": "Pending for activation" + } +} +] + +
+
+ +   +
+
+

Create a Holiday

+ + + + + + + +
Mandatory Fields
name, description, fromDate, toDate, repaymentsRescheduledTo, offices
+
+
+ +POST https://DomainName/api/v1/holidays + + +POST holidays +Content-Type: application/json +Request Body: +{ +"name": "Good Friday", +"description": "Good Friday", +"dateFormat": "dd MMMM yyyy", +"locale": "en", +"fromDate": "25 October 2013", +"toDate": "25 October 2013", +"repaymentsRescheduledTo": "26 October 2013", +"offices": [ + {"officeId":"1"}, + {"officeId":"2"} +] +} + + +{ +"resourceId": 1 +} + +
+
+ +   +
+
+

Activate a Holiday

+

Always Holidays are created in pending state. This API allows to activate a holiday.

+

Only the active holidays are considered for rescheduling the loan repayment.

+
+
+ +POST https://DomainName/api/v1/holidays/{holidayId}?command=activate + + +POST holidays +Content-Type: application/json +Request Body: +{ +} + + +{ +"resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve a Holiday

+

Example Requests:

+
holidays/1
+
+
+
+ +GET https://DomainName/api/v1/holidays/{holidayId} + + +{ + "id": 1, + "name": "Good Friday", + "fromDate": [ + 2013, + 10, + 25 + ], + "toDate": [ + 2013, + 10, + 25 + ], + "repaymentsRescheduledTo": [ + 2013, + 10, + 26 + ], + "status": { + "id": 100, + "code": "holidayStatusType.active", + "value": "Active" + } +} + +
+
+ +   +
+
+

Update a Holiday

+

If a holiday is in pending state (created and not activated) then all fields are allowed to modify. Once holidays become active only name and descriptions are allowed to modify.

+
+
+ +PUT https://DomainName/api/v1/holidays/{holidayId} + + +PUT holidays/1 +Content-Type: application/json +Request Body: +{ + name:"Independence day", + description: "Holiday for Independence day celebration" +} + + +{ + "resourceId": 1, + "changes": { + "name": "Independence day", + "description": "Holiday for Independence day celebration" + } +} + +
+
+ +   +
+
+

Delete a Holiday

+

This API allows to delete a holiday. This is a soft delete the deleted holiday status is marked as deleted.

+
+
+ +DELETE https://DomainName/api/v1/holidays/{holidayId} + + +DELETE holidays/1 +Content-Type: application/json +Request Body: +{ +} + + +{ + "resourceId": 1 +} + +
+
+ + + +   +
+
+

Working days

+

The days of the week that are workdays. +

+

+ Rescheduling of repayments when it falls on a non-working is turned on /off by enable/disable reschedule-future-repayments parameter in Global configurations. +

+

+ Allow transactions on non-working days is configurable by enabling/disbaling the allow-transactions-on-non_workingday parameter in Global configurations. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Mandotory Field Descriptions
recurrence
Recurrence pattern
repaymentRescheduleType
repayment reschedule type .Options listed on the schedule for repayments on non-working days +
extendTermForDailyRepayments
Extend the term for loans following a daily repayment schedule.Expects boolean value true/false
locale
locale must be provided.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Schedule for repayments on non-working day
Same day
The repayments schedule for same day regardless of it's a non-working day. +
Next workday
The repayments reschedule to next working day. e.g. if a repayment falls on a non-working day will be rescheduled to next available working day. +
Previous workday
The repayments reschedule to previous working day. e.g. if a repayment falls on a non-working day will be rescheduled to previous available working day. +
Next scheduled meeting
The repayments reschduled to next scheduled meeting. +
+
+
+   +
+
+

Working Days Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for working days. +

+

Example Request:

+
workingdays/template
+
+
+ +GET https://DomainName/api/v1/workingdays/template + + +{ + "repaymentRescheduleOptions": [ + { + "id": 1, + "code": "RepaymentRescheduleType.same.day", + "value": "same day" + }, + { + "id": 4, + "code": "RepaymentRescheduleType.move.to.previous.working.day", + "value": "move to previous working day" + }, + { + "id": 3, + "code": "RepaymentRescheduleType.move.to.next.repayment.meeting.day", + "value": "move to next repayment meeting day" + }, + { + "id": 2, + "code": "RepaymentRescheduleType.move.to.next.working.day", + "value": "move to next working day" + } + ] +} + +
+
+   +
+
+

List Working days

+

Example Requests:

+
workingdays
+
+
+
+
+ +GET https://DomainName/api/v1/workingdays + + +[ + { + "id": 1, + "recurrence": "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR", + "repaymentRescheduleType": { + "id": 4, + "code": "RepaymentRescheduleType.move.to.next.working.day", + "value": "move to next working day" + } + "extendTermForDailyRepayments" : true + } +] + +
+
+   +
+
+

Update a Working Day

+ + + + + + + +
Mandatory Fields
recurrence,repaymentRescheduleType,extendTermForDailyRepayments,locale
+
+
+ +PUT https://DomainName/api/v1/Workingdays/1 + + +PUT holidays +Content-Type: application/json +Request Body: +{ +"recurrence": "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,SU", +"locale": "en", +"repaymentsRescheduledType": 4, +"extendTermForDailyRepayments": false +} + + +{ +"resourceId": 1 +} + +
+
+ + + + +   +
+
+

Currency

+

Application related configuration around viewing/updating + the currencies permitted for use within the MFI.

+
+
+ +   +
+
+

Retrieve Currency Configuration

+

Returns the list of currencies permitted for use AND the + list of currencies not selected (but available for selection).

+

Example Requests:

+
currencies
+
+
+
currencies?fields=selectedCurrencyOptions
+
+
+ +GET https://DomainName/api/v1/currencies + + +{ + "selectedCurrencyOptions": [ + { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + ], + "currencyOptions": [ + { + "code": "AFN", + "name": "Afghanistan Afghani", + "decimalPlaces": 2, + "nameCode": "currency.AFN", + "displayLabel": "Afghanistan Afghani [AFN]" + }, + { + "code": "ALL", + "name": "Albanian Lek", + "decimalPlaces": 2, + "nameCode": "currency.ALL", + "displayLabel": "Albanian Lek [ALL]" + }, + { + "code": "ZWD", + "name": "Zimbabwe Dollar", + "decimalPlaces": 2, + "nameCode": "currency.ZWD", + "displayLabel": "Zimbabwe Dollar [ZWD]" + } + ] +} + +
+
+ +   +
+
+

Update Currency Configuration

+

Updates the list of currencies permitted for use.

+
+
+ +PUT https://DomainName/api/v1/currencies + + +PUT currencies +Content-Type: application/json +Request Body: +{ + "currencies": [ + "KES", + "BND", + "LBP", + "GHC", + "USD", + "XOF", + "AED", + "AMD" + ] +} + + +{ + "currencies": [ + "KES", + "BND", + "LBP", + "GHC", + "USD", + "XOF", + "AED", + "AMD" + ] +} + +
+
+ +   +
+
+

Global Configuration

+

Global configuration related to set of supported enable/disable configurations:

+
    +
  1. maker-checker - defaults to false - if true turns on maker-checker functionality
  2. +
  3. reschedule-future-repayments - defaults to false - if true reschedules repayemnts which falls on a non-working day to configured repayment rescheduling rule
  4. +
  5. allow-transactions-on-non_workingday - defaults to false - if true allows transactions on non-working days
  6. +
  7. reschedule-repayments-on-holidays - defaults to false - if true reschedules repayemnts which falls on a non-working day to defined reschedule date
  8. +
  9. allow-transactions-on-holiday - defaults to false - if true allows transactions on holidays
  10. +
  11. savings-interest-posting-current-period-end - Set it at the database level before any savings interest is posted. When set as false(default), interest will be posted on the first date of next period. If set as true, interest will be posted on last date of current period. There is no difference in the interest amount posted.
  12. +
  13. financial-year-beginning-month - Set it at the database level before any savings interest is posted. Allowed values 1 - 12 (January - December). Interest posting periods are evaluated based on this configuration.
  14. +
  15. meetings-mandatory-for-jlg-loans - if set to true, enforces all JLG loans to follow a meeting schedule belonging to either the parent group or Center.
  16. +
+
+
+ +   +
+
+

Retrieve Global Configuration

+

Returns the list global enable/disable configurations.

+

Example Requests:

+
configurations
+
+
+ +GET https://DomainName/api/v1/configurations + + +{ + "globalConfiguration": [ + { + "name": "maker-checker", + "enabled": true, + "value": 0, + "id": 1 + }, + { + "name": "amazon-S3", + "enabled": false, + "value": 0, + "id": 2 + }, + ] +} + +
+
+ +  +
+
+

Retrieve Global Configuration

+

Returns a global enable/disable configurations.

+

Example Requests:

+
configurations/1
+
+
+ +GET https://DomainName/api/v1/configurations/1 + + + { + "name": "maker-checker", + "enabled": true, + "value": 0, + "id": 1 + } + +
+
+ +   +
+
+

Retrieve Global Configuration for surveys

+

Returns the list global enable/disable survey configurations.

+

Example Requests:

+
configurations/survey
+
+
+ + GET https://DomainName/api/v1/configurations/survey + + + { + "ppi_kenya_2005": [ + { + "name": "maker-checker", + "enabled": true, + "value": 0, + "id": 1 + }, + { + "name": "ppi_tanzania_20012", + "enabled": false, + "value": 0, + "id": 2 + }, + ] + } + +
+
+ +   +
+
+

Update Global Configuration

+

Updates an enable/disable global configuration item.

+
+
+ +PUT https://DomainName/api/v1/configurations/9 + + +PUT configurations +Content-Type: application/json +Request Body: { + "enabled":"true", + "value":2 + + } + + +{ + "resourceId": 9, + "changes": { + "enabled": true + } +} +
+
+ +   +
+
+

Cache

+

The following settings are possible for cache: +

    +
  • No Caching: caching turned off
  • +
  • Single node: caching on for single instance deployments of platorm (works for multiple tenants but only one tomcat)
  • +
+

+

By default caching is set to No Caching. Switching between caches results in the cache been clear e.g. from Single node to No cache and back again would clear down the single node cache.

+
+
+ +   +
+
+

Retrieve Cache Types

+

Returns the list of caches.

+

Example Requests:

+
caches
+
+
+ +GET https://DomainName/api/v1/caches + + +[ + { + "cacheType": { + "id": 1, + "code": "cacheType.noCache", + "value": "No cache" + }, + "enabled": true + }, + { + "cacheType": { + "id": 2, + "code": "cacheType.singleNode", + "value": "Single node" + }, + "enabled": false + }, + { + "cacheType": { + "id": 3, + "code": "cacheType.multiNode", + "value": "Multi node" + }, + "enabled": false + } +] + +
+
+ +   +
+
+

Switch Cache

+

Switches the cache to chosen one.

+
+
+ +PUT https://DomainName/api/v1/caches + + +PUT caches +Content-Type: application/json +Request Body: +{ + "cacheType": 2 +} + + +{ + "changes": { + "cacheType": 2 + } +} + +
+
+   +
+
+

Hooks

+

Hooks are a mechanism to trigger custom code on the occurence of events.

+

Each template during hook creation represents custom behaviour on what actions should be taken on the triggering of a registered event for a hook. The action taken might be firing a HTTP request to another server or execute internal code. +

+

In order for MifosX to send webhook payloads, your server needs to be accessible from the Internet. MifosX will send along a few HTTP headers to differentiate between event types.

+

X-Mifos-Entity - The entity type that was triggered.
+ X-Mifos-Action - The action triggered on the entity type.
+ X-Mifos-Platform-TenantId - The tenant which experienced the event.

+
+
+ +   +
+
+

Create a Hook

+

The following parameters can be passed for the creation of a hook :- +

    +
  • name - string - Required. The name of the template that is being called. (See /hooks/template for the list of valid hook names.)
  • +
  • isActive - boolean - Determines whether the hook is actually triggered.
  • +
  • events - array - Determines what events the hook is triggered for. +
  • +
  • config - hash - Required. Key/value pairs to provide settings for this hook. These settings vary between the templates.
  • +
  • templateId - Optional. The UGD template ID associated with the same entity (client or loan).
  • +

      +
+
+ +POST https://DomainName/api/v1/hooks + + +POST hooks +Content-Type: application/json +Request Body: +{ + "name": "Web", + "isActive": true, + "displayName": "Kremlin", + "templateId": 1, + "events": [ + { + "actionName": "DISBURSE", + "entityName": "LOAN" + }, + { + "actionName": "REPAYMENT", + "entityName": "LOAN" + } + ], + "config": { + "Payload URL": "http://example.com/webhook", + "Content Type": "json" + } +} + + +{ + "resourceId": 4 +} + +
+
+ +   +
+
+

Retrieve Hooks

+

Returns the list of hooks.

+

Example Requests:

+
hooks
+
+
+ +GET https://DomainName/api/v1/hooks + + +[ + { + "id": 1, + "name": "Web", + "displayName": "Kremlin", + "isActive": true, + "createdAt": [2014, 9, 16], + "updatedAt": [2014, 9, 16], + "templateId": 1, + "templateName": "My UGD", + "events": [ + { + "actionName": "DISBURSE", + "entityName": "LOAN" + }, + { + "actionName": "REPAYMENT", + "entityName": "LOAN" + } + ], + "config": [ + { + "fieldName": "Content Type", + "fieldValue": "json" + }, + { + "fieldName": "Payload URL", + "fieldValue": "https://abc.com/api" + } + ] + } +] + +
+
+ +   +
+
+

Retrieve a Hook

+

Returns the details of a Hook.

+

Example Requests:

+
hooks/1
+
+
+ +GET https://DomainName/api/v1/hooks/{hookId} + + +{ + "id": 1, + "name": "Web", + "displayName": "Kremlin", + "isActive": true, + "createdAt": [2014, 9, 16], + "updatedAt": [2014, 9, 16], + "templateId": 1, + "templateName": "My UGD", + "events": [ + { + "actionName": "DISBURSE", + "entityName": "LOAN" + }, + { + "actionName": "REPAYMENT", + "entityName": "LOAN" + } + ], + "config": [ + { + "fieldName": "Content Type", + "fieldValue": "json" + }, + { + "fieldName": "Payload URL", + "fieldValue": "https://abc.com/api" + } + ] +} + +
+
+ +   +
+
+

Update a Hook

+

Updates the details of a hook.

+
+
+ +PUT https://DomainName/api/v1/hooks/{hookId} + + +PUT hooks/4 +Content-Type: application/json +Request Body: +{ + "name": "Web", + "isActive": true, + "displayName": "Local SMS Provider", + "events": [ + { + "actionName": "DISBURSE", + "entityName": "LOAN" + } + ], + "config": { + "Payload URL": "http://changed.com/sms", + "Content Type": "json" + } +} + + +{ + "resourceId": 4, + "changes": { + "displayName": "Local SMS Provider", + "events": [ + { + "actionName": "DISBURSE", + "entityName": "LOAN" + } + ], + "config": { + "Payload URL": "http://changed.com/sms", + "Content Type": "json" + } + } +} + +
+
+ +   +
+
+

Delete a Hook

+

Deletes a hook.

+
+
+ +DELETE https://DomainName/api/v1/hooks/{hookId} + + +DELETE hooks/4 +Content-Type: application/json + + +{ + "resourceId": 4 +} + +
+
+ +   +
+
+

Retrieve Hooks Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
hooks/template
+
+
+ +GET https://DomainName/api/v1/hooks/template + + +{ + "templates": [ + { + "name": "Web", + "schema": [ + { + "fieldName": "Content Type", + "fieldType": "string", + "optional": true, + "placeholder": "json / form" + }, + { + "fieldName": "Payload URL", + "fieldType": "string", + "optional": false + } + ] + }, + { + },... + ], + "groupings": [ + { + "name": "jobs", + "entities": [ + { + "name": "SCHEDULER", + "actions": ["EXECUTEJOB", "UPDATE"] + }, + { + },... + ] + }, + { + },... + ] +} + +
+
+ +   +
+
+

Codes

+

Code and code values: Codes represent a specific category of + data, their code values are a specific instance of that category.

+

+ Codes are mostly system defined which means the code itself + comes out of the box and cannot be modified however its code values + can be. e.g. 'Customer Identifier', it defaults to a code value of + 'Passport' but could be 'Drivers License, National Id' etc +

+

+
+ +   +
+
+

Create a Code

+

Creates a code. Codes created through api are always 'user + defined' and so system defined is marked as false.

+
+
+ +POST https://DomainName/api/v1/codes + + +POST codes +Content-Type: application/json +Request Body: +{ + "name": "MyNewCode" +} + + +{ + "resourceId": 4 +} + +
+
+ +   +
+
+

Retrieve Codes

+

Returns the list of codes.

+

Example Requests:

+
codes
+
+
+ +GET https://DomainName/api/v1/codes + + +[ + { + "id": 1, + "name": "Customer Identifier", + "systemDefined": true + }, + { + "id": 2, + "name": "Gender", + "systemDefined": true + }, + { + "id": 3, + "name": "Education", + "systemDefined": true + } +] + +
+
+ +   +
+
+

Retrieve a Code

+

Returns the details of a Code.

+

Example Requests:

+
codes/1
+
+
+ +GET https://DomainName/api/v1/codes/{codeId} + + +{ + "id": 1, + "name": "Customer Identifier", + "systemDefined": true +} + +
+
+ +   +
+
+

Update a Code

+

Updates the details of a code if it is not system defined.

+
+
+ +PUT https://DomainName/api/v1/codes/{codeId} + + +PUT codes/4 +Content-Type: application/json +Request Body: +{ + "name": "MyNewCode(changed)" +} + + +{ + "resourceId": 4, + "changes": { + "name": "MyNewCode(changed)" + } +} + +
+
+ +   +
+
+

Delete a Code

+

Deletes a code if it is not system defined.

+
+
+ +DELETE https://DomainName/api/v1/codes/{codeId} + + +DELETE codes/4 +Content-Type: application/json + + +{ + "resourceId": 4 +} + +
+
+ + +   +
+
+

Code Values

+

Code and code values: Codes represent a specific category of + data, their code values are a specific instance of that category.

+

+ Codes are mostly system defined which means the code itself + comes out of the box and cannot be modified however its code values + can be. e.g. 'Customer Identifier', it defaults to a code value of + 'Passport' but could be 'Drivers License, National Id' etc +

+

+
+ +   +
+
+

Create a Code Value

+
+
+ +POST https://DomainName/api/v1/codes/1/codevalues + + +POST codes/1/codevalues +Content-Type: application/json +Request Body: +{ + "name":"Ration Card", + "description: "Ration card information", + "position":"1" +} + + +{ + "resourceId": 4 +} + +
+
+ +   +
+
+

List Code Values

+

Returns the list of Code Values for a given Code

+

Example Requests:

+
codes/1/codevalues
+
+
+ +GET https://DomainName/api/v1/codes/{codeId}/codevalues + + +[ + { + "id": 1, + "name": "Passport", + "description: "Passport information", + "position": 0 + }, + { + "id": 2, + "name": "Id", + "description: "ID information", + "position": 0 + }, + { + "id": 3, + "name": "Drivers License", + "description: "Drivers License information", + "position": 0 + }, + { + "id": 4, + "name": "Any Other Id Type", + "description: "Any Other Id Type information", + "position": 0 + }, + { + "id": 5, + "name": "Ration Card", + "description: "Ration Card information", + "position": 1 + } +] + +
+
+ +   +
+
+

Retrieve a Code Value

+

Returns the details of a Code Value

+

Example Requests:

+
codes/1/codevalues/1
+
+
+ +GET https://DomainName/api/v1/codes/{codeId}/codevalues/{codevalueId} + + +{ + "id": 1, + "name": "Passport", + "description: "Passport information", + "position": 0 +} + +
+
+ +   +
+
+

Update a Code Value

+

Updates the details of a code value.

+
+
+ +PUT https://DomainName/api/v1/codes/{codeId}/codevalues/{codevalueId} + + +PUT codes/1/codevalues/1 +Content-Type: application/json +Request Body: +{ + "name": "Indian Passport", + "description": "Indian Passport information", + "position":2 +} + + +{ + "resourceId": 1, + "changes": + { + "name": "Indian Passport", + "description": "Indian Passport information", + "position": 2 + } +} + +
+
+ +   +
+
+

Delete a Code Value

+

Deletes a code value

+
+
+ +DELETE https://DomainName/api/v1/codes/{codeId}/codevalues/{codevalueId} + + +DELETE codes/1/codevalues/5 +Content-Type: application/json + + +{ + "resourceId": 5 +} + +
+
+ + + +   +
+
+

Audits

+

Every non-read Mifos API request is audited. A fully processed request can + not be changed or deleted. See maker checker api for situations where an audit is not + fully processed.

+ + Permissions: To search and look at audit entries a user needs to be attached to a role + that has one of the ALL_FUNCTIONS, ALL_FUNCTIONS_READ or READ_AUDIT permissions.

+ + Data Scope: A user can only see audits that are within their data scope. However, + 'head office' users can see all audits including those that aren't office/branch related + e.g. Loan Product changes. +

+

+
+ +   +
+
+

List Audits

+

Get a 200 list of audits that match the criteria supplied and sorted by audit id in descending order, + and are within the requestors' data scope. Also it supports pagination and sorting

+
Arguments
+
+
actionName
+
optional
+
Examples: CREATE, UPDATE, DISBURSE
+ +
entityName
+
optional
+
Examples: CLIENT, LOAN, FUND
+ +
resourceId
+
optional, + The id value of the entityName +
+ +
makerId
+
optional, + The id value of the application user creating the entry +
+ +
makerDateTimeFrom
+
optional, + Get entries created on or after this +
+
Example: 2013-04-10 08:00:00
+ +
makerDateTimeTo
+
optional, + Get entries created on or before this +
+
Example: 2013-05-10 08:00:00
+ +
checkerId
+
optional, + The id value of the application user that checked (approved) the entry +
+ +
checkerDateTimeFrom
+
optional, + Get entries checked on or after this +
+
Example: 2013-04-10 08:00:00
+ +
checkerDateTimeTo
+
optional, + Get entries checked on or before this +
+
Example: 2013-05-10 18:00:00
+ +
processingResult
+
optional, + The enum value of the processing status +
+
values:
+ 0: Invalid
+ 1: processed
+ 2: awaiting.approval
+ 3: rejected +
+ +
officeId
+
optional, + The id value of the office/branch associated with the entry (if there is one) +
+ +
groupId
+
optional, + The id value of the group associated with the entry (if there is one). + A group is a general idea and may be a Center, a Group, a Communal Bank or other. +
+ +
clientId
+
optional, + The id value of the client associated with the entry (if there is one) +
+ +
loanId
+
optional, + The id value of the loan associated with the entry (if there is one) +
+ +
savingsAccountId
+
optional, + The id value of the savings account associated with the entry (if there is one) +
+ +
includeJson
+
optional, + Values are true, false. Default is false. +
+
paged
+
+ Boolean optional, defaults to false +
+
If paged is true then results will be paginated.
+ +
offset
+
+ Integer optional, defaults to 0 +
+
Indicates from what result to start from.
+ +
limit
+
+ Integer optional, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
orderBy
+
+ String optional, one of id, actionName, entityName, resourceId, subresourceId, madeOnDate, checkedOnDate, officeName, groupName, clientName, loanAccountNo, savingsAccountNo +
+
Orders the results by the field indicated.
+ +
sortBy
+
+ String optional, one of ASC, DESC +
+
Indicates what way to order results if orderBy is used.
+ +
+

Example Requests:

+
audits

+
audits?fields=madeOnDate,maker,processingResult

+
audits?makerDateTimeFrom=2013-03-25 08:00:00&makerDateTimeTo=2013-04-04 18:00:00

+
audits?officeId=1

+
audits?officeId=1&includeJson=true
+
+
+ +GET https://DomainName/api/v1/audits + + +[ + { + "id": 671, + "actionName": "PERMISSIONS", + "entityName": "ROLE", + "resourceId": 6, + "maker": "keithwoodlock", + "madeOnDate": 1365014262000, + "processingResult": "processed" + }, + { + "id": 670, + "actionName": "CREATE", + "entityName": "CLIENTNOTE", + "resourceId": 287, + "maker": "keithwoodlock", + "madeOnDate": 1365014204000, + "processingResult": "awaiting.approval", + "officeName": "my office", + "clientName": "gg ggg" + }, + { + "id": 668, + "actionName": "UPDATE", + "entityName": "PERMISSION", + "maker": "keithwoodlock", + "madeOnDate": 1365014186000, + "processingResult": "processed" + }, + { + "id": 667, + "actionName": "CREATE", + "entityName": "CLIENTNOTE", + "resourceId": 286, + "maker": "keithwoodlock", + "madeOnDate": 1365014169000, + "processingResult": "processed", + "officeName": "my office name", + "clientName": "gg ggg" + }, + { + "id": 666, + "actionName": "CREATE", + "entityName": "CLIENT", + "resourceId": 363, + "maker": "keithwoodlock", + "madeOnDate": 1365012843000, + "processingResult": "awaiting.approval", + "officeName": "my office name" + }, + { + "id": 657, + "actionName": "CREATE", + "entityName": "CLIENT", + "resourceId": 362, + "maker": "ii", + "madeOnDate": 1364953928000, + "checker": "ii", + "checkedOnDate": 1365010060000, + "processingResult": "processed", + "officeName": "my office name", + "clientName": "gg ggg" + }, + { + "id": 645, + "actionName": "CREATE", + "entityName": "LOAN", + "resourceId": 373, + "maker": "keithwoodlock", + "madeOnDate": 1364860260000, + "checker": "keithwoodlock", + "checkedOnDate": 1364861222000, + "processingResult": "processed", + "officeName": "another office", + "clientName": "another client", + "loanAccountNo": "000000373" + },... + ] + + +GET https://DomainName/api/v1/audits?paged=true&limit=5 + + +{ + "totalFilteredRecords": 30, + "pageItems": [ + { + "id": 671, + "actionName": "PERMISSIONS", + "entityName": "ROLE", + "resourceId": 6, + "maker": "keithwoodlock", + "madeOnDate": 1365014262000, + "processingResult": "processed" + }, + { + "id": 670, + "actionName": "CREATE", + "entityName": "CLIENTNOTE", + "resourceId": 287, + "maker": "keithwoodlock", + "madeOnDate": 1365014204000, + "processingResult": "awaiting.approval", + "officeName": "my office", + "clientName": "gg ggg" + }, + { + "id": 668, + "actionName": "UPDATE", + "entityName": "PERMISSION", + "maker": "keithwoodlock", + "madeOnDate": 1365014186000, + "processingResult": "processed" + }, + { + "id": 667, + "actionName": "CREATE", + "entityName": "CLIENTNOTE", + "resourceId": 286, + "maker": "keithwoodlock", + "madeOnDate": 1365014169000, + "processingResult": "processed", + "officeName": "my office name", + "clientName": "gg ggg" + }, + { + "id": 666, + "actionName": "CREATE", + "entityName": "CLIENT", + "resourceId": 363, + "maker": "keithwoodlock", + "madeOnDate": 1365012843000, + "processingResult": "awaiting.approval", + "officeName": "my office name" + } + ] +} + +
+
+ +   +
+
+

Audit Search Template

+

This is a convenience resource. It can be useful when + building an Audit Search UI. "appUsers" are data scoped to + the office/branch the requestor is associated with. +

+

Example Requests:

+
audits/searchtemplate
+
audits/searchtemplate?fields=actionNames
+
+
+ +GET https://DomainName/api/v1/audits/searchtemplate + + +{ + "appUsers": [ + { + "id": 30, + "username": "user 1" + }, + { + "id": 28, + "username": "user 2" + }, + { + "id": 35, + "username": "user 3" + },... + ], + "actionNames": [ + "CREATE", + "DELETE", + "UPDATE", + "ACTIVATE", + "ADJUST", + "APPROVALUNDO", + "APPROVE", + "APPROVEINPAST", + "BULKREASSIGN", + "CALCULATEINTEREST", + "CLOSE", + "CLOSEASRESCHEDULED", + "CREATEHISTORIC", + "DEPOSIT", + "DEREGISTER", + "DISBURSALUNDO", + "DISBURSE", + "DISBURSEINPAST", + "INTEREST", + "PERMISSIONS", + "REGISTER", + "REJECT",... + ], + "entityNames": [ + "CALENDAR", + "CENTER", + "CHARGE", + "CLIENT", + "CLIENTIDENTIFIER", + "CLIENTIMAGE", + "CLIENTNOTE", + "CODE", + "CODEVALUE", + "COLLATERAL", + "CONFIGURATION", + "CURRENCY", + "DATATABLE", + "DEPOSITACCOUNT", + "DEPOSITNOTE", + "DEPOSITPRODUCT", + "DOCUMENT", + "FUND", + "GLACCOUNT", + "GLCLOSURE", + "GROUP", + "GROUPNOTE",... + ], + "processingResults": [ + { + "id": 0, + "processingResult": "invalid" + }, + { + "id": 1, + "processingResult": "processed" + }, + { + "id": 2, + "processingResult": "awaiting.approval" + }, + { + "id": 3, + "processingResult": "rejected" + } + ] +} + +
+
+ + +   +
+
+

Retrieve an Audit Entry

+

+

Example Requests:

+
audits/20
+
audits/20?fields=madeOnDate,maker,processingResult
+
+
+ +GET https://DomainName/api/v1/audits + + +{ + "id": 20, + "actionName": "REPAYMENT", + "entityName": "LOAN", + "resourceId": 868, + "maker": "dataentry1", + "madeOnDate": 1358449025000, + "processingResult": "processed", + "commandAsJson": "{\"transactionDate\":\"28 September 2012\",\"transactionAmount\":\"1,967.00\",\"locale\":\"en\",\"dateFormat\":\"dd MMMM yyyy\"}", + "officeName": "another office", + "clientName": "another client", + "loanAccountNo": "23" +} + +
+
+ + + +   +
+
+

Account number format

+

Account number preferences are used to describe custom formats for account numbers associated with Customer, Loan and Savings accounts. +

+ + + + + + + + + + + + + + + + + +
Field Descriptions
accountType
Identifies the type of the Account for which the Account number format applies
+ Refer Retrieve + Account number formats Template for complete + details +
prefixType
Identifies a custom prefix for the account number +
+ Refer Retrieve + Account number formats Template for complete + details +
+
+
+ +   +
+
+

List Account number formats

+

Example Requests:

+
accountnumberformats
+
+
+
accountnumberformats?fields=accountType,prefixType
+
+
+ +GET https://DomainName/api/v1/accountnumberformats + + +[ + { + "id": 2, + "accountType": + { + "id": 1, + "code": "accountType.client", + "value": "CLIENT" + }, + "prefixType": + { + "id": 101, + "code": "accountNumberPrefixType.clientType", + "value": "CLIENT_TYPE" + } + }, + { + "id": 3, + "accountType": + { + "id": 2, + "code": "accountType.loan", + "value": "LOAN" + }, + "prefixType": + { + "id": 201, + "code": "accountNumberPrefixType.loanProductShortName", + "value": "LOAN_PRODUCT_SHORT_NAME" + } + } +] + +
+
+ +   +
+
+

Retrieve Account number format Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
accountnumberformats/template
+
+
+ +GET https://DomainName/api/v1/accountnumberformats/template + + + + + { + "accountTypeOptions": + [ + { + "id": 1, + "code": "accountType.client", + "value": "CLIENT" + }, + { + "id": 2, + "code": "accountType.loan", + "value": "LOAN" + }, + { + "id": 3, + "code": "accountType.savings", + "value": "SAVINGS" + }, + { + "id": 4, + "code": "accountType.center", + "value": "CENTER" + }, + { + "id": 5, + "code": "accountType.group", + "value": "GROUP" + } + ], + "prefixTypeOptions": + { + "accountType.loan": + [ + { + "id": 201, + "code": "accountNumberPrefixType.loanProductShortName", + "value": "LOAN_PRODUCT_SHORT_NAME" + }, + { + "id": 1, + "code": "accountNumberPrefixType.officeName", + "value": "OFFICE_NAME" + } + ], + "accountType.client": + [ + { + "id": 1, + "code": "accountNumberPrefixType.officeName", + "value": "OFFICE_NAME" + }, + { + "id": 101, + "code": "accountNumberPrefixType.clientType", + "value": "CLIENT_TYPE" + } + ], + "accountType.savings": + [ + { + "id": 301, + "code": "accountNumberPrefixType.savingsProductShortName", + "value": "SAVINGS_PRODUCT_SHORT_NAME" + }, + { + "id": 1, + "code": "accountNumberPrefixType.officeName", + "value": "OFFICE_NAME" + } + ], + "accountType.center": + [ + { + "id": 1, + "code": "accountNumberPrefixType.officeName", + "value": "OFFICE_NAME" + } + ], + "accountType.group": + [ + { + "id": 1, + "code": "accountNumberPrefixType.officeName", + "value": "OFFICE_NAME" + }, + ] + } + } + + + +
+
+ +   +
+
+

Retrieve an Account number format

+

Example Requests:

+
accountnumberformats/1
+
+
+
accountnumberformats/1?template=true
+
+
+
accountnumberformats/1?fields=accountType,prefixType
+
+
+ +GET https://DomainName/api/v1/accountnumberformats/{accountnumberformatId} + + + +{ + "id": 2, + "accountType": + { + "id": 1, + "code": "accountType.client", + "value": "CLIENT" + }, + "prefixType": + { + "id": 101, + "code": "accountNumberPrefixType.clientType", + "value": "CLIENT_TYPE" + } +} + + +
+
+ +   +
+
+

Create an Account number format

+

+ Note: You may associate a single Account number format for a given account type
+

+ + + + + + + +
Mandatory Fields + for Account number formats
accountType
+
+
+ +POST https://DomainName/api/v1/accountnumberformats + + +POST /accountnumberformats +Content-Type: application/json +Request Body: +{ + accountType :1, + prefixType: 101 +} + + +{ + "resourceId": 4 +} + + + +POST /accountnumberformats +Content-Type: application/json +Request Body: +{ + accountType :2, + prefixType: 201 +} + + +{ + "resourceId": 5 +} + +
+
+ +   +
+
+

Update an Account number format

+
+
+ +PUT https://DomainName/api/v1/accountnumberformats/{accountnumberformatId} + + +PUT accountnumberformats/2 +Content-Type: application/json +Request Body: +{ + prefixType:1 +} + + +{ + "resourceId": 2, + "changes": + { + "prefixType": "OFFICE_NAME" + } +} + + +
+
+ +   +
+
+

Delete an Account number format

+

+ Note: Account numbers created while this format was active would remain unchanged. +

+
+
+ +DELETE https://DomainName/api/v1/accountnumberformats/{accountnumberformatId} + + +DELETE accountnumberformats/2 +Content-Type: application/json +No Request Body: + + +{ + "resourceId": 2 +} + + +
+
+ + +   +
+
+

Maker Checker (or 4-eye) functionality

+

Apache Fineract Maker Checker functionality allows an MFI to define transactions + as having a maker and a checker phase. One user enters, deletes or changes data. + Then, another user that has "Checker" rights for that transaction, can inspect + and approve the data. +

+ +

By default, Maker Checker functionality is disabled. + See Update Global Configuration to enable/disable + Maker Checker functionality at a global level. +

+ +

+ Additionally, Maker Checker functionality for each transaction (permission) is disabled by default. + see Enable/Disable Permissions for Maker Checker to enable/disable + Maker Checker functionality at a transaction (permission) level. +

+ +

+ Finally, to give checking rights to a user (via a role associated with the user) see + Update a Role's Permissions +

+

For example,
+ +{ + "permissions":{ + "CREATE_GUARANTOR_CHECKER":true, + "CREATE_CLIENT_CHECKER":true + } +} + +
+ will give checking rights for CREATE_GUARANTOR and CREATE_CLIENT

+

Alternatively, the special permissions ALL_FUNCTIONS or CHECKER_SUPER_USER will give blanket + checking rights. +

+

+ When a user "makes" an entry that is enabled for Maker Checker, it is audited and the audit status + is set to a value of 2 (awaiting.approval). +

+ + Checkers can only Check and approve entries that they have been permitted to check.

+ + Checkers can only Check and approve entries that are within their data scope. However, + 'head office' Checkers can Check and approve all entries + including those that aren't office/branch related (as long as they have the Checker permissions) + e.g. Loan Product changes. +

+

+
+ +   +
+
+

List Maker Checker Entries

+

Get a list of entries that can be checked by the requestor that match the criteria supplied.

+
Arguments
+
+
actionName
+
optional
+
Examples: CREATE, UPDATE, DISBURSE
+ +
entityName
+
optional
+
Examples: CLIENT, LOAN, FUND
+ +
resourceId
+
optional, + The id value of the entityName +
+ +
makerId
+
optional, + The id value of the application user creating the entry +
+ +
makerDateTimeFrom
+
optional, + Get entries created on or after this +
+
Example: 2013-04-10 08:00:00
+ +
makerDateTimeTo
+
optional, + Get entries created on or before this +
+
Example: 2013-05-10 08:00:00
+ +
officeId
+
optional, + The id value of the office/branch associated with the entry (if there is one) +
+ +
groupId
+
optional, + The id value of the group associated with the entry (if there is one). + A group is a general idea and may be a Center, a Group, a Communal Bank or other. +
+ +
clientId
+
optional, + The id value of the client associated with the entry (if there is one) +
+ +
loanId
+
optional, + The id value of the loan associated with the entry (if there is one) +
+ +
savingsAccountId
+
optional, + The id value of the savings account associated with the entry (if there is one) +
+ +
includeJson
+
optional, + Values are true, false. Default is false. +
+ +
+

Example Requests:

+
makercheckers

+
makercheckers?fields=madeOnDate,maker,processingResult

+
makercheckers?makerDateTimeFrom=2013-03-25 08:00:00&makerDateTimeTo=2013-04-04 18:00:00

+
makercheckers?officeId=1

+
makercheckers?officeId=1&includeJson=true
+
+
+ +GET https://DomainName/api/v1/makercheckers + + +[ + { + "id": 654, + "actionName": "CREATE", + "entityName": "LOANPRODUCT", + "resourceId": 15, + "maker": "keithwoodlock", + "madeOnDate": 1364924512000, + "processingResult": "awaiting.approval" + }, + { + "id": 666, + "actionName": "CREATE", + "entityName": "CLIENT", + "resourceId": 363, + "maker": "keithwoodlock", + "madeOnDate": 1365012843000, + "processingResult": "awaiting.approval", + "officeName": "my office name" + }, + { + "id": 670, + "actionName": "CREATE", + "entityName": "CLIENTNOTE", + "resourceId": 287, + "maker": "keithwoodlock", + "madeOnDate": 1365014204000, + "processingResult": "awaiting.approval", + "officeName": "my office name", + "clientName": "gg ggg" + } +] + +
+
+ +   +
+
+

Maker Checker Search Template

+

This is a convenience resource. It can be useful when + building a Checker Inbox UI. "appUsers" are data scoped to + the office/branch the requestor is associated with. + "actionNames" and "entityNames" returned are those that the + requestor has Checker approval permissions for. +

+

Example Requests:

+
makercheckers/searchtemplate
+
makercheckers/searchtemplate?fields=entityNames
+
+
+ +GET https://DomainName/api/v1/audits/searchtemplate + + +{ + "appUsers": [ + { + "id": 30, + "username": "user 1" + }, + { + "id": 28, + "username": "user 2" + }, + { + "id": 35, + "username": "user 3" + },... + ], + "actionNames": [ + "CREATE", + "DELETE", + "UPDATE", + "ACTIVATE", + "ADJUST", + "APPROVALUNDO", + "APPROVE",... + ], + "entityNames": [ + "CALENDAR", + "CENTER", + "CHARGE", + "CLIENT", + "CLIENTIDENTIFIER",... + ] +} + +
+
+ +   +
+
+

Approve Maker Checker Entry

+
+
+ +POST https://DomainName/api/v1/makercheckers/{auditId}?command=approve + + +POST makercheckers/1?command=approve +Content-Type: application/json + + { "auditId": 1 } +
+
+   +
+
+

Reject Maker Checker Entry

+
+
+ +POST https://DomainName/api/v1/makercheckers/{auditId}?command=reject + + +POST makercheckers/1?command=reject +Content-Type: application/json + + { "auditId": 1 } +
+
+ +   +
+
+

Delete Maker Checker Entry

+
+
+ +DELETE https://DomainName/api/v1/makercheckers/{auditId} + + +DELETE makercheckers/1 +Content-Type: application/json + + { "auditId": 1 } +
+
+ + +   +
+
+

MIFOSX-BATCH JOBS

+

Batch jobs (also known as cron jobs on Unix-based systems) are a series of back-end jobs executed on a computer at a particular time defined in job's cron expression. +

+ +

At any point, you can view the list of batch jobs scheduled to run along with other details specific to each job. Manually you can execute the jobs at any point of time. +

+

The scheduler status can be either "Active" or "Standby". If the scheduler status is Active, it indicates that all batch jobs are running/ will run as per the specified schedule.If the scheduler status is Standby, it will ensure all scheduled batch runs are suspended. +

+
+
+ +   +
+
+

Retrieve Scheduler Jobs

+

Returns the list of jobs.

+

Example Requests:

+
jobs
+
+
+ +GET https://DomainName/api/v1/jobs + + +[ + { + "jobId": 1, + "displayName": "Update loan Summary", + "cronExpression": "0 0 22 1/1 * ? *", + "active": false, + "currentlyRunning": false, + "lastRunHistory": { + "version": 17, + "jobRunStartTime": "Jul 26, 2013 1:38:26 PM", + "jobRunEndTime": "Jul 26, 2013 1:38:26 PM", + "status": "success", + "triggerType": "application" + } + }, + { + "jobId": 2, + "displayName": "Update Loan Arrears Ageing", + "nextRunTime": "Jul 27, 2013 12:01:00 AM", + "cronExpression": "0 1 0 1/1 * ? *", + "active": true, + "currentlyRunning": false, + "lastRunHistory": { + "version": 18, + "jobRunStartTime": "Jul 26, 2013 4:05:32 PM", + "jobRunEndTime": "Jul 26, 2013 4:05:32 PM", + "status": "success", + "triggerType": "application" + } + }, + { + "jobId": 3, + "displayName": "Update Loan Paid In Advance", + "nextRunTime": "Jul 27, 2013 12:05:00 AM", + "cronExpression": "0 5 0 1/1 * ? *", + "active": true, + "currentlyRunning": false, + "lastRunHistory": { + "version": 16, + "jobRunStartTime": "Jul 26, 2013 4:15:47 PM", + "jobRunEndTime": "Jul 26, 2013 4:15:47 PM", + "status": "success", + "triggerType": "application" + } + }, + { + "jobId": 4, + "displayName": "Apply Annual Fee For Savings", + "nextRunTime": "Jul 26, 2013 10:20:00 PM", + "cronExpression": "0 20 22 1/1 * ? *", + "active": true, + "currentlyRunning": false, + "lastRunHistory": { + "version": 11, + "jobRunStartTime": "Jul 26, 2013 12:00:37 PM", + "jobRunEndTime": "Jul 26, 2013 12:00:38 PM", + "status": "success + "triggerType": "application" + } + }, + { + "jobId": 5, + "displayName": "Apply Holidays To Loans", + "nextRunTime": "Jul 27, 2013 12:00:00 PM", + "cronExpression": "0 0 12 * * ?", + "active": true, + "currentlyRunning": false, + "lastRunHistory": { + "version": 16, + "jobRunStartTime": "Jul 26, 2013 4:31:54 PM", + "jobRunEndTime": "Jul 26, 2013 4:31:55 PM", + "status": "success", + "triggerType": "application" + } + } +] + + +
+
+ +   +
+
+

Retrieve a Job

+

Returns the details of a Job.

+

Example Requests:

+
jobs/5
+
+
+ +GET https://DomainName/api/v1/jobs/{jobId} + + +https://localhost:8443/fineract-provider/api/v1/jobs/5 +{ + "jobId": 5, + "displayName": "Apply Holidays To Loans", + "nextRunTime": "Jul 27, 2013 12:00:00 PM", + "cronExpression": "0 0 12 * * ?", + "active": true, + "currentlyRunning": false, + "lastRunHistory": { + "version": 16, + "jobRunStartTime": "Jul 26, 2013 4:31:54 PM", + "jobRunEndTime": "Jul 26, 2013 4:31:55 PM", + "status": "success", + "triggerType": "application" + } +} + +
+
+ +   +
+
+

Update a Job

+

Updates the details of a job.

+
+
+ +PUT https://DomainName/api/v1/jobs/{jobId} + + +PUT jobs/1 +Content-Type: application/json +{ + "displayName":"Update loan Summary", + "cronExpression":"0 0 22 1/1 * ? *", + "active":"true" +} +
+
+ +   +
+
+

Run a Job

+

Manually Execute Specific Job.

+
+
+ +POST https://DomainName/api/v1/jobs/{jobId}?command=executeJob + + +POST jobs/1?command=executeJob + +
+
+ +   +
+
+

Retrieve Job Run History

+

Example Requests:

+
jobs/5/runhistory?offset=0&limit=200
+
+
+ +GET https://DomainName/api/v1/jobs/{jobid}/runhistory?offset=0&limit=200 + + +{ + "totalFilteredRecords": 8, + "pageItems": [ + { + "version": 1, + "jobRunStartTime": "Jul 16, 2013 12:00:00 PM", + "jobRunEndTime": "Jul 16, 2013 12:00:00 PM", + "status": "success", + "triggerType": "cron" + }, + { + "version": 2, + "jobRunStartTime": "Jul 17, 2013 12:00:00 PM", + "jobRunEndTime": "Jul 17, 2013 12:00:00 PM", + "status": "success", + "triggerType": "cron" + }, + { + "version": 3, + "jobRunStartTime": "Jul 18, 2013 12:00:00 PM", + "jobRunEndTime": "Jul 18, 2013 12:00:01 PM", + "status": "success", + "triggerType": "cron" + }, + { + "version": 4, + "jobRunStartTime": "Jul 19, 2013 12:00:00 PM", + "jobRunEndTime": "Jul 19, 2013 12:00:00 PM", + "status": "success", + "triggerType": "cron" + }, + { + "version": 5, + "jobRunStartTime": "Jul 20, 2013 11:16:07 AM", + "jobRunEndTime": "Jul 20, 2013 11:16:07 AM", + "status": "success", + "triggerType": "application" + }, + { + "version": 6, + "jobRunStartTime": "Jul 20, 2013 11:35:05 AM", + "jobRunEndTime": "Jul 20, 2013 11:35:05 AM", + "status": "success", + "triggerType": "application" + }, + { + "version": 7, + "jobRunStartTime": "Jul 20, 2013 12:00:00 PM", + "jobRunEndTime": "Jul 20, 2013 12:00:00 PM", + "status": "success", + "triggerType": "cron" + }, + { + "version": 8, + "jobRunStartTime": "Jul 22, 2013 12:00:00 PM", + "jobRunEndTime": "Jul 22, 2013 12:00:00 PM", + "status": "success", + "triggerType": "cron" + } + ] +} + +
+
+ +   +
+
+

Retrieve Scheduler Status

+

Returns the scheduler status.

+

Example Requests:

+
scheduler
+
+
+ +GET https://DomainName/api/v1/scheduler + + +https://localhost:8443/fineract-provider/api/v1/scheduler +{ + "active": true +} + +
+
+ +   +
+
+

Activate Scheduler Jobs

+

Activates the scheduler job service.

+
+
+ +POST https://DomainName/api/v1/scheduler?command=start + + +POST scheduler?command=start + +
+
+ +   +
+
+

Suspend Scheduler Jobs

+

Suspends the scheduler job service.

+
+
+ +POST https://DomainName/api/v1/scheduler?command=stop + + +POST scheduler?command=stop + +
+
+ +   +
+
+

External Services

+

External Services Configuration related to set of supported configurations for third party services like Amazon S3 and SMTP:

+
    +
  1. S3 (Amazon S3):
  2. +
  3. s3_access_key -
  4. +
  5. s3_bucket_name -
  6. +
  7. s3_secret_key -
  8. +

    +
  9. SMTP (Email Service):
  10. +
  11. username -
  12. +
  13. password -
  14. +
  15. host -
  16. +
  17. port -
  18. +
  19. useTLS -
  20. + +
+
+
+ +   +
+
+

Retrieve External Services Configuration

+

Returns a external Service configurations based on the Service Name.

+

Service Names supported are S3 and SMTP.

+

Example Requests:

+
externalservice/SMTP
+
+
+ +GET https://DomainName/api/v1/externalservice/{serviceName} + + + + + [ + { + "name": "username", + "value": "test@mifos.com" + }, + { + "name": "password", + "value": "XXXX" + }, + { + "name": "host", + "value": "smtp.gmail.com" + }, + { + "name": "port", + "value": "25" + }, + { + "name": "useTLS", + "value": "true" + } + ] + + + +
+
+ +   +
+
+

Update External Service

+

Updates the external Service Configuration for a Service Name.

+
+
+ +PUT https://DomainName/api/v1/externalservice/{serviceName} + + +PUT externalservice/S3 +Content-Type: application/json +{ + "username" : "test@mifos.org" + "password" : "XXXX" +} + +
+
+ + +   +
+
+

Funds

+
+
+ +   +
+
+

Create a Fund

+

Creates a fund.

+
+
+ +POST https://DomainName/api/v1/funds + + +POST funds +Content-Type: application/json +Request Body: +{ + "name": "EU Agri Fund" +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve Funds

+

Returns the list of funds.

+

Example Requests:

+
funds
+
+
+ +GET https://DomainName/api/v1/funds + + +[ + { + "id": 1, + "name": "EU Agri Fund" + } +] + +
+
+ +   +
+
+

Retrieve a Fund

+

Returns the details of a Fund.

+

Example Requests:

+
funds/1
+
+
+ +GET https://DomainName/api/v1/funds/{fundId} + + +{ + "id": 1, + "name": "EU Agri Fund" +} + +
+
+ +   +
+
+

Update a Fund

+

Updates the details of a fund.

+
+
+ +PUT https://DomainName/api/v1/funds/{fundId} + + +PUT funds/1 +Content-Type: application/json +Request Body: +{ + "name": "EU Agri Fund (2010-2020)" +} + + +{ + "resourceId": 1, + "changes": { + "name": "EU Agri Fund (2010-2020)" + } +} + +
+
+ + +   +
+
+

Staff

+

Allows you to model staff members. At present the key role + of significance is whether this staff member is a loan officer or + not.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
firstname
First Name of the new Employee.
lastname
Last Name of the new Employee. +
externalId
ID to put an external reference for an Employee.
mobileNo
Mobile number of an Employee. +
isLoanOfficer
Indicates whether the employee account is to be created as Loan Officer. If isLoanOfficer=true, then the employee is Loan Officer. If isLoanOfficer=false, then the employee is + not Loan Officer. +
isActive
Indicates whether the employee account is to be created as Active. If isActive=true, then employee is active. If isActive=false, then employee is inactive.
+
+
+ + +   +
+
+

Create a staff member

+

Creates a staff member.

+ + + + + + + +
Mandatory Fields
officeId, firstname, lastname
+
+ + + + + + + +
Optional Fields
isLoanOfficer, isActive
+
+
+ +POST https://DomainName/api/v1/staff + + +POST staff +Content-Type: application/json +Request Body: +{ + "officeId": 1, + "firstname": "John", + "lastname": "Doe", + "isLoanOfficer": "true", + "externalId": "17H", + "mobileNo": "+353851239876", + "isActive": "true", + "joiningDate": "01 January 2009", + "locale":"en", + "dateFormat":"dd MMMM yyyy" +} + + +{ + "officeId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve Staff

+

Returns the list of staff members.

+

Example Requests:

+
staff
+
+
+ +GET https://DomainName/api/v1/staff + + +[ + { + "id": 1, + "firstname": "John", + "lastname": "Doe", + "displayName": "Doe, John", + "officeId": 1, + "officeName": "Head Office", + "isLoanOfficer": true, + "externalId": "17H", + "isActive": "true", + "joiningDate":[2009,8,1] + } +] + +
+
+ +   +
+
+

Retrieve a Staff Member

+

Returns the details of a Staff Member.

+

Example Requests:

+
staff/1
+
+
+ GET https://DomainName/api/v1/staff/{staffId} + +{ + "id": 1, + "firstname": "John", + "lastname": "Doe", + "displayName": "Doe, John", + "officeId": 1, + "officeName": "Head Office", + "isLoanOfficer": true, + "externalId": "17H", + "isActive": "true", + "joiningDate":[2009,8,1] +} + +
+
+ +   +
+
+

Retrieve a Staff by status

+

Returns the details of a Staff based on status.

+

By default it Returns all the ACTIVE Staff.

+

If status=INACTIVE, then it returns all INACTIVE Staff.

+

and for status=ALL, it Returns both ACTIVE and INACTIVE Staff.

+

Example Requests:

+
staff?status=active
+
+
+ GET https://DomainName/api/v1/staff?status={ACTIVE|INACTIVE|ALL} + +{ + "id": 1, + "firstname": "John", + "lastname": "Doe", + "displayName": "Doe, John", + "officeId": 1, + "officeName": "Head Office", + "isLoanOfficer": true, + "externalId": "17H", + "isActive": "true", + "joiningDate":[2009,8,1] +} + +
+
+ +   +
+
+

Update a Staff Member

+

Updates the details of a staff member.

+
+
+ +PUT https://DomainName/api/v1/staff/{staffId} + + +PUT staff/1 +Content-Type: application/json +Request Body: +{ + "isLoanOfficer": "false", + "externalId": "17Hbb" +} + + +{ + "officeId": 1, + "resourceId": 1, + "changes": { + "isLoanOfficer": false, + "externalId": "17Hbb" + } +} + +
+
+ + + +  +
+
+

Charges

+

+ Its typical for MFIs to add extra costs for their financial + products. These are typically Fees or Penalties. +

+

A Charge on fineract platform is what we use to model both Fees and Penalties.

+

At present we support defining charges for use with Client accounts and both loan and saving products.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name associated with this charge.
chargeAppliesTo
Enumeration for indicating whether charge is to be applicable for loans, savings or clients.
+ 1=Loans, + 2=Savings, + 3=Client +

Once a charge definiton has been created, this attribute cannot be changed at any point.

+
active
Boolean flag determines if the charge is currently active.
penalty
Boolean flag determines if the charge is a penalty. If false the charge is considered a Fee
currencyCode
A three letter ISO code of currency.
chargeCalculationType
Enumeration for indicating whether charge amount is flat or percentage based:
+ 1=Flat, + 2=% of Amount +

Used in combination with amount parameter e.g 1 % of Amount or 3.50 Flat

+

For loans, % of Amount refers to the loan principal disbursed.

+

For savings, % of Amount can be used with 'withrawal fees' and refers to the amount withdrawn.

+
amount
The charge amount. Used in combination with chargeCalculationType parameter. e.g 1 % of Amount or 3.50 Flat
minCap
Optional: Can be used when a '% of Amount' value is used for chargeCalculationType. +

Used to enforce a minimum charge amount in cases where the calculated amount is less than the minimum amount provided.

+

e.g. A 2% fee with a minimum cap of 500:
+ In case of a 5000 loan, the 2% is 100, and therefore automatically 500 is used as the value of the charge. +

+
maxCap
Optional: Can be used when a '% of Amount' value is used for chargeCalculationType. +

Used to enforce a maximum charge amount in cases where the calculated amount is greater than the maximum amount provided.

+

e.g. A 2% fee, with a maximum of 2000.:
+ In case of a 150000 loan, the 2% adds up to 3000 charge, and therefore the maximum cap of 2000 will be used. +

+
chargeTimeType
An enumeration indicating the time at which the charge becomes due:
+

+ 1 = Disbursement : Applicable for loans and deducted at the time of loan disbursement.
+ 2 = Specified Due Date : Adhoc charge can be applied for loans and savings on a specified due date.
+ 3 = Savings Activation : This charge is applicable for savings account and charged at the time of account activation. This charge will be autodeducted once the account is activated with sufficient opening balance.
+ 5 = Withdrawal fee : Charge applied to every withdrawal of savings account.
+ 6 = Annual Fee : Recurring charge applied annually for savings on a specified Month and day. see feeOnMonthDay
+ 7 = Monthly Fee : Recurring charge applied on regular interval of months for savings. see feeOnMonthDay and feeInterval +

+
chargePaymentMode
Applicable to loan charges only: Enumeration for indicating whether charge is to be paid through an Account Transfer from savings or through Regular payment mode.
+ 0=Regular, + 1=Account Transfer +
feeOnMonthDay
Used along with monthDayFormat to indicate the recurring charge due date starting on a given day of the month and follow specified feeInterval. e.g. fee due date starting on 10 May with feeInterval of two (2) months then a recurring fee on 10th of every two months is applied to savings account. monthDayFormat indicates day and month formatting used e.g. "dd MMM" for 10 May
+ This field is mandatory if chargeTimeType is of type Monthly Fee +
feeInterval
Fee to be applied on a specified interval.
+ This field is mandatory if chargeTimeType is of type Monthly Fee or feeFrequency is selcted +
feeFrequency
This field is Optional Used to indicate the recurring(days,weeks,months and Years) charge due date starting on system calculated date for overdue penalty.
incomeAccount
This field is Optional and can be used only when a charge is applied to a Client. It indicates the Income or Liability account which gets + credited when a payment is made on this charge
+
+
+ +   +
+
+

Retrieve Charge Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
charges/template
+
+
+ +GET https://DomainName/api/v1/charges/template + + +{ + "active": false, + "penalty": false, + "currencyOptions": [ + { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + ], + "chargeCalculationTypeOptions": [ + { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + }, + { + "id": 3, + "code": "chargeCalculationType.percent.of.amount.and.interest", + "value": "% Loan Amount + Interest" + }, + { + "id": 4, + "code": "chargeCalculationType.percent.of.interest", + "value": "% Interest" + } + ], + "chargeAppliesToOptions": [ + { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + } + ], + "chargeTimeTypeOptions": [ + { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + { + "id": 3, + "code": "chargeTimeType.savingsActivation", + "value": "Savings Activation" + }, + { + "id": 5, + "code": "chargeTimeType.withdrawalFee", + "value": "Withdrawal Fee" + }, + { + "id": 6, + "code": "chargeTimeType.annualFee", + "value": "Annual Fee" + }, + { + "id": 7, + "code": "chargeTimeType.monthlyFee", + "value": "Monthly Fee" + }, + { + "id": 8, + "code": "chargeTimeType.instalmentFee", + "value": "Instalment Fee" + }, + { + "id": 9, + "code": "chargeTimeType.overdueInstallment", + "value": "overdue fees" + }, + { + "id": 10, + "code": "chargeTimeType.overdraftFee", + "value": "Overdraft Fee" + } + ], + "chargePaymetModeOptions": [ + { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + }, + { + "id": 1, + "code": "chargepaymentmode.accounttransfer", + "value": "Account transfer" + } + ], + "loanChargeCalculationTypeOptions": [ + { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + }, + { + "id": 3, + "code": "chargeCalculationType.percent.of.amount.and.interest", + "value": "% Loan Amount + Interest" + }, + { + "id": 4, + "code": "chargeCalculationType.percent.of.interest", + "value": "% Interest" + } + ], + "loanChargeTimeTypeOptions": [ + { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + { + "id": 8, + "code": "chargeTimeType.instalmentFee", + "value": "Instalment Fee" + }, + { + "id": 9, + "code": "chargeTimeType.overdueInstallment", + "value": "overdue fees" + } + ], + "savingsChargeCalculationTypeOptions": [ + { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + } + ], + "savingsChargeTimeTypeOptions": [ + { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + { + "id": 3, + "code": "chargeTimeType.savingsActivation", + "value": "Savings Activation" + }, + { + "id": 5, + "code": "chargeTimeType.withdrawalFee", + "value": "Withdrawal Fee" + }, + { + "id": 6, + "code": "chargeTimeType.annualFee", + "value": "Annual Fee" + }, + { + "id": 7, + "code": "chargeTimeType.monthlyFee", + "value": "Monthly Fee" + }, + { + "id": 10, + "code": "chargeTimeType.overdraftFee", + "value": "Overdraft Fee" + } + ], + "feeFrequencyOptions": [ + { + "id": 0, + "code": "loanTermFrequency.periodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "loanTermFrequency.periodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "loanTermFrequency.periodFrequencyType.months", + "value": "Months" + }, + { + "id": 3, + "code": "loanTermFrequency.periodFrequencyType.years", + "value": "Years" + } + ] +} + +
+
+ +   +
+
+

Create/Define a Charge

+

Define a new charge that can later be associated with loans and savings through their respective product definitions or directly on each account instance.

+
+
+ +POST https://DomainName/api/v1/charges + + +POST charges +Content-Type: application/json +Request Body: +{ +"name": "Loan service fee", +"chargeAppliesTo": 1, +"currencyCode": "USD", +"locale": "en", +"amount": "230.56", +"chargeTimeType": "1", +"chargeCalculationType": "1", +"chargePaymentMode": "1", +"active": true +} + + +{ +"resourceId": 1 +} + + +POST charges +Content-Type: application/json +Request Body: +{ +"locale": "en", +"name": "Default Penalty", +"amount": "2", +"currencyCode": "USD", +"chargeAppliesTo": "1", +"chargeTimeType": "2", +"chargeCalculationType": "2", +"chargePaymentMode": "1", +"active": "true", +"penalty": "true", +"minCap": 50.00, +"maxCap": 100.00 +} + + +{ +"resourceId": 4 +} + + + +POST charges +Content-Type: application/json +Request Body: +{ +"locale": "en", +"name": "Annuaul Fee", +"amount": "20", +"currencyCode": "USD", +"chargeAppliesTo": "2", +"chargeTimeType": "6", +"chargeCalculationType": "1", +"chargePaymentMode": "1", +"active": "true", +"penalty": "false" +} + + +{ +"resourceId": 5 +} + + +POST charges +Content-Type: application/json +Request Body: +{ +"locale": "en", +"name": "Quarterly Fee", +"amount": "5", +"currencyCode": "USD", +"chargeAppliesTo": "2", +"chargeTimeType": "7", +"feeOnMonthDay": "10 May", +"monthDayFormat": "dd MMM", +"feeInterval": "4", +"chargeCalculationType": "1", +"active": "true", +"penalty": "false" +} + + +{ +"resourceId": 6 +} + + +POST charges +Content-Type: application/json +Request Body: +{ + "chargeAppliesTo":1, + "feeFrequency":1, + "feeInterval":"2", + "name":"overdue charge", + "currencyCode":"USD", + "chargeTimeType":9, + "chargeCalculationType":1, + "chargePaymentMode":0, + "amount":"50", + "active":true, + "penalty":"true", + "locale":"en", + "monthDayFormat":"dd MMM" +} + + +{ +"resourceId": 7 +} + + +POST charges +Content-Type: application/json +Request Body: +{ + "chargeAppliesTo": 2, + "name": "Weekly Fee", + "currencyCode": "USD", + "chargeTimeType": 11, + "chargeCalculationType": 1, + "feeInterval": "1", + "amount": "10", + "active": true, + "locale": "en" +} + + +{ + "resourceId": 8 +} + +
+
+ +   +
+
+

Retrieve Charges

+

Returns the list of defined charges.

+

Example Requests:

+
charges
+
+
+ +GET https://DomainName/api/v1/charges + + +[ + { + "id": 1, + "name": "Loan service fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 230.56, + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode":{ + "id":1, + "code":"chargepaymentmode.accounttransfer", + "value":"Account transfer" + } + }, + { + "id": 54, + "chargeId": 12, + "name": "Loan service fee 2", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeCalculationType": { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + }, + "percentage": 2.000000, + "amountPercentageAppliedTo": 14000.000000, + "currency": { + "code": "KES", + "name": "Kenyan Shilling", + "decimalPlaces": 2, + "displaySymbol": "KSh", + "nameCode": "currency.KES", + "displayLabel": "Kenyan Shilling (KSh)" + }, + "amount": 500.000000, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 500.000000, + "amountOrPercentage": 2.000000, + "penalty": false, + "chargePaymentMode": { + "id": 1, + "code": "chargepaymentmode.accounttransfer", + "value": "Account transfer" + }, + "paid": false, + "waived": false, + "chargePayable": true, + "minCap": 500.000000, + "maxCap": 1000.000000 + }, +] + +
+
+ +   +
+
+

Retrieve a Charge

+

Returns the details of a defined Charge.

+

Example Requests:

+
charges/1
+
+
+ +GET https://DomainName/api/v1/charges/{chargeId} + + +{ + "id": 1, + "name": "Loan service fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 230.56, + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode":{ + "id":1, + "code":"chargepaymentmode.accounttransfer", + "value":"Account transfer" + } +} + +
+
+ +   +
+
+

Update a Charge

+

Updates the details of a Charge.

+
+
+ +PUT https://DomainName/api/v1/charges/{chargeId} + + +PUT charges/1 +Content-Type: application/json +Request Body: +{ + "name": "Loan service fee(changed)" +} + + +{ + "resourceId": 1, + "changes": { + "name": "Loan service fee(changed)" + } +} + +
+
+ +   +
+
+

Delete a Charge

+

Deletes a Charge.

+
+
+ +DELETE https://DomainName/api/v1/charges/{chargeId} + + +DELETE charges/1 +Content-Type: application/json + + { "resourceId": 1 } +
+
+ + +   +
+
+

Accounting Rules

+

+ It is typical scenario in MFI's that non accountants pass journal entries on a regular basis. + For Ex: A branch office might deposit their entire cash at hand to their Bank account at the end of a + working day. The branch office users might not understand enough of accounting to figure out which + account needs to get credited and which account needs to be debited to represent this transaction. +

+

Enter accounting rules, an abstraction on top of manual Journal entires for enabling + simpler data entry. + An accounting rule can define any of the following abstractions +

    +
  • A Simple journal entry where both the credit and debit account have been preselected
  • +
  • A Simple journal entry where either credit or debit accounts have been limited to a + pre-selected list of accounts (Ex: Debit account should be one of "Bank of America" of "JP Morgan" + and credit account should be "Cash") +
  • +
  • A Compound journal entry where multiple debits and / or multiple credits may be made + amongst a set of preselected list of accounts (Ex: Credit account should be either "Bank Of America" + or "Cash" and debit account can be "Employee Salary" and/or "Miscellenous Expenses") +
  • +
+ +

+ +

An accounting rule can also be optionally associated with a branch, so that only a particular Branch's + users have access to the rule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name of the accounting rule
description
A description of the accounting rule.
officeId
An Optional Office for this accounting rule is applicable.
accountToDebit
ID of the target account to be Debited
accountToCredit
ID of the target account to be Credited
debitTags
A list of accounting Tags. Any Ledger account with this tag can serve as the + account to be debited.
This parameter is optional, if accountToDebit present in the request params
creditTags
A list of accounting Tags. Any Ledger account with this tag can serve as the + account to be credited.
This parameter is optional, if accountToCredit present in the request params
allowMultipleDebitEntries
Allows passing multiple debit entries for the accounting rule
allowMultipleCreditEntries
Allows passing multiple credit entries for the accounting rule
paymentTypeId
Allows passing multiple credit entries for the accounting rule
+
+
+ +   +
+
+

Retrieve Accounting Rule Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
accountingrules/template
+
+
+ +GET https://DomainName/api/v1/accountingrules/template + + +{ + "systemDefined": false, + "allowedOffices": [{ + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + }], + "allowedAccounts": [{ + "id": 21, + "name": "Cash 2", + "parentId": 18, + "glCode": "20011", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "description": "Cash", + "nameDecorated": "............Cash 2", + "tagId": { + "id": 10, + "name": "asset tag" + } + }, + { + "id": 9, + "name": "Employee Salary", + "parentId": 8, + "glCode": "456674", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 5, + "code": "accountType.expense", + "value": "EXPENSE" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "Employee Salary", + "tagId": { + "id": 14, + "name": "Expenses Tag" + } + }] +} + +
+
+ +   +
+
+

Create/Define a Accounting rule

+

Define a new Accounting rule.

+ + + + + + + +
Mandatory Fields
name, officeId,
accountToDebit OR debitTags,
accountToCredit OR creditTags.
+
+
+ + + + + + + +
Optional Fields
description
+
+
+ +POST https://DomainName/api/v1/accountingrules + + +POST accountingrules +Content-Type: application/json +Request Body: +{ + "name": "test", + "officeId": "1", + "accountToDebit": "21", + "accountToCredit": "9", + "description": "Employee salary" +} + + +{ + "officeId":1, + "resourceId":1 +} + + +POST accountingrules +Content-Type: application/json +Request Body: +{ + "name": "fordocs", + "officeId": "1", + "debitTags": ["10","11"], + "allowMultipleDebitEntries": "true", + "creditTags": ["12","13"], + "allowMultipleCreditEntries": "true", + "description": "for api docs" +} + + +{ + "officeId":1, + "resourceId":2 +} + + +POST accountingrules +Content-Type: application/json +Request Body: +{ + "name": "test123", + "officeId": "1", + "accountToDebit": "21", + "creditTags": ["12", "13"], + "allowMultipleCreditEntries": "false", + "description": "Employee salary" +} + + +{ + "officeId":1, + "resourceId":3 +} + + +POST accountingrules +Content-Type: application/json +Request Body: +{ + "name": "fordocstest", + "officeId": "1", + "debitTags": ["10","11"], + "allowMultipleDebitEntries": "false", + "accountToCredit": "9", + "description": "for api docs" +} + + +{ + "officeId":1, + "resourceId":4 +} + +
+
+ +   +
+
+

Retrieve Accounting Rules

+

Returns the list of defined accounting rules.

+

Example Requests:

+
accountingrules
+
+
+ +GET https://DomainName/api/v1/accountingrules + + +[{ + "id": 1, + "officeId": 1, + "officeName": "Head Office", + "name": "test", + "description": "Employee salary", + "systemDefined": false, + "debitAccountHead": { + "id": 21, + "name": "Cash 2", + "glCode": "20011", + "disabled": false, + "manualEntriesAllowed": false + }, + "creditAccountHead": { + "id": 9, + "name": "Employee Salary", + "glCode": "456674", + "disabled": false, + "manualEntriesAllowed": false + } +}, +{ + "id": 2, + "officeId": 1, + "officeName": "Head Office", + "name": "A L1", + "description": "aafff", + "systemDefined": false, + "debitAccountHead": { + "id": 3, + "name": "A L", + "glCode": "10003", + "disabled": false, + "manualEntriesAllowed": false + }, + "creditAccountHead": { + "id": 4, + "name": "car loan", + "glCode": "10004", + "disabled": false, + "manualEntriesAllowed": false + } +}] + +
+
+ +   +
+
+

Retrieve a Accounting rule

+

Returns the details of a defined Accounting rule.

+

Example Requests:

+
accountingrules/1
+
+
+ +GET https://DomainName/api/v1/accountingrules/{accountingruleId} + + +{ + "id": 1, + "officeId": 1, + "officeName": "Head Office", + "name": "test", + "description": "Employee salary", + "systemDefined": false, + "debitAccountHead": { + "id": 21, + "name": "Cash 2", + "glCode": "20011", + "disabled": false, + "manualEntriesAllowed": false + }, + "creditAccountHead": { + "id": 9, + "name": "Employee Salary", + "glCode": "456674", + "disabled": false, + "manualEntriesAllowed": false + } +} + +
+
+ +   +
+
+

Update a Accounting Rule

+

Updates the details of a Accounting rule.

+
+
+ +PUT https://DomainName/api/v1/accountingrules/{accountingruleId} + + +PUT accountingrules/1 +Content-Type: application/json +Request Body: +{ + "name": "Employee Salary posting rule" +} + + +{ + "resourceId": 1, + "changes": { + "name": "Employee Salary posting rule" + } +} + +
+
+ +   +
+
+

Delete a Accounting Rule

+

Deletes a Accounting rule.

+
+
+ +DELETE https://DomainName/api/v1/accountingrules/{accountingruleId} + + +DELETE accountingrules/1 +Content-Type: application/json + + { "resourceId": 1 } +
+
+ + +   +
+
+

Savings Product:

+

An MFIs savings product offerings are modeled using this API.

+

When creating savings accounts, the details from the savings product are used to auto fill details of the savings account application process.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
The name of the product offering.
shortName
Shortname associated with a saving product.
+ An abbreviated version of the name, used in reports or menus where space is limited. +
description
A description of the product offering.
currencyCode
Three letter ISO code representing currency.
digitsAfterDecimal
Override the currency default value for digitsAfterDecimal.
inMultiplesOf
Override the default value for rounding currency to multiples of provided value.
nominalAnnualInterestRate
The default interest rate set when creating savings accounts of this type of product. e.g. 5% Per year - It number here is always expressed as the Nominal APR.
interestCompoundingPeriodType
The period at which interest rate is compounded. 1=Daily, 4=Monthly (at end of month)
interestPostingPeriodType
The period at which interest rate is posted or credited to savings account. 4=Monthly (at end of month), 5=Quarterly (at end of quarter, 31st Mar, 30th Jun, 30th Sep, 31st Dec)
interestCalculationType
The interest calculation method used: 1=Daily Balance or 2=Average Daily Balance
interestCalculationDaysInYearType
The setting for number of days in year to use: 360=360 Days, 365=365 Days
minRequiredOpeningBalance
Optional: If provided, sets the minimum deposit amount required to open a savings account e.g. 2,000
lockinPeriodFrequency
Optional: If provided, used along with lockinPeriodFrequencyType to indicate the length of time that the savings account is 'locked in' and withdrawals are not allowed. e.g. 6 Months
lockinPeriodFrequencyType
Optional: If provided, used along with lockinPeriodFrequency to indicate the length of time that the savings account is 'locked in' and withdrawals are not allowed. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months
withdrawalFeeForTransfers
Optional: Used along with withdrawalFeeAmount to indicate whether the withdrawal fee should be applied on the account for account transfers .
accountingRule
Specifies if accounting is enabled for the particular + product and the type of the accounting rule to be used + Example Values:1=NONE,2=CASH_BASED
allowOverdraft
Optional: If provided, depending on the value mark the savings account as overdraft account
overdraftLimit
Optional: If provided, sets the maximum allowed overdraft amount for a savings account e.g. 5,000 else set the limit as zero
minBalanceForInterestCalculation
Optional: If provided, balance must be greater than provided value for calculation of interest e.g. 5,000
enforceMinRequiredBalance
Optional: If set to true, validates that the account balance does not + fall below minRequiredBalance
minRequiredBalance
Optional: If provided, sets an indicator of the minimum required balance of the savings account e.g. 5,000 else set the limit as zero. Note that enforceMinRequiredBalance determines if the minimum required balance is enforced
+
+
+ +   +
+
+

Retrieve Savings Product Template

+

This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
savingsproducts/template
+
+
+ GET https://Domain Name/api/v1/savingsproducts/template + +{ + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsInterestPostingPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "accountingRule": { + "id": 1, + "code": "accountingRuleType.none", + "value": "NONE" + }, + "currencyOptions": [ + { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + ], + "interestCompoundingPeriodTypeOptions": [ + { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + { + "id": 2, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.weekly", + "value": "Weekly" + }, + { + "id": 3, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.biweekly", + "value": "Bi-Weekly" + }, + { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + }, + { + "id": 5, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.quarterly", + "value": "Quarterly" + }, + { + "id": 6, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.biannual", + "value": "Semi-Annual" + }, + { + "id": 7, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.annual", + "value": "Annually" + }, + { + "id": 8, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.nocompounding", + "value": "No Compounding - Simple Interest" + } + ], + "interestPostingPeriodTypeOptions": [ + { + "id": 4, + "code": "savings.interest.posting.period.savingsInterestPostingPeriodType.monthly", + "value": "Monthly" + }, + { + "id": 5, + "code": "savings.interest.posting.period.savingsInterestPostingPeriodType.quarterly", + "value": "Quarterly" + }, + { + "id": 6, + "code": "savings.interest.posting.period.savingsInterestPostingPeriodType.biannual", + "value": "Semi-Annual" + }, + { + "id": 7, + "code": "savings.interest.posting.period.savingsInterestPostingPeriodType.annual", + "value": "Annually" + } + ], + "interestCalculationTypeOptions": [ + { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + { + "id": 2, + "code": "savingsInterestCalculationType.averagedailybalance", + "value": "Average Daily Balance" + } + ], + "interestCalculationDaysInYearTypeOptions": [ + { + "id": 360, + "code": "savingsInterestCalculationDaysInYearType.days360", + "value": "360 Days" + }, + { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + } + ], + "lockinPeriodFrequencyTypeOptions": [ + { + "id": 0, + "code": "savings.lockin.savingsPeriodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "savings.lockin.savingsPeriodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "savings.lockin.savingsPeriodFrequencyType.months", + "value": "Months" + }, + { + "id": 3, + "code": "savings.lockin.savingsPeriodFrequencyType.years", + "value": "Years" + } + ], + "withdrawalFeeTypeOptions": [ + { + "id": 1, + "code": "savingsWithdrawalFeesType.flat", + "value": "Flat" + }, + { + "id": 2, + "code": "savingsWithdrawalFeesType.percent.of.amount", + "value": "% of Amount" + } + ], + "paymentTypeOptions": [ + { + "id": 14, + "name": "Wire Transfer", + "position": 0 + }, + { + "id": 13, + "name": "Cash", + "position": 1 + } + ], + "accountingRuleOptions": [ + { + "id": 1, + "code": "accountingRuleType.none", + "value": "NONE" + }, + { + "id": 2, + "code": "accountingRuleType.cash", + "value": "CASH BASED" + }, + { + "id": 3, + "code": "accountingRuleType.accrual", + "value": "ACCRUAL BASED" + } + ], + "accountingMappingOptions": { + "liabilityAccountOptions": [ + { + "id": 15, + "name": "Savings Control", + "glCode": "50001", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 2, + "code": "accountType.liability", + "value": "LIABILITY" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "Savings Control", + "tagId": { + "id": 0 + } + } + ], + "assetAccountOptions": [ + { + "id": 2, + "name": "Cash", + "glCode": "100001", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + }, + { + "id": 16, + "name": "Savings Reference", + "glCode": "100007", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "Savings Reference", + "tagId": { + "id": 0 + } + }, + { + "id": 12, + "name": "HDFC Rajajinagar", + "glCode": "100015", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + }, + { + "id": 1, + "name": "Loan Portfolio", + "glCode": "10003", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + }, + { + "id": 7, + "name": "Interest Receivable", + "glCode": "10005", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + }, + { + "id": 8, + "name": "Penalties Receivable", + "glCode": "10008", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + }, + { + "id": 9, + "name": "Fee Receivable", + "glCode": "10009", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + } + ], + "expenseAccountOptions": [ + { + "id": 6, + "name": "Write Off Expenses", + "glCode": "60001", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 5, + "code": "accountType.expense", + "value": "EXPENSE" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + }, + { + "id": 13, + "name": "Employee Salary", + "glCode": "60002", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 5, + "code": "accountType.expense", + "value": "EXPENSE" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + }, + { + "id": 18, + "name": "Interest On Savings", + "glCode": "60003", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 5, + "code": "accountType.expense", + "value": "EXPENSE" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "nameDecorated": "Interest On Savings", + "tagId": { + "id": 0 + } + } + ], + "incomeAccountOptions": [ + { + "id": 3, + "name": "Income from Interest", + "glCode": "40001", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 4, + "code": "accountType.income", + "value": "INCOME" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + }, + { + "id": 4, + "name": "Income from Fees", + "glCode": "40002", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 4, + "code": "accountType.income", + "value": "INCOME" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + }, + { + "id": 5, + "name": "Income from Penalties", + "glCode": "40004", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 4, + "code": "accountType.income", + "value": "INCOME" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "tagId": {} + } + ] + }, + "chargeOptions" : [ { "active" : true, + "amount" : 200, + "chargeAppliesTo" : { "code" : "chargeAppliesTo.savings", + "id" : 2, + "value" : "Savings" + }, + "chargeCalculationType" : { "code" : "chargeCalculationType.flat", + "id" : 1, + "value" : "Flat" + }, + "chargePaymentMode" : { "code" : "chargepaymentmode.regular", + "id" : 0, + "value" : "chargepaymentmode.regular" + }, + "chargeTimeType" : { "code" : "chargeTimeType.specifiedDueDate", + "id" : 2, + "value" : "Specified due date" + }, + "currency" : { "code" : "USD", + "decimalPlaces" : 2, + "displayLabel" : "US Dollar ($)", + "displaySymbol" : "$", + "name" : "US Dollar", + "nameCode" : "currency.USD" + }, + "id" : 4, + "name" : "Savings charge 1", + "penalty" : false + }, + { "active" : true, + "amount" : 300, + "chargeAppliesTo" : { "code" : "chargeAppliesTo.savings", + "id" : 2, + "value" : "Savings" + }, + "chargeCalculationType" : { "code" : "chargeCalculationType.flat", + "id" : 1, + "value" : "Flat" + }, + "chargePaymentMode" : { "code" : "chargepaymentmode.regular", + "id" : 0, + "value" : "chargepaymentmode.regular" + }, + "chargeTimeType" : { "code" : "chargeTimeType.specifiedDueDate", + "id" : 2, + "value" : "Specified due date" + }, + "currency" : { "code" : "USD", + "decimalPlaces" : 2, + "displayLabel" : "US Dollar ($)", + "displaySymbol" : "$", + "name" : "US Dollar", + "nameCode" : "currency.USD" + }, + "id" : 5, + "name" : "Savings charge 2", + "penalty" : false + } + ] +} + +
+
+ +   +
+
+

Create a Savings Product

+ + + + + +
Mandatory Fields
name, shortName, description, currencyCode, digitsAfterDecimal,inMultiplesOf, nominalAnnualInterestRate, + interestCompoundingPeriodType, interestCalculationType, interestCalculationDaysInYearType,accountingRule
+
+ + + + + +
Mandatory Fields for Cash based accounting (accountingRule = 2)
savingsReferenceAccountId, savingsControlAccountId, interestOnSavingsAccountId, incomeFromFeeAccountId, transfersInSuspenseAccountId, incomeFromPenaltyAccountId
+
+ + + +
Optional Fields
minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, charges, allowOverdraft, overdraftLimit, minBalanceForInterestCalculation
+
+
+ POST https://Domain Name/api/v1/savingsproducts + POST savingsproducts +Content-Type: application/json +Request Body: +{ + "name": "Passbook Savings", + "shortName": "PBSV", + "description": "Daily compounding using Daily Balance, 5% per year, 365 days in year", + "currencyCode": "USD", + "digitsAfterDecimal": 2, + "inMultiplesOf": 0, + "locale": "en", + "nominalAnnualInterestRate": "5.0", + "interestCompoundingPeriodType": 1, + "interestPostingPeriodType":4, + "interestCalculationType": 1, + "interestCalculationDaysInYearType": "365", + "accountingRule":"1", + "charges":[{"id":"1"}] +} + + +{ + "resourceId": 1 +} + + POST savingsproducts +Content-Type: application/json +Request Body: +{ + "locale": "en", + "name": "New Passbook Savings ", + "shortName": "NPBS", + "description": "A savings product", + "currencyCode": "USD", + "digitsAfterDecimal": "2", + "inMultiplesOf": 0, + "nominalAnnualInterestRate": "15", + "interestCompoundingPeriodType": "1", + "interestPostingPeriodType": "4", + "interestCalculationType": "1", + "interestCalculationDaysInYearType": "365", + "minRequiredOpeningBalance": "50", + "allowOverdraft":true, + "overdraftLimit":5000, + "minBalanceForInterestCalculation":5000, + "minRequiredBalance":20, + "enforceMinRequiredBalance":true, + "lockinPeriodFrequency": "4", + "lockinPeriodFrequencyType": "1", + "withdrawalFeeForTransfers":false, + "accountingRule": "2", + "charges":[{"id":"1"},{"id":3}] + "savingsReferenceAccountId": "16", + "transfersInSuspenseAccountId": "16", + "savingsControlAccountId": "15", + "interestOnSavingsAccountId": "18", + "incomeFromFeeAccountId": "4", + "incomeFromPenaltyAccountId": "4", + "feeToIncomeAccountMappings":[ + { + "chargeId":"6", + "incomeAccountId":"16" + } + ], + "penaltyToIncomeAccountMappings":[ + { + "chargeId":"4", + "incomeAccountId":"15" + } + ], + "paymentChannelToFundSourceMappings": [ + { + "paymentTypeId": "14", + "fundSourceAccountId": "2" + } + ] +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve a Savings Product

+

Example Requests:

+
savingsproducts/1
+

+
savingsproducts/1?template=true
+

+
savingsproducts/1?fields=name,description
+
+
+ GET https://Domain Name/api/v1/savingsproducts/1 + +{ + "id": 1, + "name": "savings product", + "shortName": "sa1", + "description": "gtasga", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "nominalAnnualInterestRate": 5.000000, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "withdrawalFeeForTransfers": false, + "accountingRule": { + "id": 2, + "code": "accountingRuleType.cash", + "value": "CASH BASED" + }, + "accountingMappings": { + "savingsReferenceAccount": { + "id": 12, + "name": "savings ref", + "glCode": "20" + }, + "incomeFromFeeAccount": { + "id": 16, + "name": "income from savings fee", + "glCode": "24" + }, + "incomeFromPenaltyAccount": { + "id": 17, + "name": "income from sav penalites", + "glCode": "25" + }, + "interestOnSavingsAccount": { + "id": 15, + "name": "interest on savings", + "glCode": "23" + }, + "savingsControlAccount": { + "id": 13, + "name": "savings ref tool kit", + "glCode": "21" + }, + "transfersInSuspenseAccount": { + "id": 14, + "name": "saving transfers", + "glCode": "22" + } + }, + "paymentChannelToFundSourceMappings": [ + { + "paymentType": { + "id": 10, + "name": "check" + }, + "fundSourceAccount": { + "id": 12, + "name": "savings ref", + "glCode": "20" + } + } + ], + "feeToIncomeAccountMappings": [ + { + "charge": { + "id": 11, + "name": "sav charge", + "active": false, + "penalty": false + }, + "incomeAccount": { + "id": 16, + "name": "income from savings fee", + "glCode": "24" + } + } + ], + "penaltyToIncomeAccountMappings": [ + { + "charge": { + "id": 12, + "name": "sav 2", + "active": false, + "penalty": true + }, + "incomeAccount": { + "id": 17, + "name": "income from sav penalites", + "glCode": "25" + } + } + ], + "charges": [] +} + +
+
+ +   +
+
+

Update a Savings Product

+
+
+ PUT https://Domain Name/api/v1/savingsproducts/{productId} + POST savingsproducts/1 +Content-Type: application/json +Request Body: +{ + "description": "Passbook Savings Lite.", + "locale": "en", + "interestRate": "5.73" +} + + +{ + "resourceId": 1, + "changes": { + "description": "Passbook Savings Lite.", + "interestRate": 5.73, + "locale": "en" + } +} + +
+
+ +   +
+
+

Delete a Savings Product

+
+
+ +DELETE https://Domain Name/api/v1/savingsproducts/{productId} + + +DELETE savingsproducts/1 +Content-Type: application/json + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

List Savings Products

+

Example Requests:

+
savingsproducts
+

+
savingsproducts?fields=name
+
+
+ GET https://Domain Name/api/v1/savingsproducts + +[ + { + "id": 1, + "name": "Savings product", + "shortName": "sa1", + "description": "gtasga", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "nominalAnnualInterestRate": 5.000000, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "withdrawalFeeForTransfers": false, + "accountingRule": { + "id": 2, + "code": "accountingRuleType.cash", + "value": "CASH BASED" + } + } +] +
+
+ + + +   +
+
+

Fixed Deposit Product:

+

This is one of the advanced term deposit product offered by MFI's. The Fixed Deposit Products (aka FD) product offerings are modeled using this API.

+

The FD products are deposit accounts which are held for a fixed term – like 1 year, 2 years etc.

+

When creating fixed deposit accounts, the details from the fixed deposit product are used to auto fill details of the fixed deposit account application process.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
The name of the product offering.
shortName
Shortname associated with a fixed deposit product.
+ An abbreviated version of the name, used in reports or menus where space is limited. +
description
A description of the product offering.
currencyCode
Three letter ISO code representing currency.
digitsAfterDecimal
Override the currency default value for digitsAfterDecimal.
inMultiplesOf
Override the default value for rounding currency to multiples of provided value.
interestCompoundingPeriodType
The period at which interest rate is compounded. 1=Daily, 4=Monthly (at end of month)
interestPostingPeriodType
The period at which interest rate is posted or credited to fixed deposit account. 4=Monthly (at end of month), 5=Quarterly (at end of quarter, 31st Mar, 30th Jun, 30th Sep, 31st Dec)
interestCalculationType
The interest calculation method used: 1=Daily Balance or 2=Average Daily Balance
interestCalculationDaysInYearType
The setting for number of days in year to use: 360=360 Days, 365=365 Days
lockinPeriodFrequency
Optional: If provided, used along with lockinPeriodFrequencyType to indicate the length of time that the fixed deposit account is 'locked in' and premature closure is not allowed. e.g. 2 Months
lockinPeriodFrequencyType
Optional: If provided, used along with lockinPeriodFrequency to indicate the length of time that the fixed deposit account is 'locked in' and premature closure is not allowed. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 2 Months
minDepositTerm
This is used along with minDepositTermTypeId to define allowed minimum deposit term for creating a fixed deposit account using this product. e.g. 6 Months
minDepositTermTypeId
Used along with minDepositTerm to define allowed minimum deposit term for creating a fixed deposit account using this product. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months +
maxDepositTerm
Optional: If provided, used along with maxDepositTermTypeId to define allowed maximum deposit term for creating a fixed deposit account using this product. e.g. 3 Years
maxDepositTermTypeId
Optional: If provided, used along with maxDepositTerm to define allowed maximum deposit term for creating a fixed deposit account using this product. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 3 Years +
inMultiplesOfDepositTerm
Optional: If provided, used along with inMultiplesOfDepositTermTypeId to indicate the allowed deposit periods after minimum deposit period. e.g. If inMultiplesOfDepositTerm is 3 Months then the next allowed deposit period after minimum deposit of 6 Months should be 9 Months.
inMultiplesOfDepositTermTypeId
Optional: If provided, used along with inMultiplesOfDepositTerm to indicate the allowed deposit periods after minimum deposit period. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. If inMultiplesOfDepositTerm is 3 Months then the next allowed deposit period after minimum deposit of 6 Months should be 9 Months. +
preClosurePenalApplicable
Optional: expects boolean value true/false, If provided as true then must provide preClosurePenalInterest and preClosurePenalInterestOnTypeId.
preClosurePenalInterest
Optional: Must provide when preClosurePenalApplicable is true. Used along with preClosurePenalInterestOnTypeId to apply a penalalty on top of applicable interest rate for Pre-mature closure of accounts. e.g. “1%� means 1% less than the interest rate applicable.
preClosurePenalInterestOnTypeId
Optional: Must provide when preClosurePenalApplicable is true. Used along with preClosurePenalInterest to decide what should be the applicable interest rate to which penalalty can be applied on Pre-mature closure of accounts. 1=Whole Term, 2=Till Premature withdrawal e.g. “1%� means 1% less than the interest rate applicable till premature withdrawal.
accountingRule
Specifies if accounting is enabled for the particular + product and the type of the accounting rule to be used + Example Values:1=NONE,2=CASH_BASED
+
+
+ +   +
+
+

Create a Fixed Deposit Product

+ + + + + +
Mandatory Fields
name, shortName, description, currencyCode, digitsAfterDecimal,inMultiplesOf, + interestCompoundingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minDepositTerm, minDepositTermTypeId, accountingRule
+
+ + + + + +
Mandatory Fields for Cash based accounting (accountingRule = 2)
savingsReferenceAccountId, savingsControlAccountId, interestOnSavingsAccountId, incomeFromFeeAccountId, transfersInSuspenseAccountId, incomeFromPenaltyAccountId
+
+ + + +
Optional Fields
lockinPeriodFrequency, lockinPeriodFrequencyType, maxDepositTerm, maxDepositTermTypeId, inMultiplesOfDepositTerm, inMultiplesOfDepositTermTypeId, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnTypeId, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, charges, charts
+
+
+ POST https://Domain Name/api/v1/fixeddepositproducts + POST fixeddepositproducts +Content-Type: application/json +Request Body: +{ + "name": "Fixed deposit product", + "shortName": "FD01", + "description": "Daily compounding using Daily Balance, 5% per year, 365 days in year", + "currencyCode": "USD", + "digitsAfterDecimal": 2, + "inMultiplesOf": 0, + "locale": "en", + "interestCompoundingPeriodType": 1, + "interestPostingPeriodType":4, + "interestCalculationType": 1, + "interestCalculationDaysInYearType": "365", + "accountingRule":"1", + "preClosurePenalApplicable":"true", + "preClosurePenalInterest":"1.75", + "preClosurePenalInterestOnTypeId":1, + "minDepositTerm":1, + "minDepositTermTypeId":1, + "maxDepositTerm":5, + "maxDepositTermTypeId":3, + "charts":[ + { + "fromDate": "01 Jan 2014", + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "dateFormat":"dd MMMM yyyy", + "chartSlabs":[ + { + "description":"from 0 to 90 days", + "periodType":"1", + "fromPeriod":"0", + "toPeriod":"90", + "annualInterestRate":"4.5" + } + ] + } + ] +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve a Fixed Deposit Product

+

Example Requests:

+
fixeddepositproducts/1
+

+
fixeddepositproducts/1?template=true
+

+
fixeddepositproducts/1?fields=name,description
+
+
+ GET https://Domain Name/api/v1/fixeddepositproducts/1 + +{ + "id": 1, + "name": "Fixed deposit product", + "shortName": "FD01", + "description": "Daily compounding using Daily Balance, 5% per year, 365 days in year", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "accountingMappings": { + "savingsReferenceAccount": { + "id": 12, + "name": "savings ref", + "glCode": "20" + }, + "incomeFromFeeAccount": { + "id": 16, + "name": "income from savings fee", + "glCode": "24" + }, + "incomeFromPenaltyAccount": { + "id": 17, + "name": "income from sav penalites", + "glCode": "25" + }, + "interestOnSavingsAccount": { + "id": 15, + "name": "interest on savings", + "glCode": "23" + }, + "savingsControlAccount": { + "id": 13, + "name": "savings ref tool kit", + "glCode": "21" + }, + "transfersInSuspenseAccount": { + "id": 14, + "name": "saving transfers", + "glCode": "22" + } + }, + "feeToIncomeAccountMappings": [ + { + "charge": { + "id": 11, + "name": "sav charge", + "active": false, + "penalty": false + }, + "incomeAccount": { + "id": 16, + "name": "income from savings fee", + "glCode": "24" + } + } + ], + "penaltyToIncomeAccountMappings": [ + { + "charge": { + "id": 12, + "name": "sav 2", + "active": false, + "penalty": true + }, + "incomeAccount": { + "id": 17, + "name": "income from sav penalites", + "glCode": "25" + } + } + ], + "preClosurePenalApplicable":"true", + "preClosurePenalInterest":"1.75", + "preClosurePenalInterestOnType": { + "id": 1, + "code": "preClosurePenalInterestOnType.wholeTerm", + "value": "Whole term" + }, + "minDepositTerm":1, + "minDepositTermType": { + "id": 1, + "code": "deposit.term.savingsPeriodFrequencyType.weeks", + "value": "Weeks" + }, + "maxDepositTerm":5, + "maxDepositTermType": { + "id": 3, + "code": "deposit.term.savingsPeriodFrequencyType.years", + "value": "Years" + }, + "activeChart": { + "id": 8, + "fromDate": [ + 2014, + 1, + 1 + ], + "savingsProductId": 8, + "savingsProductName": "Fixed deposit product", + "chartSlabs": [ + { + "id": 18, + "description": "from 0 to 90 days", + "periodType": { + "id": 1, + "code": "interestChartPeriodType.weeks", + "value": "Weeks" + }, + "fromPeriod": 0, + "toPeriod": 90, + "annualInterestRate": 4.5, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ], + "periodTypes": [ + { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + { + "id": 1, + "code": "interestChartPeriodType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "interestChartPeriodType.months", + "value": "Months" + }, + { + "id": 3, + "code": "interestChartPeriodType.years", + "value": "Years" + } + ] + } +} + +
+
+ +   +
+
+

Update a Fixed Deposit Product

+
+
+ PUT https://Domain Name/api/v1/fixeddepositproducts/{productId} + POST fixeddepositproducts/1 +Content-Type: application/json +Request Body: +{ + "description": "Fixed deposit product new offerings", + "locale": "en", + "minDepositTerm":5, + "minDepositTermTypeId":1, +} + + +{ + "resourceId": 1, + "changes": { + "description": "Fixed deposit product new offerings", + "minDepositTerm": 5 + } +} + +
+
+ +   +
+
+

Delete a Fixed Deposit Product

+
+
+ +DELETE https://Domain Name/api/v1/fixeddepositdproducts/{productId} + + +DELETE fixeddepositdproducts/1 +Content-Type: application/json + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

List Fixed Deposit Products

+

Example Requests:

+
fixeddepositproducts
+

+
fixeddepositproducts?fields=name
+
+
+ GET https://Domain Name/api/v1/fixeddepositproducts + +[ + { + "id": 3, + "name": "FD01", + "shortName": "FD01", + "description": "FD01", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "preClosurePenalApplicable": false, + "minDepositTerm": 3, + "maxDepositTerm": 4, + "minDepositTermType": { + "id": 2, + "code": "deposit.term.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "maxDepositTermType": { + "id": 3, + "code": "deposit.term.savingsPeriodFrequencyType.years", + "value": "Years" + }, + "nominalAnnualInterestRate": 0, + "interestCompoundingPeriodType": { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "accountingRule": { + "id": 1, + "code": "accountingRuleType.none", + "value": "NONE" + } + } +] +
+
+ + + +   +
+
+

Recurring Deposit Product:

+

Recurring Deposits are a special kind of Term Deposits offered by MFI's. The Recurring Deposit Products (aka RD) product offerings are modeled using this API.

+

Recurring Deposits help people with regular incomes to deposit a fixed amount every month (specified recurring frequency) into their Recurring Deposit account.

+

When creating recurring deposit accounts, the details from the recurring deposit product are used to auto fill details of the recurring deposit account application process.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + e.g. 2 Months + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
The name of the product offering.
shortName
Shortname associated with a recurring deposit product.
+ An abbreviated version of the name, used in reports or menus where space is limited. +
description
A description of the product offering.
currencyCode
Three letter ISO code representing currency.
digitsAfterDecimal
Override the currency default value for digitsAfterDecimal.
inMultiplesOf
Override the default value for rounding currency to multiples of provided value.
interestCompoundingPeriodType
The period at which interest rate is compounded. 1=Daily, 4=Monthly (at end of month)
interestPostingPeriodType
The period at which interest rate is posted or credited to recurring deposit account. 4=Monthly (at end of month), 5=Quarterly (at end of quarter, 31st Mar, 30th Jun, 30th Sep, 31st Dec)
interestCalculationType
The interest calculation method used: 1=Daily Balance or 2=Average Daily Balance
interestCalculationDaysInYearType
The setting for number of days in year to use: 360=360 Days, 365=365 Days
lockinPeriodFrequency
Optional: If provided, used along with lockinPeriodFrequencyType to indicate the length of time that the recurring deposit account is 'locked in' and premature closure is not allowed. e.g. 2 Months
lockinPeriodFrequencyType
recurringDepositFrequency
The frequency for depositing a fixed amount to recurring deposit account.
recurringDepositFrequencyTypeId
Used along with recurringDepositFrequency to define frequency for depositing a fixed amount to recurring deposit account. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. deposit every 1 Months +
minDepositTerm
This is used along with minDepositTermTypeId to define allowed minimum deposit term for creating a recurring deposit account using this product. e.g. 6 Months
minDepositTermTypeId
Used along with minDepositTerm to define allowed minimum deposit term for creating a recurring deposit account using this product. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months +
maxDepositTerm
Optional: If provided, used along with maxDepositTermTypeId to define allowed maximum deposit term for creating a recurring deposit account using this product. e.g. 3 Years
maxDepositTermTypeId
Optional: If provided, used along with maxDepositTerm to define allowed maximum deposit term for creating a recurring deposit account using this product. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 3 Years +
inMultiplesOfDepositTerm
Optional: If provided, used along with inMultiplesOfDepositTermTypeId to indicate the allowed deposit periods after minimum deposit period. e.g. If inMultiplesOfDepositTerm is 3 Months then the next allowed deposit period after minimum deposit of 6 Months should be 9 Months.
inMultiplesOfDepositTermTypeId
Optional: If provided, used along with inMultiplesOfDepositTerm to indicate the allowed deposit periods after minimum deposit period. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. If inMultiplesOfDepositTerm is 3 Months then the next allowed deposit period after minimum deposit of 6 Months should be 9 Months. +
preClosurePenalApplicable
Optional: expects boolean value true/false, If provided as true then must provide preClosurePenalInterest and preClosurePenalInterestOnTypeId.
preClosurePenalInterest
Optional: Must provide when preClosurePenalApplicable is true. Used along with preClosurePenalInterestOnTypeId to apply a penalalty on top of applicable interest rate for Pre-mature closure of accounts. e.g. “1%� means 1% less than the interest rate applicable.
preClosurePenalInterestOnTypeId
Optional: Must provide when preClosurePenalApplicable is true. Used along with preClosurePenalInterest to decide what should be the applicable interest rate to which penalalty can be applied on Pre-mature closure of accounts. 1=Whole Term, 2=Till Premature withdrawal e.g. “1%� means 1% less than the interest rate applicable till premature withdrawal.
accountingRule
Specifies if accounting is enabled for the particular + product and the type of the accounting rule to be used + Example Values:1=NONE,2=CASH_BASED
+
+
+ +   +
+
+

Create a Recurring Deposit Product

+ + + + + +
Mandatory Fields
name, shortName, description, currencyCode, digitsAfterDecimal,inMultiplesOf, + interestCompoundingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minDepositTerm, minDepositTermTypeId, recurringDepositFrequency, recurringDepositFrequencyTypeId, accountingRule, depositAmount
+
+ + + + + +
Mandatory Fields for Cash based accounting (accountingRule = 2)
savingsReferenceAccountId, savingsControlAccountId, interestOnSavingsAccountId, incomeFromFeeAccountId, transfersInSuspenseAccountId, incomeFromPenaltyAccountId
+
+ + + +
Optional Fields
lockinPeriodFrequency, lockinPeriodFrequencyType, maxDepositTerm, maxDepositTermTypeId, inMultiplesOfDepositTerm, inMultiplesOfDepositTermTypeId, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnTypeId, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, charges, charts, minDepositAmount, maxDepositAmount
+
+
+ POST https://Domain Name/api/v1/recurringdepositproducts + POST recurringdepositproducts +Content-Type: application/json +Request Body: +{ + "name": "Recurring deposit product", + "shortName": "RD01", + "description": "Daily compounding using Daily Balance, 5% per year, 365 days in year", + "currencyCode": "USD", + "digitsAfterDecimal": 2, + "inMultiplesOf": 0, + "locale": "en", + "interestCompoundingPeriodType": 1, + "interestPostingPeriodType":4, + "interestCalculationType": 1, + "interestCalculationDaysInYearType": "365", + "accountingRule":"1", + "recurringDepositFrequency":1, + "recurringDepositFrequencyTypeId":2, + "preClosurePenalApplicable":"true", + "preClosurePenalInterest":"1.75", + "preClosurePenalInterestOnTypeId":1, + "minDepositTerm":1, + "minDepositTermTypeId":1, + "maxDepositTerm":5, + "maxDepositTermTypeId":3, + depositAmount: "10000", + minDepositAmount: "100", + maxDepositAmount: "1000000", + "charts":[ + { + "fromDate": "01 Jan 2014", + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "dateFormat":"dd MMMM yyyy", + "chartSlabs":[ + { + "description":"from 0 to 90 days", + "periodType":"1", + "fromPeriod":"0", + "toPeriod":"90", + "annualInterestRate":"4.5" + } + ] + } + ] +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve a Recurring Deposit Product

+

Example Requests:

+
recurringdepositproducts/1
+

+
recurringdepositproducts/1?template=true
+

+
recurringdepositproducts/1?fields=name,description
+
+
+ GET https://Domain Name/api/v1/recurringdepositproducts/1 + +{ + "id": 1, + "name": "Recurring deposit product", + "shortName": "RD01", + "description": "Daily compounding using Daily Balance, 5% per year, 365 days in year", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "accountingMappings": { + "savingsReferenceAccount": { + "id": 12, + "name": "savings ref", + "glCode": "20" + }, + "incomeFromFeeAccount": { + "id": 16, + "name": "income from savings fee", + "glCode": "24" + }, + "incomeFromPenaltyAccount": { + "id": 17, + "name": "income from sav penalites", + "glCode": "25" + }, + "interestOnSavingsAccount": { + "id": 15, + "name": "interest on savings", + "glCode": "23" + }, + "savingsControlAccount": { + "id": 13, + "name": "savings ref tool kit", + "glCode": "21" + }, + "transfersInSuspenseAccount": { + "id": 14, + "name": "saving transfers", + "glCode": "22" + } + }, + "feeToIncomeAccountMappings": [ + { + "charge": { + "id": 11, + "name": "sav charge", + "active": false, + "penalty": false + }, + "incomeAccount": { + "id": 16, + "name": "income from savings fee", + "glCode": "24" + } + } + ], + "penaltyToIncomeAccountMappings": [ + { + "charge": { + "id": 12, + "name": "sav 2", + "active": false, + "penalty": true + }, + "incomeAccount": { + "id": 17, + "name": "income from sav penalites", + "glCode": "25" + } + } + ], + "recurringDepositFrequency":1, + "recurringDepositFrequencyType": { + "id": 2, + "code": "recurring.deposit.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "minDepositAmount":100.00, + "depositAmount":10000.00, + "maxDepositAmount":1000000.00, + "preClosurePenalApplicable":"true", + "preClosurePenalInterest":"1.75", + "preClosurePenalInterestOnType": { + "id": 1, + "code": "preClosurePenalInterestOnType.wholeTerm", + "value": "Whole term" + }, + "minDepositTerm":1, + "minDepositTermType": { + "id": 1, + "code": "deposit.term.savingsPeriodFrequencyType.weeks", + "value": "Weeks" + }, + "maxDepositTerm":5, + "maxDepositTermType": { + "id": 3, + "code": "deposit.term.savingsPeriodFrequencyType.years", + "value": "Years" + }, + "activeChart": { + "id": 8, + "fromDate": [ + 2014, + 1, + 1 + ], + "savingsProductId": 8, + "savingsProductName": "Fixed deposit product", + "chartSlabs": [ + { + "id": 18, + "description": "from 0 to 90 days", + "periodType": { + "id": 1, + "code": "interestChartPeriodType.weeks", + "value": "Weeks" + }, + "fromPeriod": 0, + "toPeriod": 90, + "annualInterestRate": 4.5, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ], + "periodTypes": [ + { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + { + "id": 1, + "code": "interestChartPeriodType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "interestChartPeriodType.months", + "value": "Months" + }, + { + "id": 3, + "code": "interestChartPeriodType.years", + "value": "Years" + } + ] + } +} + +
+
+ +   +
+
+

Update a Recurring Deposit Product

+
+
+ PUT https://Domain Name/api/v1/recurringdepositproducts/{productId} + POST recurringdepositproducts/1 +Content-Type: application/json +Request Body: +{ + "description": "Recurring deposit product new offerings", + "locale": "en", + "minDepositTerm":5, + "minDepositTermTypeId":1, +} + + +{ + "resourceId": 1, + "changes": { + "description": "Recurring deposit product new offerings", + "minDepositTerm": 5 + } +} + +
+
+ +   +
+
+

Delete a Recurring Deposit Product

+
+
+ +DELETE https://Domain Name/api/v1/recurringdepositdproducts/{productId} + + +DELETE recurringdepositdproducts/1 +Content-Type: application/json + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

List Recuring Deposit Products

+

Example Requests:

+
recurringdepositproducts
+

+
recurringdepositproducts?fields=name
+
+
+ GET https://Domain Name/api/v1/recurringdepositproducts + +[ + { + "id": 3, + "name": "RD01", + "shortName": "RD01", + "description": "RD01", + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "recurringDepositFrequency":1, + "recurringDepositFrequencyType": { + "id": 2, + "code": "recurring.deposit.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "preClosurePenalApplicable": false, + "minDepositTerm": 3, + "maxDepositTerm": 4, + "minDepositTermType": { + "id": 2, + "code": "deposit.term.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "maxDepositTermType": { + "id": 3, + "code": "deposit.term.savingsPeriodFrequencyType.years", + "value": "Years" + }, + "interestCompoundingPeriodType": { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "accountingRule": { + "id": 1, + "code": "accountingRuleType.none", + "value": "NONE" + } + } +] +
+
+ + + +   +
+
+

Savings Account:

+

Savings accounts are instances of a praticular savings product created for an individual or group. An application process around the creation of accounts is also supported.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Starting StateActionResultant State
-SubmitSubmitted and pending approval
Submitted and pending approvalRejectClosed - Rejected
Submitted and pending approvalWithdrawn by ApplicantClosed - Withdrawn by Applicant
Submitted and pending approvalApproveApproved
ApprovedUndo ApprovalSubmitted and pending approval
ApprovedActivateActive
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
clientId
The client you are creating the savings account for. Either clientId or groupId must be provided.
groupId
The group you are creating the savings account for. Either clientId or groupId must be provided.
productId
The id of the product used for this savings account. The savings account inherits the selected currency of the product and possibly other details if not overridden in the savings account creation request.
accountNo
The account no. associated with this loan. Is auto generated if not provided at creation time.
externalId
A place to put an external reference for this savings account useful in migrations e.g. The ID another system uses. If provided, it must be unique.
submittedOnDate
submittedOnDate must be provided when initially creating savings account application. locale and dateFormat parameters must be provided with this.
nominalAnnualInterestRate
The interest rate set for savings account e.g. 5% Per year - It is always expressed as the Nominal APR.
interestCompoundingPeriodType
The period at which interest rate is compounded. 1=Daily, 4=Monthly (at end of month)
interestPostingPeriodType
The period at which interest rate is posted or credited to savings account. The actual crediting or posting transaction is date as occurring on the day after the end of the period. 4=Monthly (at end of month), 5=Quarterly (at end of quarter, 31st Mar, 30th Jun, 30th Sep, 31st Dec), 7=Annually (at end of calendar year 31st Dec)
interestCalculationType
The interest calculation method used: 1=Daily Balance or 2=Average Daily Balance
interestCalculationDaysInYearType
The setting for number of days in year to use: 360=360 Days, 365=365 Days
minRequiredOpeningBalance
Optional: If provided, sets the minimum deposit amount required to open a savings account e.g. 2,000
lockinPeriodFrequency
Optional: If provided, used along with lockinPeriodFrequencyType to indicate the length of time that the savings account is 'locked in' and withdrawals are not allowed. e.g. 6 Months
lockinPeriodFrequencyType
Optional: If provided, used along with lockinPeriodFrequency to indicate the length of time that the savings account is 'locked in' and withdrawals are not allowed. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months
withdrawalFeeForTransfers
Optional: Used along with withdrawalFeeAmount to indicate whether the withdrawal fee should be applied on the account for account transfers .
allowOverdraft
Optional: If provided, depending on the value mark the savings account as overdraft account
overdraftLimit
Optional: If provided, sets the maximum allowed overdraft amount for a savings account e.g. 5,000 else set the limit as zero
+
+
+ +   +
+
+

Retrieve Savings Account Template:

+

This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Arguments

+
+
clientId
+
Integer mandatory
+
productId
+
Integer optional
+
If entered, productId, productName and selectedProduct fields are returned.
+
+

Example Requests:

+
savingsaccounts/template?clientId=1
+

+
savingsaccounts/template?clientId=1&productId=1
+
+
+ GET https://Domain Name/api/v1/savingsaccounts/template?clientId={clientId} + +{ + "clientId": 1, + "clientName": "small business", + "productOptions": [ + { + "id": 1, + "name": "Passbook Savings" + } + ] +} + +
+ +
+ GET https://Domain Name/api/v1/savingsaccounts/template?clientId={clientId}&productId={productId} + +{ + "clientId": 1, + "clientName": "small business", + "savingsProductId": 1, + "savingsProductName": "Passbook Savings", + "timeline": {}, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "nominalAnnualInterestRate": 5, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "productOptions": [ + { + "id": 1, + "name": "Passbook Savings" + } + ], + "fieldOfficerOptions": [ + { + "id": 3, + "firstname": "Mrs.", + "lastname": "loanofficerB1", + "displayName": "loanofficerB1, Mrs.", + "officeId": 2, + "officeName": "branch 1", + "isLoanOfficer": true + }, + { + "id": 1, + "firstname": "Mr.", + "lastname": "loanofficerHO", + "displayName": "loanofficerHO, Mr.", + "officeId": 1, + "officeName": "branch 1", + "isLoanOfficer": true + } + ], + "interestCompoundingPeriodTypeOptions": [ + { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + } + ], + "interestPostingPeriodTypeOptions": [ + { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + { + "id": 5, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.quarterly", + "value": "Quarterly" + }, + { + "id": 7, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.annual", + "value": "Annually" + } + ], + "interestCalculationTypeOptions": [ + { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + { + "id": 2, + "code": "savingsInterestCalculationType.averagedailybalance", + "value": "Average Daily Balance" + } + ], + "interestCalculationDaysInYearTypeOptions": [ + { + "id": 360, + "code": "savingsInterestCalculationDaysInYearType.days360", + "value": "360 Days" + }, + { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + } + ], + "lockinPeriodFrequencyTypeOptions": [ + { + "id": 0, + "code": "savings.lockin.savingsPeriodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "savings.lockin.savingsPeriodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "savings.lockin.savingsPeriodFrequencyType.months", + "value": "Months" + }, + { + "id": 3, + "code": "savings.lockin.savingsPeriodFrequencyType.years", + "value": "Years" + } + ], + "withdrawalFeeTypeOptions": [ + { + "id": 1, + "code": "savingsWithdrawalFeesType.flat", + "value": "Flat" + }, + { + "id": 2, + "code": "savingsWithdrawalFeesType.percent.of.amount", + "value": "% of Amount" + } + ], + "chargeOptions": [ + { + "id": 4, + "name": "Savings charge 1", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 200, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "chargepaymentmode.regular" + } + }, + { + "id": 5, + "name": "Savings charge 2", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 300, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "chargepaymentmode.regular" + } + }, + { + "id": 6, + "name": "Annual fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 50, + "chargeTimeType": { + "id": 6, + "code": "chargeTimeType.annualFee", + "value": "Annual Fee" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 7, + "name": "Quarterly fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 5, + "chargeTimeType": { + "id": 7, + "code": "chargeTimeType.monthlyFee", + "value": "Monthly Fee" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + }, + "feeOnMonthDay": [ + 10, + 5 + ], + "feeInterval": 4 + } + ] +} + +
+
+ +   +
+
+

Submit new savings application

+
+ + + +
Mandatory Fields
clientId or groupId, productId, submittedOnDate
+
+ + + +
Optional Fields
accountNo, externalId, fieldOfficerId
+
+ + + + +
Inherited from Product (if not provided)
nominalAnnualInterestRate, interestCompoundingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, allowOverdraft, overdraftLimit
+
+
+

Minimal request: accountNo auto generated, remaining details inherited from savings product.

+ POST https://Domain Name/api/v1/savingsaccounts + POST savingsaccount +Content-Type: application/json +Request Body: +{ + "clientId": 1, + "productId": 1, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "submittedOnDate": "01 March 2011" +} + +

Minimal request: accountNo provided (must be unique), remaining details inherited from savings product.

+ POST savingsaccount +Content-Type: application/json +Request Body: +{ + "clientId": 1, + "productId": 1, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "submittedOnDate": "01 March 2011", + "accountNo": "SA000023", + "externalId": "SYS-23" +} + +

Full request: accountNo provided (must be unique), remaining details override details from savings product (except currency).

+ POST savingsaccount +Content-Type: application/json +Request Body: +{ + "clientId": 1, + "productId": 1, + "fieldOfficerId": 1, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "submittedOnDate": "01 March 2013", + "accountNo": "SA000023", + "externalId": "SYS-23", + "nominalAnnualInterestRate": "5.65", + "interestCompoundingPeriodType": 1, + "interestPostingPeriodType": 4, + "interestCalculationType": 1, + "interestCalculationDaysInYearType": 365, + "minRequiredOpeningBalance": "1,000", + "lockinPeriodFrequency": 6, + "lockinPeriodFrequencyType": 2, + "allowOverdraft":true, + "overdraftLimit":5000, + "charges":[{"id":"1"}] +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Approve savings application

+

Approves savings application so long as its in 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=approve + POST savingsaccount/1?command=approve +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "01 March 2013" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 200, + "code": "savingsAccountStatusType.approved", + "value": "Approved", + "submittedAndPendingApproval": false, + "approved": true, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "02 March 2013" + } +} + +
+
+ +   +
+
+

Undo approval savings application

+

Will move 'approved' savings application back to 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=undoApproval + POST savingsaccount/1?command=undoApproval +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "approvedOnDate": "" + } +} + +
+
+ +  +
+
+

Assign Savings Officer

+

Allows you to assign Savings Officer for existing Savings Account.

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=assignSavingsOfficer + POST savingsaccounts/1?command=assignSavingsOfficer +Content-Type: application/json +Request Body: +{ + assignmentDate : "04 September 2014", + dateFormat : "dd MMMM yyyy", + fromSavingsOfficerId : "", + locale : "en", + toSavingsOfficerId : 2 +} + + +{ + "officeId":2, + "savingsId":8, + "resourceId":8, + "changes":{"savingsOfficerId":2} +} + +
+
+ +   +
+
+

Unassign Savings Officer

+

Allows you to unassign the Savings Officer.

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=unassignSavingsOfficer + POST savingsaccounts/1?command=unassignSavingsOfficer +Content-Type: application/json +Request Body: +{ + dateFormat : "dd MMMM yyyy", + locale : "en", + unassignedDate : "05 September 2014" +} + + +{ + "officeId":2, + "clientId":8, + "resourceId":8, + "changes":{} +} + +
+
+ +   +
+
+

Reject savings application

+

Rejects savings application so long as its in 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=reject + POST savingsaccount/1?command=reject +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "03 March 2013" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 500, + "code": "savingsAccountStatusType.rejected", + "value": "Rejected", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": true, + "withdrawnByApplicant": false, + "active": false, + "closed": true + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "03 March 2013", + "closedOnDate": "03 March 2013" + } +} + +
+
+ +   +
+
+

Withdraw savings application

+

Used when an applicant withdraws from the savings application. It must be in 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=withdrawnByApplicant + POST savingsaccount/1?command=withdrawnByApplicant +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "withdrawnOnDate": "03 March 2013" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 400, + "code": "savingsAccountStatusType.withdrawn.by.applicant", + "value": "Withdrawn by applicant", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": true, + "active": false, + "closed": true + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "withdrawnOnDate": "03 March 2013", + "closedOnDate": "03 March 2013" + } +} + +
+
+ +   +
+
+

Activate a savings account

+

Results in an approved savings application being converted into an 'active' savings account.

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=activate + POST savingsaccount/1?command=activate +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "activatedOnDate": "01 March 2013" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 300, + "code": "savingsAccountStatusType.active", + "value": "Active", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": true, + "closed": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "activatedOnDate": "01 March 2013" + } +} + +
+
+ +   +
+
+

Close a savings account

+

Results in an Activated savings application being converted into an 'closed' savings account.

+

closedOnDate is closure date of savings account

+

withdrawBalance is a boolean value, true value of this field performs a withdrawal transaction with account's running balance.

+ + + + + + + +
Mandatory Fields
dateFormat,locale,closedOnDate
+
+ + + + + + + +
Optional Fields
note, withdrawBalance, paymentTypeId, accountNumber, checkNumber, routingCode, receiptNumber, bankNumber
+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=close + POST savingsaccount/5?command=close +Content-Type: application/json +Request Body: +{ + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closedOnDate":"26 August 2013", + "note":"close note" +} + + +{ + "officeId":1, + "clientId":1, + "savingsId":5, + "resourceId":5, + "changes":{ + "status":{ + "id":600, + "code":"savingsAccountStatusType.closed", + "value":"Closed", + "submittedAndPendingApproval":false, + "approved":false, + "rejected":false, + "withdrawnByApplicant":false, + "active":false, + "closed":true + }, + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "closedOnDate":"26 August 2013", + "note":"close note" + } +} + + POST savingsaccount/5?command=close +Content-Type: application/json +Request Body: +{ + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closedOnDate":"26 August 2013", + "note":"close note", + "withdrawBalance":true, + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId":1, + "clientId":1, + "savingsId":5, + "resourceId":5, + "changes":{ + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123", + "status":{ + "id":600, + "code":"savingsAccountStatusType.closed", + "value":"Closed", + "submittedAndPendingApproval":false, + "approved":false, + "rejected":false, + "withdrawnByApplicant":false, + "active":false, + "closed":true + }, + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "closedOnDate":"26 August 2013", + "note":"close note" + } +} + +
+
+ +   +
+
+

Calculate Interest on Savings Account

+

+ Calculates interest earned on a savings account based on todays date. It does not attempt to post or credit the interest on the account. That is responsibility of the Post Interest API that will likely be called by overnight process. +

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=calculateInterest + POST savingsaccount/1?command=calculateInterest +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Post Interest on Savings Account

+

+ Calculates and Posts interest earned on a savings account based on todays date and whether an interest posting or crediting event is due. +

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{savingsId}?command=postInterest + POST savingsaccount/1?command=postInterest +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

List savings applications/accounts

+

Example Requests:

+
savingsaccounts
+

+
savingsaccounts?fields=name
+
+
+ GET https://Domain Name/api/v1/savingsaccounts + +{ + "totalFilteredRecords": 1, + "pageItems": [ + { + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "small business", + "savingsProductId": 1, + "savingsProductName": "Passbook Savings", + "fieldOfficerId": 0, + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "timeline": { + "submittedOnDate": [ + 2013, + 3, + 1 + ] + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "nominalAnnualInterestRate": 5, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountBalance": 0 + } + } + ] +} + +
+
+ +   +
+
+

Retrieve a savings application/account:

+

Arguments

+
+
associations
+
optional, Either 'all' or a comma separated list of savings 'associations' (itemized below).
+

Associations are just extra pieces of data that you might or might not want to retrieve.

+
'all': Gets data related to all associations e.g. ?associations=all.
+
'transactions': Gets data related to transactions on the account e.g. ?associations=transactions
+
'charges':Savings Account charges data.
+
+

Example Requests :

+
savingsaccounts/1
+

+
savingsaccounts/1?associations=all
+
+
+ GET https://DomainName/api/v1/savingsaccounts/{accountId} + +{ + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "small business", + "savingsProductId": 1, + "savingsProductName": "Passbook Savings", + "fieldOfficerId": 0, + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "timeline": { + "submittedOnDate": [ + 2013, + 3, + 1 + ] + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "nominalAnnualInterestRate": 5, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountBalance": 0 + } +} + +
+
+ +   +
+
+

Modify a savings application

+

Savings application can only be modified when in 'Submitted and pending approval' state. Once the application is approved, the details cannot be changed using this method. Specific api endpoints will be created to allow change of interest detail such as rate, compounding period, posting period etc

+
+
+ PUT https://Domain Name/api/v1/savingsaccounts/{accountsId} + PUT savingsaccounts/1 +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "nominalAnnualInterestRate": "5.9999999999" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "nominalAnnualInterestRate": 5.9999999999, + "locale": "en" + } +} + +
+
+ +   +
+
+

Delete a savings application

+

At present we support hard delete of savings application so long as its in 'Submitted and pending approval' state. One the application is moves past this state, it is not possible to do a 'hard' delete of the application or the account. An API endpoint will be added to close/de-activate the savings account.

+
+
+ DELETE https://Domain Name/api/v1/savingsaccounts/{accountsId} + DELETE savingsaccounts/1 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Savings Account Transactions:

+

Transactions possible on a savings account.

+ + + + + + + + +
Field Descriptions
transactionDate
The date of the transaction.
transactionAmount
The amount of the transaction.
+
+
+ +   +
+
+

Retrieve Savings Account Transaction Template:

+

This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Requests:

+
savingsaccounts/1/transactions/template
+
+
+
+ GET https://Domain Name/api/v1/savingsaccounts/{accountId}/transactions/template + + +{ + "accountId": 1, + "accountNo": "000000001", + "date": [ + 2013, + 5, + 27 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "paymentTypeOptions": [ + { + "id": 14, + "name": "Wire Transfer", + "position": 0 + }, + { + "id": 13, + "name": "Cash", + "position": 1 + } + ] +} + +
+
+ +  +
+
+

Retrieve Savings Account Transaction:

+

This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Requests:

+
savingsaccounts/1/transactions/1
+
+
+
+ GET https://Domain Name/api/v1/savingsaccounts/{accountId}/transactions/{transactionId} + + +{ + "id": 1, + "transactionType": { + "id": 2, + "code": "savingsAccountTransactionType.withdrawal", + "value": "Withdrawal", + "deposit": false, + "withdrawal": true, + "interestPosting": false, + "feeDeduction": false + }, + "accountId": 1, + "accountNo": "000000001", + "date": [ + 2013, + 8, + 7 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "paymentDetailData": { + "id": 62, + "paymentType": { + "id": 11, + "name": "cash" + }, + "accountNumber": "", + "checkNumber": "", + "routingCode": "", + "receiptNumber": "", + "bankNumber": "" + }, + "amount": 5000, + "runningBalance": 0, + "reversed": true +} + +
+
+ +   +
+
+

Deposit Transaction

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{accountsId}/transactions?command=deposit + POST savingsaccounts/1/transactions?command=deposit +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "27 May 2013", + "transactionAmount": "500", + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 47, + "changes": { + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ +   +
+
+

Withdrawal Transaction

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{accountsId}/transactions?command=withdrawal + POST savingsaccounts/1/transactions?command=withdrawal +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "27 May 2013", + "transactionAmount": "500", + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 48, + "changes": { + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ +   +
+
+

Adjust Transaction

+

This command modifies the given transaction.

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{accountsId}/transactions/{transactionId}?command=modify + POST savingsaccounts/1/transactions/1?command=modify +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "27 May 2013", + "transactionAmount": "500", + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 48, + "changes": { + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ + +   +
+
+

Undo transaction

+

This command reverses the given transaction.

+
+
+ POST https://Domain Name/api/v1/savingsaccounts/{accountsId}/transactions/{transactionId}?command=undo + POST savingsaccounts/1/transactions/1?command=undo +Content-Type: application/json +No Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ + + +   +
+
+

Savings Charges

+

Its typical for MFIs to add maintenance and operating charges. They can be either Fees or Penalties. +

+

Savings Charges are instances of Charges and + represent either fees and penalties for savings products. Refer Charges + for documentation of the various properties of a charge, Only additional properties ( + specific to the context of a Charge being associated with a Savings account) are + described here

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
amountPaid
The Total amount which has been paid for this Charge +
amountWaived
The Total amount that has been waived for this Charge +
amountWrittenOff
Total amount written off from this Charge +
amountOutstanding
The Total outstanding amount for this Charge +
+
+
+ +   +
+
+

List Savings Charges

+

Example Requests:

+
savingsaccounts/1/charges
+
+
savingsaccounts/1/charges?chargeStatus=all
+
+
savingsaccounts/1/charges?chargeStatus=inactive
+
+
savingsaccounts/1/charges?chargeStatus=active
+
+
savingsaccounts/1/charges?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/savingsaccounts/{accountId}/charges + + +[ + { + "id": 1, + "chargeId": 3, + "accountId": 57, + "name": "Savings account maintenance fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + }, + { + "id": 2, + "chargeId": 4, + "accountId": 57, + "name": "Pass book Fee", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2013, + 3, + 29 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + }, + { + "id": 9, + "chargeId": 4, + "accountId": 57, + "name": "Withdrawal fee percentage", + "chargeTimeType": { + "id": 5, + "code": "chargeTimeType.withdrawalFee", + "value": "Withdrawal Fee" + }, + "chargeCalculationType": { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + }, + "percentage": 0.25, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 0, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 0, + "amountOrPercentage": 0.25, + "penalty": false + }, + { + "id": 10, + "chargeId": 6, + "accountId": 57, + "name": "Annual fee - INR", + "chargeTimeType": { + "id": 6, + "code": "chargeTimeType.annualFee", + "value": "Annual Fee" + }, + "feeOnMonthDay": [ + 10, + 9 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 50, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 50, + "amountOrPercentage": 50, + "penalty": false + } +] + +
+
+ +   +
+
+

Retrieve Savings Charges Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
savingsaccounts/1/charges/template
+
+
+ +GET https://DomainName/api/v1/savingsaccounts/{accountId}/charges/template + + +{ + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "chargeOptions": [ + { + "id": 2, + "name": "Passbook Fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + } + }, + { + "id": 3, + "name": "Chequebook fee", + "active": true, + "penalty": true, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 1, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + } + }, + { + "id": 6, + "name": "Annual fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 50, + "chargeTimeType": { + "id": 6, + "code": "chargeTimeType.annualFee", + "value": "Annual Fee" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + } + ], + "penalty": false +} + +
+
+ +   +
+
+

Retrieve a Savings account Charge

+

Example Requests:

+
/savingsaccounts/1/charges/5
+
+
+
/savingsaccounts/1/charges/5?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/savingsaccounts/{accountId}/charges/{savingsAccountChargeId} + + +{ + "id": 1, + "chargeId": 1, + "name": "Passbook fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false +} +
+
+ +   +
+
+

Create a Savings account Charge

+ + + + + + + + + + + + + + + + + + + +
Mandatory Fields + for Savings account Charges
chargeId, amount
Mandatory Fields + for Savings account Charges of Specified due date type
chargeId, amount, dueDate, dateFormat, locale
Mandatory Fields + for Savings account Charges of Annual fee type
chargeId, amount, feeOnMonthDay, monthDayFormat, locale
+
+
+ +POST https://DomainName/api/v1/savingsaccounts/{accountId}/charges + + +POST /savingsaccounts/1/charges +Content-Type: application/json +Request Body: +{ + "chargeId": "2", + "locale": "en", + "amount": "100", + "dateFormat": "dd MMMM yyyy", + "dueDate": "29 April 2013" +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 6 +} + + +POST /savingsaccounts/1/charges +Content-Type: application/json +Request Body: +{ + "chargeId": "2", + "locale": "en", + "amount": "25", + "monthDayFormat": "dd MMMM", + "feeOnMonthDay": "09 October" +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 7 +} + +
+
+ +   +
+
+

Update a Savings account Charge

+

Currently Savings account Charges may be updated only if the Savings account + is not yet approved. +

+
+
+ +PUT https://DomainName/api/v1/savingsaccounts/{accountId}/charges/{savingsAccountChargeId} + + +PUT savingsaccounts/1/charges/6 +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "amount": "60", + "dueDate": "27 March 2013" +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 6, + "changes": { + "dueDate": "27 March 2013", + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "amount": 60.0 + } +} + +
+
+ +   +
+
+

Delete a Savings account Charge

+

+ Note:Currently, A Savings account Charge may only be removed from Savings that are not + yet approved. +

+
+
+ +DELETE https://DomainName/api/v1/savingsaccounts/{accountId}/charges/{savingsAccountChargeId} + + +DELETE savingsaccounts/1/charges/2 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 2 +} + +
+
+ +   +
+
+

Pay a Savings account Charge

+

+ An active charge will be paid when savings account is active and having sufficient balance. +

+
+
+ +POST https://DomainName/api/v1/savingsaccounts/{accountId}/charges/{savingsAccountChargeId}?command=paycharge + + +POST savingsaccounts/1/charges/2?command=paycharge +Content-Type: application/json +Request Body: +{ + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "amount": "60", + "dueDate": "12 September 2013" +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 2 +} + +
+
+ +   +
+
+

Waive off a Savings account Charge

+

+ Outstanding charge amount will be waived off. +

+
+
+ +POST https://DomainName/api/v1/savingsaccounts/{accountId}/charges/{savingsAccountChargeId}?command=waive + + +POST savingsaccounts/1/charges/2?command=waive +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 2 +} + +
+
+ +   +
+
+

Inactivate a Savings account Charge

+

+ A charge will be allowed to inactivate when savings account is active and not having any dues as of today. If charge is overpaid, corresponding charge payment transactions will be reversed. +

+
+
+ +POST https://DomainName/api/v1/savingsaccounts/{accountId}/charges/{savingsAccountChargeId}?command=inactivate + + +POST savingsaccounts/1/charges/2?command=inactivate +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 2 +} + +
+
+ + + + +   +
+
+

Fixed Deposit Account:

+

Fixed Deposit accounts are instances of a praticular fixed deposit product created. An application process around the creation of accounts is also supported.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Starting StateActionResultant State
-SubmitSubmitted and pending approval
Submitted and pending approvalRejectClosed - Rejected
Submitted and pending approvalWithdrawn by ApplicantClosed - Withdrawn by Applicant
Submitted and pending approvalApproveApproved
ApprovedUndo ApprovalSubmitted and pending approval
ApprovedActivateActive
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
clientId
The client you are creating the fixed deposit account for. Either clientId or groupId must be provided.
groupId
The group you are creating the fixed deposit account for. Either clientId or groupId must be provided.
productId
The id of the product used for this fixed deposit account. The fixed deposit account inherits the selected currency of the product and possibly other details if not overridden in the fixed deposit account creation request.
accountNo
The account no. associated with this fixed deposit. Is auto generated if not provided at creation time.
externalId
A place to put an external reference for this fixed deposit account useful in migrations e.g. The ID another system uses. If provided, it must be unique.
submittedOnDate
submittedOnDate must be provided when initially creating fixed deposit account application. locale and dateFormat parameters must be provided with this.
interestCompoundingPeriodType
The period at which interest rate is compounded. 1=Daily, 4=Monthly (at end of month)
interestPostingPeriodType
The period at which interest rate is posted or credited to fixed deposit account. The actual crediting or posting transaction is date as occurring on the day after the end of the period. 4=Monthly (at end of month), 5=Quarterly (at end of quarter, 31st Mar, 30th Jun, 30th Sep, 31st Dec), 7=Annually (at end of calendar year 31st Dec)
interestCalculationType
The interest calculation method used: 1=Daily Balance or 2=Average Daily Balance
interestCalculationDaysInYearType
The setting for number of days in year to use: 360=360 Days, 365=365 Days
lockinPeriodFrequency
Optional: If provided, used along with lockinPeriodFrequencyType to indicate the length of time that the fixed deposit account is 'locked in' and withdrawals are not allowed. e.g. 6 Months
lockinPeriodFrequencyType
Optional: If provided, used along with lockinPeriodFrequency to indicate the length of time that the fixed deposit account is 'locked in' and withdrawals are not allowed. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months
depositAmount
The fixed deposit amount for which interest is provided on maturity.
depositPeriod
Used along with depositPeriodFrequencyId to define term for which amount is deposited in fixed deposit. e.g. 6 Months
depositPeriodFrequencyId
Used along with depositPeriod to define term for which amount is deposited in fixed deposit. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months +
minDepositTerm
This is used along with minDepositTermTypeId to define allowed minimum deposit term for creating a fixed deposit account using this product. e.g. 6 Months
minDepositTermTypeId
Used along with minDepositTerm to define allowed minimum deposit term for creating a fixed deposit account using this product. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months +
maxDepositTerm
Optional: If provided, used along with maxDepositTermTypeId to define allowed maximum deposit term for creating a fixed deposit account using this product. e.g. 3 Years
maxDepositTermTypeId
Optional: If provided, used along with maxDepositTerm to define allowed maximum deposit term for creating a fixed deposit account using this product. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 3 Years +
inMultiplesOfDepositTerm
Optional: If provided, used along with inMultiplesOfDepositTermTypeId to indicate the allowed deposit periods after minimum deposit period. e.g. If inMultiplesOfDepositTerm is 3 Months then the next allowed deposit period after minimum deposit of 6 Months should be 9 Months.
inMultiplesOfDepositTermTypeId
Optional: If provided, used along with inMultiplesOfDepositTerm to indicate the allowed deposit periods after minimum deposit period. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. If inMultiplesOfDepositTerm is 3 Months then the next allowed deposit period after minimum deposit of 6 Months should be 9 Months. +
preClosurePenalApplicable
Optional: expects boolean value true/false, If provided as true then must provide preClosurePenalInterest and preClosurePenalInterestOnTypeId.
preClosurePenalInterest
Optional: Must provide when preClosurePenalApplicable is true. Used along with preClosurePenalInterestOnTypeId to apply a penalalty on top of applicable interest rate for Pre-mature closure of accounts. e.g. “1%� means 1% less than the interest rate applicable.
preClosurePenalInterestOnTypeId
Optional: Must provide when preClosurePenalApplicable is true. Used along with preClosurePenalInterest to decide what should be the applicable interest rate to which penalalty can be applied on Pre-mature closure of accounts. 1=Whole Term, 2=Till Premature withdrawal e.g. “1%� means 1% less than the interest rate applicable till premature withdrawal.
+
+
+ +   +
+
+

Retrieve Fixed Deposit Account Template:

+

This is a convenience resource. It can be useful when building maintenance user interface screens for fixed deposit applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Arguments

+
+
clientId
+
Integer mandatory
+
productId
+
Integer optional
+
If entered, productId, productName and selectedProduct fields are returned.
+
+

Example Requests:

+
fixeddepositaccounts/template?clientId=1
+

+
fixeddepositaccounts/template?clientId=1&productId=1
+
+
+ GET https://Domain Name/api/v1/fixeddepositaccounts/template?clientId={clientId} + +{ + "clientId": 1, + "clientName": "small business", + "productOptions": [ + { + "id": 1, + "name": "Passbook Savings" + } + ] +} + +
+ +
+ GET https://Domain Name/api/v1/fixeddepositaccounts/template?clientId={clientId}&productId={productId} + +{ + "clientId": 1, + "clientName": "small business", + "savingsProductId": 1, + "savingsProductName": "Passbook Savings", + "timeline": {}, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "nominalAnnualInterestRate": 5, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "productOptions": [ + { + "id": 1, + "name": "Passbook Savings" + } + ], + "fieldOfficerOptions": [ + { + "id": 3, + "firstname": "Mrs.", + "lastname": "loanofficerB1", + "displayName": "loanofficerB1, Mrs.", + "officeId": 2, + "officeName": "branch 1", + "isLoanOfficer": true + }, + { + "id": 1, + "firstname": "Mr.", + "lastname": "loanofficerHO", + "displayName": "loanofficerHO, Mr.", + "officeId": 1, + "officeName": "branch 1", + "isLoanOfficer": true + } + ], + "interestCompoundingPeriodTypeOptions": [ + { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + } + ], + "interestPostingPeriodTypeOptions": [ + { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + { + "id": 5, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.quarterly", + "value": "Quarterly" + }, + { + "id": 7, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.annual", + "value": "Annually" + } + ], + "interestCalculationTypeOptions": [ + { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + { + "id": 2, + "code": "savingsInterestCalculationType.averagedailybalance", + "value": "Average Daily Balance" + } + ], + "interestCalculationDaysInYearTypeOptions": [ + { + "id": 360, + "code": "savingsInterestCalculationDaysInYearType.days360", + "value": "360 Days" + }, + { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + } + ], + "lockinPeriodFrequencyTypeOptions": [ + { + "id": 0, + "code": "savings.lockin.savingsPeriodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "savings.lockin.savingsPeriodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "savings.lockin.savingsPeriodFrequencyType.months", + "value": "Months" + }, + { + "id": 3, + "code": "savings.lockin.savingsPeriodFrequencyType.years", + "value": "Years" + } + ], + "withdrawalFeeTypeOptions": [ + { + "id": 1, + "code": "savingsWithdrawalFeesType.flat", + "value": "Flat" + }, + { + "id": 2, + "code": "savingsWithdrawalFeesType.percent.of.amount", + "value": "% of Amount" + } + ], + "chargeOptions": [ + { + "id": 4, + "name": "Savings charge 1", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 200, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "chargepaymentmode.regular" + } + }, + { + "id": 5, + "name": "Savings charge 2", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 300, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "chargepaymentmode.regular" + } + }, + { + "id": 6, + "name": "Annual fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 50, + "chargeTimeType": { + "id": 6, + "code": "chargeTimeType.annualFee", + "value": "Annual Fee" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 7, + "name": "Quarterly fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 5, + "chargeTimeType": { + "id": 7, + "code": "chargeTimeType.monthlyFee", + "value": "Monthly Fee" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + }, + "feeOnMonthDay": [ + 10, + 5 + ], + "feeInterval": 4 + } + ] +} + +
+
+ +   +
+
+

Submit new fixed deposit application

+
+ + + +
Mandatory Fields
clientId or groupId, productId, submittedOnDate, depositAmount, depositPeriod, depositPeriodFrequencyId
+
+ + + +
Optional Fields
accountNo, externalId, fieldOfficerId,linkAccountId(if provided initial deposit amount will be collected from this account),transferInterestToSavings(By enabling this flag all interest postings will be transferred to linked saving account )
+
+ + + + +
Inherited from Product (if not provided)
interestCompoundingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency, lockinPeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnTypeId, charts
+
+
+

Minimal request: accountNo auto generated, remaining details inherited from fixed deposit product.

+ POST https://Domain Name/api/v1/fixeddepositaccounts + POST fixeddepositaccount +Content-Type: application/json +Request Body: +{ + "clientId": 1, + "productId": 1, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "submittedOnDate": "01 March 2014", + "depositAmount":"5000", + "depositPeriod":"6", + "depositPeriodFrequencyId":"2" +} + +

Minimal request: accountNo provided (must be unique), remaining details inherited from fixed deposit product.

+ POST fixeddepositaccount +Content-Type: application/json +Request Body: +{ + "clientId": 1, + "productId": 1, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "submittedOnDate": "01 March 2014", + "depositAmount":"5000", + "depositPeriod":"6", + "depositPeriodFrequencyId":"2", + "accountNo": "FD000023", + "externalId": "FD-23" +} + +

Full request: accountNo provided (must be unique), remaining details override details from fixed deposit product (except currency).

+ POST savingsaccount +Content-Type: application/json +Request Body: +{ + "clientId": 1, + "productId": 1, + "fieldOfficerId": 1, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "submittedOnDate": "01 March 2014", + "accountNo": "FD000024", + "externalId": "FD-24", + "interestCompoundingPeriodType": 1, + "interestPostingPeriodType": 4, + "interestCalculationType": 1, + "interestCalculationDaysInYearType": 365, + "depositAmount":"5000", + "depositPeriod":"6", + "depositPeriodFrequencyId":"2", + "lockinPeriodFrequency": 6, + "lockinPeriodFrequencyType": 2, + "charges":[{"id":"1"}] +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Approve fixed deposit application

+

Approves fixed deposit application so long as its in 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{accountId}?command=approve + POST fixeddepositaccounts/1?command=approve +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "01 March 2013" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 200, + "code": "savingsAccountStatusType.approved", + "value": "Approved", + "submittedAndPendingApproval": false, + "approved": true, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "01 March 2013" + } +} + +
+
+ +   +
+
+

Undo approval fixed deposit application

+

Will move 'approved' fixed deposit application back to 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{accountId}?command=undoApproval + POST fixeddepositaccounts/1?command=undoApproval +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "approvedOnDate": "" + } +} + +
+
+ +   +
+
+

Reject fixed deposit application

+

Rejects fixed deposit application so long as its in 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{accountId}?command=reject + POST fixeddepositaccounts/1?command=reject +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "03 March 2013" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 500, + "code": "savingsAccountStatusType.rejected", + "value": "Rejected", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": true, + "withdrawnByApplicant": false, + "active": false, + "closed": true + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "03 March 2013", + "closedOnDate": "03 March 2013" + } +} + +
+
+ +   +
+
+

Withdraw fixed deposit application

+

Used when an applicant withdraws from the fixed deposit application. It must be in 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{savingsId}?command=withdrawnByApplicant + POST savingsaccount/1?command=withdrawnByApplicant +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "withdrawnOnDate": "03 March 2013" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 400, + "code": "savingsAccountStatusType.withdrawn.by.applicant", + "value": "Withdrawn by applicant", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": true, + "active": false, + "closed": true + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "withdrawnOnDate": "03 March 2013", + "closedOnDate": "03 March 2013" + } +} + +
+
+ +   +
+
+

Activate a fixed deposit account

+

Results in an approved fixed deposit application being converted into an 'active' fixed deposit account.

+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{accountId}?command=activate + POST savingsaccount/1?command=activate +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "activatedOnDate": "01 March 2013" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 300, + "code": "savingsAccountStatusType.active", + "value": "Active", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": true, + "closed": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "activatedOnDate": "01 March 2013" + } +} + +
+
+ +   +
+
+

Close a fixed deposit account

+

Results in a Matured fixed deposit account being converted into a 'closed' fixed deposit account.

On account close allowed actions are.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Action on CloseResult
Withdraw Deposit                     Matured amount withdrawn and paid to client
Transfer to SavingsMatured amount transfered to specified savings account.
                     
Re-InvestCreate new Fixed deposit application with matured amount as deposit amount.
+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{accountId}?command=close + POST fixeddepositaccounts/1?command=close +Content-Type: application/json +Request Body: + { + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closedOnDate":"19 April 2014", + "note":"Closing and transfering amount to savings", + "onAccountClosureId":"200", + "toSavingsAccountId":1, + "transferDescription":"Transfered matured amount to savings account" + } + + +{ +"officeId":1, +"clientId":1, +"savingsId":5, +"resourceId":5, +"changes":{ + "status":{ + "id":600, + "code":"savingsAccountStatusType.closed", + "value":"Closed", + "submittedAndPendingApproval":false, + "approved":false, + "rejected":false, + "withdrawnByApplicant":false, + "active":false, + "closed":true + }, + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "closedOnDate":"19 April 2014", + "note":"Closing and transfering amount to savings" + } +} + +
+
+ +   +
+
+

Premature Close a fixed deposit account

+

Results in an Active fixed deposit account being converted into a 'Premature Closed' fixed deposit account with options to withdraw prematured amount. (premature amount is calculated using interest rate chart applicable along with penal interest if any.)

On account premature closure allowed actions are.

+ + + + + + + + + + + + + + + + + +
Action on Premature CloseResult
Withdraw Deposit                     Matured amount withdrawn and paid to client
Transfer to SavingsMatured amount transfered to specified savings account.
+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{accountId}?command=prematureClose + POST fixeddepositaccounts/1?command=prematureClose +Content-Type: application/json +Request Body: + { + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closedOnDate":"19 April 2014", + "note":"Close and transfer amount to savings", + "onAccountClosureId":"200", + "toSavingsAccountId":1, + "transferDescription":"Transfered matured amount to savings account" + } + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 700, + "code": "savingsAccountStatusType.pre.mature.closure", + "value": "Premature Closed", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false, + "prematureClosed": true, + "transferInProgress": false, + "transferOnHold": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "closedOnDate": "19 April 2014", + "note": "Close and transfer amount to savings" + } +} + +
+
+ +   +
+
+

Calculate Premature amount on Fixed deposit account

+

Calculate premature amount on fixed deposit account till premature close date. Premature amount is calculated based on interest chart and penal interest applicable.

+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{accountId}?command=calculatePrematureAmount + POST fixeddepositaccounts/1?command=calculatePrematureAmount +Content-Type: application/json +Request Body: + { + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closedOnDate":"19 April 2014" + } + + +{ + "maturityAmount": 100.65, + "savingsAccounts": [ + { + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "Sangamesh N", + "savingsProductId": 1, + "savingsProductName": "FD-0001" + } + ], + "onAccountClosureOptions": [ + { + "id": 100, + "code": "depositAccountClosureType.withdrawDeposit", + "value": "Withdra Deposit" + }, + { + "id": 200, + "code": "depositAccountClosureType.transferToSavings", + "value": "Transfer to Savings" + }, + { + "id": 300, + "code": "depositAccountClosureType.reinvest", + "value": "Re-Invest" + } + ], + "paymentTypeOptions": [], + "id": 12, + "depositType": { + "id": 300, + "code": "depositAccountType.recurringDeposit", + "value": "Recurring Deposit" + } +} + +
+
+ +   +
+
+

Calculate Interest on Fixed Deposit Account

+

+ Calculates interest earned on a fixed deposit account based on todays date. It does not attempt to post or credit the interest on the account. That is responsibility of the Post Interest API that will likely be called by overnight process. +

+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{accountId}?command=calculateInterest + POST fixeddepositaccount/1?command=calculateInterest +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Post Interest on Fixed Deposit Account

+

+ Calculates and Posts interest earned on a fixed deposit account based on todays date and whether an interest posting or crediting event is due. +

+
+
+ POST https://Domain Name/api/v1/fixeddepositaccounts/{accountId}?command=postInterest + POST fixeddepositaccount/1?command=postInterest +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

List Fixed deposit applications/accounts

+

Example Requests:

+
fixeddepositaccounts
+

+
fixeddepositaccounts?fields=name
+
+
+ GET https://Domain Name/api/v1/fixeddepositaccounts + +[ + { + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "Sangamesh N", + "savingsProductId": 3, + "savingsProductName": "FD01", + "fieldOfficerId": 0, + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false, + "prematureClosed": false, + "transferInProgress": false, + "transferOnHold": false + }, + "timeline": { + "submittedOnDate": [ + 2014, + 3, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "interestCompoundingPeriodType": { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountBalance": 0 + }, + "interestFreePeriodApplicable": false, + "preClosurePenalApplicable": false, + "minDepositTerm": 3, + "maxDepositTerm": 4, + "minDepositTermType": { + "id": 2, + "code": "deposit.term.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "maxDepositTermType": { + "id": 3, + "code": "deposit.term.savingsPeriodFrequencyType.years", + "value": "Years" + }, + "depositAmount": 5000, + "maturityAmount": 5140.25, + "maturityDate": [ + 2014, + 9, + 1 + ], + "depositPeriod": 6, + "depositPeriodFrequency": { + "id": 2, + "code": "deposit.period.savingsPeriodFrequencyType.months", + "value": "Months" + } + } +] + + +
+
+ +   +
+
+

Retrieve a fixed deposit application/account:

+

Arguments

+
+
associations
+
optional, Either 'all' or a comma separated list of fixed deposit 'associations' (itemized below).
+

Associations are just extra pieces of data that you might or might not want to retrieve.

+
'all': Gets data related to all associations e.g. ?associations=all.
+
'transactions': Gets data related to transactions on the account e.g. ?associations=transactions
+
'charges':fixed deposit Account charges data.
+
+

Example Requests :

+
fixeddepositaccounts/1
+

+
fixeddepositaccounts/1?associations=all
+
+
+ GET https://DomainName/api/v1/fixeddepositaccounts/{accountId} + +{ + "id": 1, + "accountNo": "FD000023", + "externalId": "FD-23", + "clientId": 1, + "clientName": "Sangamesh N", + "savingsProductId": 3, + "savingsProductName": "FD01", + "fieldOfficerId": 0, + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false, + "prematureClosed": false, + "transferInProgress": false, + "transferOnHold": false + }, + "timeline": { + "submittedOnDate": [ + 2014, + 3, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "interestCompoundingPeriodType": { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "interestFreePeriodApplicable": false, + "preClosurePenalApplicable": false, + "minDepositTerm": 3, + "maxDepositTerm": 4, + "minDepositTermType": { + "id": 2, + "code": "deposit.term.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "maxDepositTermType": { + "id": 3, + "code": "deposit.term.savingsPeriodFrequencyType.years", + "value": "Years" + }, + "depositAmount": 5000, + "maturityAmount": 5140.25, + "maturityDate": [ + 2014, + 9, + 1 + ], + "depositPeriod": 6, + "depositPeriodFrequency": { + "id": 2, + "code": "deposit.period.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountBalance": 0 + }, + "accountChart": { + "id": 4, + "fromDate": [ + 2013, + 10, + 2 + ], + "accountId": 5, + "accountNumber": "FD000023", + "chartSlabs": [ + { + "id": 13, + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 181, + "toPeriod": 365, + "annualInterestRate": 5.5, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + { + "id": 12, + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 1, + "toPeriod": 180, + "annualInterestRate": 5, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + { + "id": 11, + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 366, + "annualInterestRate": 6, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ], + "periodTypes": [ + { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + { + "id": 1, + "code": "interestChartPeriodType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "interestChartPeriodType.months", + "value": "Months" + }, + { + "id": 3, + "code": "interestChartPeriodType.years", + "value": "Years" + } + ] + } +} + +
+
+ +   +
+
+

Modify a fixed deposit application

+

Fixed deposit application can only be modified when in 'Submitted and pending approval' state. Once the application is approved, the details cannot be changed using this method. Specific api endpoints will be created to allow change of interest detail such as rate, compounding period, posting period etc

+
+
+ PUT https://Domain Name/api/v1/fixeddepositaccounts/{accountId} + PUT fixeddepositaccounts/1 +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "depositAmount": 6000 +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "depositAmount": 6000, + "locale": "en" + } +} + +
+
+ +   +
+
+

Delete a fixed deposit application

+

At present we support hard delete of fixed deposit application so long as its in 'Submitted and pending approval' state. One the application is moves past this state, it is not possible to do a 'hard' delete of the application or the account. An API endpoint will be added to close/de-activate the fixed deposit account.

+
+
+ DELETE https://Domain Name/api/v1/fixeddepositaccounts/{accountsId} + DELETE fixeddepositaccounts/1 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 1 +} + +
+
+ + + + +   +
+
+

Recurring Deposit Account:

+

Recurring Deposit accounts are instances of a praticular recurring deposit product created. An application process around the creation of accounts is also supported.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Starting StateActionResultant State
-SubmitSubmitted and pending approval
Submitted and pending approvalRejectClosed - Rejected
Submitted and pending approvalWithdrawn by ApplicantClosed - Withdrawn by Applicant
Submitted and pending approvalApproveApproved
ApprovedUndo ApprovalSubmitted and pending approval
ApprovedActivateActive
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
clientId
The client you are creating the recurring deposit account for. Either clientId or groupId must be provided.
groupId
The group you are creating the recurring deposit account for. Either clientId or groupId must be provided.
productId
The id of the product used for this recurring deposit account. The recurring deposit account inherits the selected currency of the product and possibly other details if not overridden in the recurring deposit account creation request.
accountNo
The account no. associated with this recurring deposit. Is auto generated if not provided at creation time.
externalId
A place to put an external reference for this recurring deposit account useful in migrations e.g. The ID another system uses. If provided, it must be unique.
submittedOnDate
submittedOnDate must be provided when initially creating recurring deposit account application. locale and dateFormat parameters must be provided with this.
interestCompoundingPeriodType
The period at which interest rate is compounded. 1=Daily, 4=Monthly (at end of month)
interestPostingPeriodType
The period at which interest rate is posted or credited to recurring deposit account. The actual crediting or posting transaction is date as occurring on the day after the end of the period. 4=Monthly (at end of month), 5=Quarterly (at end of quarter, 31st Mar, 30th Jun, 30th Sep, 31st Dec), 7=Annually (at end of calendar year 31st Dec)
interestCalculationType
The interest calculation method used: 1=Daily Balance or 2=Average Daily Balance
interestCalculationDaysInYearType
The setting for number of days in year to use: 360=360 Days, 365=365 Days
lockinPeriodFrequency
Optional: If provided, used along with lockinPeriodFrequencyType to indicate the length of time that the recurring deposit account is 'locked in' and withdrawals are not allowed. e.g. 6 Months
lockinPeriodFrequencyType
Optional: If provided, used along with lockinPeriodFrequency to indicate the length of time that the recurring deposit account is 'locked in' and withdrawals are not allowed. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months
recurringDepositAmount
The recurring deposit amount to be deposited regularly on a specified by deposit frequency.
recurringDepositFrequency
Used along with recurringDepositFrequencyTypeId to define the frequency at which recurringDepositAmount to be deposited into RD account. e.g. 6 Months
recurringDepositFrequencyTypeId
Used along with recurringDepositFrequency to define the frequency at which recurringDepositAmount to be deposited into RD account. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months +
depositPeriod
Used along with depositPeriodFrequencyId to define term for which amount is deposited in recurring deposit. e.g. 6 Months
depositPeriodFrequencyId
Used along with depositPeriod to define term for which amount is deposited in recurring deposit. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months +
minDepositTerm
This is used along with minDepositTermTypeId to define allowed minimum deposit term for creating a recurring deposit account using this product. e.g. 6 Months
minDepositTermTypeId
Used along with minDepositTerm to define allowed minimum deposit term for creating a recurring deposit account using this product. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 6 Months +
maxDepositTerm
Optional: If provided, used along with maxDepositTermTypeId to define allowed maximum deposit term for creating a recurring deposit account using this product. e.g. 3 Years
maxDepositTermTypeId
Optional: If provided, used along with maxDepositTerm to define allowed maximum deposit term for creating a recurring deposit account using this product. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. 3 Years +
inMultiplesOfDepositTerm
Optional: If provided, used along with inMultiplesOfDepositTermTypeId to indicate the allowed deposit periods after minimum deposit period. e.g. If inMultiplesOfDepositTerm is 3 Months then the next allowed deposit period after minimum deposit of 6 Months should be 9 Months.
inMultiplesOfDepositTermTypeId
Optional: If provided, used along with inMultiplesOfDepositTerm to indicate the allowed deposit periods after minimum deposit period. 0=Days, 1=Weeks, 2=Months, 3=Years + e.g. If inMultiplesOfDepositTerm is 3 Months then the next allowed deposit period after minimum deposit of 6 Months should be 9 Months. +
preClosurePenalApplicable
Optional: expects boolean value true/false, If provided as true then must provide preClosurePenalInterest and preClosurePenalInterestOnTypeId.
preClosurePenalInterest
Optional: Must provide when preClosurePenalApplicable is true. Used along with preClosurePenalInterestOnTypeId to apply a penalalty on top of applicable interest rate for Pre-mature closure of accounts. e.g. “1%� means 1% less than the interest rate applicable.
preClosurePenalInterestOnTypeId
Optional: Must provide when preClosurePenalApplicable is true. Used along with preClosurePenalInterest to decide what should be the applicable interest rate to which penalalty can be applied on Pre-mature closure of accounts. 1=Whole Term, 2=Till Premature withdrawal e.g. “1%� means 1% less than the interest rate applicable till premature withdrawal.
+
+
+ +   +
+
+

Retrieve recurring Deposit Account Template:

+

This is a convenience resource. It can be useful when building maintenance user interface screens for recurring deposit applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Arguments

+
+
clientId
+
Integer mandatory
+
productId
+
Integer optional
+
If entered, productId, productName and selectedProduct fields are returned.
+
+

Example Requests:

+
fixeddepositaccounts/template?clientId=1
+

+
fixeddepositaccounts/template?clientId=1&productId=1
+
+
+ GET https://Domain Name/api/v1/fixeddepositaccounts/template?clientId={clientId} + +{ + "clientId": 1, + "clientName": "small business", + "productOptions": [ + { + "id": 1, + "name": "Passbook Savings" + } + ] +} + +
+ +
+ GET https://Domain Name/api/v1/fixeddepositaccounts/template?clientId={clientId}&productId={productId} + +{ + "clientId": 1, + "clientName": "small business", + "savingsProductId": 1, + "savingsProductName": "Passbook Savings", + "timeline": {}, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "nominalAnnualInterestRate": 5, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "productOptions": [ + { + "id": 1, + "name": "Passbook Savings" + } + ], + "fieldOfficerOptions": [ + { + "id": 3, + "firstname": "Mrs.", + "lastname": "loanofficerB1", + "displayName": "loanofficerB1, Mrs.", + "officeId": 2, + "officeName": "branch 1", + "isLoanOfficer": true + }, + { + "id": 1, + "firstname": "Mr.", + "lastname": "loanofficerHO", + "displayName": "loanofficerHO, Mr.", + "officeId": 1, + "officeName": "branch 1", + "isLoanOfficer": true + } + ], + "interestCompoundingPeriodTypeOptions": [ + { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + } + ], + "interestPostingPeriodTypeOptions": [ + { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + { + "id": 5, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.quarterly", + "value": "Quarterly" + }, + { + "id": 7, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.annual", + "value": "Annually" + } + ], + "interestCalculationTypeOptions": [ + { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + { + "id": 2, + "code": "savingsInterestCalculationType.averagedailybalance", + "value": "Average Daily Balance" + } + ], + "interestCalculationDaysInYearTypeOptions": [ + { + "id": 360, + "code": "savingsInterestCalculationDaysInYearType.days360", + "value": "360 Days" + }, + { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + } + ], + "lockinPeriodFrequencyTypeOptions": [ + { + "id": 0, + "code": "savings.lockin.savingsPeriodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "savings.lockin.savingsPeriodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "savings.lockin.savingsPeriodFrequencyType.months", + "value": "Months" + }, + { + "id": 3, + "code": "savings.lockin.savingsPeriodFrequencyType.years", + "value": "Years" + } + ], + "withdrawalFeeTypeOptions": [ + { + "id": 1, + "code": "savingsWithdrawalFeesType.flat", + "value": "Flat" + }, + { + "id": 2, + "code": "savingsWithdrawalFeesType.percent.of.amount", + "value": "% of Amount" + } + ], + "chargeOptions": [ + { + "id": 4, + "name": "Savings charge 1", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 200, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "chargepaymentmode.regular" + } + }, + { + "id": 5, + "name": "Savings charge 2", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 300, + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "chargepaymentmode.regular" + } + }, + { + "id": 6, + "name": "Annual fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 50, + "chargeTimeType": { + "id": 6, + "code": "chargeTimeType.annualFee", + "value": "Annual Fee" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + } + }, + { + "id": 7, + "name": "Quarterly fee", + "active": true, + "penalty": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 5, + "chargeTimeType": { + "id": 7, + "code": "chargeTimeType.monthlyFee", + "value": "Monthly Fee" + }, + "chargeAppliesTo": { + "id": 2, + "code": "chargeAppliesTo.savings", + "value": "Savings" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + }, + "feeOnMonthDay": [ + 10, + 5 + ], + "feeInterval": 4 + } + ] +} + +
+
+ +   +
+
+

Submit new recurring deposit application

+
+ + + +
Mandatory Fields
clientId or groupId, productId, submittedOnDate, depositPeriod, depositPeriodFrequencyId, recurringFrequency, recurringFrequencyType, depositAmount,isCalendarInherited, mandatoryRecommendedDepositAmount
+
+ + + +
Optional Fields
accountNo, externalId, fieldOfficerId, expectedFirstDepositOnDate, allowWithdrawal, adjustAdvanceTowardsFuturePayments, isMandatoryDeposit
+
+ + + + +
Inherited from Product (if not provided)
interestCompoundingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency, lockinPeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnTypeId, charts
+
+
+

Minimal request: accountNo auto generated, remaining details inherited from recurring deposit product.

+ POST https://Domain Name/api/v1/recurringdepositaccounts + POST recurringdepositaccounts +Content-Type: application/json +Request Body: +{ + "clientId": 1, + "productId": 1, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "submittedOnDate": "02 June 2014", + "depositPeriod":"20", + "depositPeriodFrequencyId":"1", + "depositAmount":10000, + "isCalendarInherited":false, + "recurringFrequency":"2", + "recurringFrequencyType":1, + "mandatoryRecommendedDepositAmount":"2000" +} + +

Minimal request: accountNo provided (must be unique), remaining details inherited from recurring deposit product.

+ POST recurringdepositaccounts +Content-Type: application/json +Request Body: +{ + "clientId": 1, + "productId": 1, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "submittedOnDate": "02 June 2014", + "depositPeriod":"20", + "depositPeriodFrequencyId":"1", + "depositAmount":10000, + "isCalendarInherited":false, + "recurringFrequency":"2", + "recurringFrequencyType":1, + "mandatoryRecommendedDepositAmount":"2000", + "accountNo": "RD000023", + "externalId": "RD-23", + "expectedFirstDepositOnDate": "02 June 2014", + "allowWithdrawal":false, + "adjustAdvanceTowardsFuturePayments":false, + "isMandatoryDeposit":false + +} + +

Full request: accountNo provided (must be unique), remaining details override details from recurring deposit product (except currency).

+ POST recurringdepositaccounts +Content-Type: application/json +Request Body: +{ + "clientId": 1, + "productId": 1, + "fieldOfficerId": 1, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "submittedOnDate": "02 June 2014", + "depositPeriod":"20", + "depositPeriodFrequencyId":"1", + "depositAmount":10000, + "isCalendarInherited":false, + "recurringFrequency":"2", + "recurringFrequencyType":1, + "mandatoryRecommendedDepositAmount":"2000", + "accountNo": "RD000023", + "externalId": "RD-23", + "expectedFirstDepositOnDate": "02 June 2014", + "allowWithdrawal":false, + "adjustAdvanceTowardsFuturePayments":false, + "isMandatoryDeposit":false, + "interestCompoundingPeriodType": 1, + "interestPostingPeriodType": 4, + "interestCalculationType": 1, + "interestCalculationDaysInYearType": 365, + "lockinPeriodFrequency": 6, + "lockinPeriodFrequencyType": 2, + "charges":[{"id":"1"}] +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Approve recurring deposit application

+

Approves recurring deposit application so long as its in 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=approve + POST recurringdepositaccounts/1?command=approve +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "01 March 2014" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 200, + "code": "savingsAccountStatusType.approved", + "value": "Approved", + "submittedAndPendingApproval": false, + "approved": true, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "approvedOnDate": "01 March 2014" + } +} + +
+
+ +   +
+
+

Undo approval recurring deposit application

+

Will move 'approved' recurring deposit application back to 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=undoApproval + POST recurringdepositaccounts/1?command=undoApproval +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "approvedOnDate": "" + } +} + +
+
+ +   +
+
+

Reject recurring deposit application

+

Rejects recurring deposit application so long as its in 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=reject + POST recurringdepositaccounts/1?command=reject +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "03 March 2014" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 500, + "code": "savingsAccountStatusType.rejected", + "value": "Rejected", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": true, + "withdrawnByApplicant": false, + "active": false, + "closed": true + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "rejectedOnDate": "03 March 2014", + "closedOnDate": "03 March 2014" + } +} + +
+
+ +   +
+
+

Withdraw recurring deposit application

+

Used when an applicant withdraws from the recurring deposit application. It must be in 'Submitted and pending approval' state.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{savingsId}?command=withdrawnByApplicant + POST recurringdepositaccounts/1?command=withdrawnByApplicant +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "withdrawnOnDate": "03 March 2014" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 400, + "code": "savingsAccountStatusType.withdrawn.by.applicant", + "value": "Withdrawn by applicant", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": true, + "active": false, + "closed": true + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "withdrawnOnDate": "03 March 2014", + "closedOnDate": "03 March 2014" + } +} + +
+
+ +   +
+
+

Activate a recurring deposit account

+

Results in an approved recurring deposit application being converted into an 'active' recurring deposit account.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=activate + POST recurringdepositaccounts/1?command=activate +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "activatedOnDate": "01 March 2013" +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 300, + "code": "savingsAccountStatusType.active", + "value": "Active", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": true, + "closed": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "activatedOnDate": "01 March 2013" + } +} + +
+
+ +   +
+
+

Update the recommended deposit amount for a recurring deposit account

+

Updates the recommended deposit amount for a RD account as on the effective date.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=updateDepositAmount + POST recurringdepositaccounts/4?command=updateDepositAmount +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "effectiveDate": "01 Dec 2014" + "mandatoryRecommendedDepositAmount": 398 +} + + + +{ + "officeId": 1, + "clientId": 6, + "savingsId": 4, + "resourceId": 4, + "changes": + { + "mandatoryRecommendedDepositAmount": 398 + } +} + + +
+
+ + +   +
+
+

Close a recurring deposit account

+

Results in a Matured recurring deposit account being converted into a 'closed' recurring deposit account.

On account close allowed actions are.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Action on CloseResult
Withdraw Deposit                     Matured amount withdrawn and paid to client
Transfer to SavingsMatured amount transfered to specified savings account.
                     
Re-InvestCreate new Fixed deposit application with matured amount as deposit amount.
+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=close + POST recurringdepositaccounts/1?command=close +Content-Type: application/json +Request Body: + { + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closedOnDate":"19 April 2014", + "note":"Closing and transfering amount to savings", + "onAccountClosureId":"100", + "transferDescription":"Transfered matured amount to savings account" + } + + +{ +"officeId":1, +"clientId":1, +"savingsId":5, +"resourceId":5, +"changes":{ + "status":{ + "id":600, + "code":"savingsAccountStatusType.closed", + "value":"Closed", + "submittedAndPendingApproval":false, + "approved":false, + "rejected":false, + "withdrawnByApplicant":false, + "active":false, + "closed":true + }, + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "closedOnDate":"19 April 2014", + "note":"Closing and transfering amount to savings" + } +} + +
+
+ +   +
+
+

Premature Close a recurring deposit account

+

Results in an Active recurring deposit account being converted into a 'Premature Closed' recurring deposit account with options to withdraw prematured amount. (premature amount is calculated using interest rate chart applicable along with penal interest if any.)

On account premature closure allowed actions are.

+ + + + + + + + + + + + + + + + + +
Action on Premature CloseResult
Withdraw Deposit                     Matured amount withdrawn and paid to client
Transfer to SavingsMatured amount transfered to a savings account.
+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=prematureClose + POST recurringdepositaccounts/1?command=prematureClose +Content-Type: application/json +Request Body: + { + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closedOnDate":"19 April 2014", + "note":"Close and transfer amount to savings", + "onAccountClosureId":"200", + "toSavingsAccountId":1, + "transferDescription":"Transfered matured amount to savings account" + } + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "status": { + "id": 700, + "code": "savingsAccountStatusType.pre.mature.closure", + "value": "Premature Closed", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false, + "prematureClosed": true, + "transferInProgress": false, + "transferOnHold": false + }, + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "closedOnDate": "19 April 2014", + "note": "Close and transfer amount to savings" + } +} + +
+
+ +   +
+
+

Calculate Premature amount on Recurring deposit account

+

Calculate premature amount on recurring deposit till premature close date. Premature amount is calculated based on interest chart and penal interest applicable if any.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=calculatePrematureAmount + POST recurringdepositaccounts/1?command=calculatePrematureAmount +Content-Type: application/json +Request Body: + { + "dateFormat":"dd MMMM yyyy", + "locale":"en", + "closedOnDate":"19 April 2014" + } + + +{ + "maturityAmount": 100.65, + "savingsAccounts": [ + { + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "Sangamesh N", + "savingsProductId": 1, + "savingsProductName": "sa", + "fieldOfficerId": 0, + "status": { + "id": 300, + "code": "savingsAccountStatusType.active", + "value": "Active", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": true, + "closed": false, + "prematureClosed": false, + "transferInProgress": false, + "transferOnHold": false + }, + "timeline": { + "submittedOnDate": [ + 2014, + 1, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "approvedOnDate": [ + 2014, + 1, + 1 + ], + "approvedByUsername": "mifos", + "approvedByFirstname": "App", + "approvedByLastname": "Administrator", + "activatedOnDate": [ + 2014, + 1, + 1 + ] + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "nominalAnnualInterestRate": 5, + "interestCompoundingPeriodType": { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "minRequiredOpeningBalance": 5000, + "withdrawalFeeForTransfers": false, + "allowOverdraft": false, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "totalDeposits": 13353.41, + "totalInterestEarned": 107.79, + "totalInterestPosted": 76.74, + "accountBalance": 13430.15 + } + } + ], + "onAccountClosureOptions": [ + { + "id": 100, + "code": "depositAccountClosureType.withdrawDeposit", + "value": "Withdra Deposit" + }, + { + "id": 200, + "code": "depositAccountClosureType.transferToSavings", + "value": "Transfer to Savings" + }, + { + "id": 300, + "code": "depositAccountClosureType.reinvest", + "value": "Re-Invest" + } + ], + "paymentTypeOptions": [], + "id": 12, + "depositType": { + "id": 300, + "code": "depositAccountType.recurringDeposit", + "value": "Recurring Deposit" + } +} + +
+
+ +   +
+
+

Calculate Interest on recurring Deposit Account

+

+ Calculates interest earned on a recurring deposit account based on todays date. It does not attempt to post or credit the interest on the account. That is responsibility of the Post Interest API that will likely be called by overnight process. +

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=calculateInterest + POST recurringdepositaccounts/1?command=calculateInterest +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Post Interest on recurring Deposit Account

+

+ Calculates and Posts interest earned on a recurring deposit account based on todays date and whether an interest posting or crediting event is due. +

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountId}?command=postInterest + POST recurringdepositaccounts/1?command=postInterest +Content-Type: application/json +Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 1, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

List Fixed deposit applications/accounts

+

Example Requests:

+
recurringdepositaccounts
+

+
recurringdepositaccounts?fields=name
+
+
+ GET https://Domain Name/api/v1/recurringdepositaccounts + +[ + { + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "Sangamesh N", + "savingsProductId": 3, + "savingsProductName": "RD01", + "fieldOfficerId": 0, + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false, + "prematureClosed": false, + "transferInProgress": false, + "transferOnHold": false + }, + "timeline": { + "submittedOnDate": [ + 2014, + 3, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "interestCompoundingPeriodType": { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountBalance": 0 + }, + "depositAmount": 1150, + "maturityAmount": 252.59, + "maturityDate": [ + 2014, + 4, + 3 + ], + "recurringDepositAmount": 100, + "recurringDepositFrequency": 1, + "recurringDepositFrequencyType": { + "id": 2, + "code": "recurring.deposit.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "preClosurePenalApplicable": false, + "minDepositTerm": 3, + "maxDepositTerm": 4, + "minDepositTermType": { + "id": 2, + "code": "deposit.term.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "maxDepositTermType": { + "id": 3, + "code": "deposit.term.savingsPeriodFrequencyType.years", + "value": "Years" + }, + "depositAmount": 5000, + "maturityAmount": 5140.25, + "maturityDate": [ + 2014, + 9, + 1 + ], + "depositPeriod": 6, + "depositPeriodFrequency": { + "id": 2, + "code": "deposit.period.savingsPeriodFrequencyType.months", + "value": "Months" + } + } +] + + +
+
+ +   +
+
+

Retrieve a recurring deposit application/account:

+

Arguments

+
+
associations
+
optional, Either 'all' or a comma separated list of recurring deposit 'associations' (itemized below).
+

Associations are just extra pieces of data that you might or might not want to retrieve.

+
'all': Gets data related to all associations e.g. ?associations=all.
+
'transactions': Gets data related to transactions on the account e.g. ?associations=transactions
+
'charges':recurring deposit Account charges data.
+
+

Example Requests :

+
recurringdepositaccounts/1
+

+
recurringdepositaccounts/1?associations=all
+
+
+ GET https://DomainName/api/v1/recurringdepositaccounts/{accountId} + +{ + "id": 1, + "accountNo": "RD000023", + "externalId": "RD-23", + "clientId": 1, + "clientName": "Sangamesh N", + "savingsProductId": 3, + "savingsProductName": "RD01", + "fieldOfficerId": 0, + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false, + "prematureClosed": false, + "transferInProgress": false, + "transferOnHold": false + }, + "timeline": { + "submittedOnDate": [ + 2014, + 3, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "interestCompoundingPeriodType": { + "id": 4, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "preClosurePenalApplicable": false, + "minDepositTerm": 3, + "maxDepositTerm": 4, + "minDepositTermType": { + "id": 2, + "code": "deposit.term.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "maxDepositTermType": { + "id": 3, + "code": "deposit.term.savingsPeriodFrequencyType.years", + "value": "Years" + }, + "recurringDepositAmount": 100, + "recurringDepositFrequency": 1, + "expectedFirstDepositOnDate": [ + 2014, + 4, + 2 + ], + "recurringDepositFrequencyType": { + "id": 2, + "code": "recurring.deposit.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "depositPeriod": 6, + "depositPeriodFrequency": { + "id": 2, + "code": "deposit.period.savingsPeriodFrequencyType.months", + "value": "Months" + }, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 1, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountBalance": 0 + }, + "accountChart": { + "id": 4, + "fromDate": [ + 2013, + 10, + 2 + ], + "accountId": 5, + "accountNumber": "RD000023", + "chartSlabs": [ + { + "id": 13, + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 181, + "toPeriod": 365, + "annualInterestRate": 5.5, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + { + "id": 12, + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 1, + "toPeriod": 180, + "annualInterestRate": 5, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + { + "id": 11, + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 366, + "annualInterestRate": 6, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ], + "periodTypes": [ + { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + { + "id": 1, + "code": "interestChartPeriodType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "interestChartPeriodType.months", + "value": "Months" + }, + { + "id": 3, + "code": "interestChartPeriodType.years", + "value": "Years" + } + ] + } +} + +
+
+ +   +
+
+

Modify a recurring deposit application

+

Recurring deposit application can only be modified when in 'Submitted and pending approval' state. Once the application is approved, the details cannot be changed using this method. Specific api endpoints will be created to allow change of interest detail such as rate, compounding period, posting period etc

+
+
+ PUT https://Domain Name/api/v1/recurringdepositaccounts/{accountId} + PUT recurringdepositaccounts/1 +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "depositAmount": 6000 +} + + +{ + "officeId": 2, + "clientId": 1, + "savingsId": 1, + "resourceId": 1, + "changes": { + "depositAmount": 6000, + "locale": "en" + } +} + +
+
+ +   +
+
+

Delete a recurring deposit application

+

At present we support hard delete of recurring deposit application so long as its in 'Submitted and pending approval' state. One the application is moves past this state, it is not possible to do a 'hard' delete of the application or the account. An API endpoint will be added to close/de-activate the recurring deposit account.

+
+
+ DELETE https://Domain Name/api/v1/recurringdepositaccounts/{accountsId} + DELETE recurringdepositaccounts/1 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 1 +} + +
+
+   +
+
+

Recurring Deposit Account Transactions:

+

Transactions possible on a recurring deposit account.

+ + + + + + + + +
Field Descriptions
transactionDate
The date of the transaction.
transactionAmount
The amount of the transaction.
+
+
+ +   +
+
+

Retrieve Recurring Deposit Account Transaction Template:

+

This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Requests:

+
recurringdepositaccounts/1/transactions/template?command=deposit
+
+
recurringdepositaccounts/1/transactions/template?command=withdrawal
+
+
+ GET https://Domain Name/api/v1/recurringdepositaccounts/{accountId}/transactions/template?command=deposit + + +{ + "id": 1, + "transactionType": { + "id": 1, + "code": "savingsAccountTransactionType.deposit", + "value": "Deposit", + "deposit": true, + "withdrawal": false, + "interestPosting": false, + "feeDeduction": false, + "initiateTransfer": false, + "approveTransfer": false, + "withdrawTransfer": false, + "rejectTransfer": false, + "overdraftInterest": false, + "writtenoff": false, + "overdraftFee": true + }, + "accountId": 1, + "accountNo": "000000001", + "date": [ + 2014, + 6, + 25 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 4, + "inMultiplesOf": 100, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100000.000000, + "reversed": false, + "paymentTypeOptions": [] +} + +
+
+ +  +
+
+

Retrieve Recurring Deposit Account Transaction:

+

Example Requests:

+
recurringdepositaccounts/1/transactions/1
+
+
+
+ GET https://Domain Name/api/v1/recurringdepositaccounts/{accountId}/transactions/{transactionId} + + +{ + "id": 1, + "transactionType": { + "id": 2, + "code": "savingsAccountTransactionType.withdrawal", + "value": "Withdrawal", + "deposit": false, + "withdrawal": true, + "interestPosting": false, + "feeDeduction": false + }, + "accountId": 1, + "accountNo": "000000001", + "date": [ + 2013, + 8, + 7 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "paymentDetailData": { + "id": 62, + "paymentType": { + "id": 11, + "name": "cash" + }, + "accountNumber": "", + "checkNumber": "", + "routingCode": "", + "receiptNumber": "", + "bankNumber": "" + }, + "amount": 5000, + "runningBalance": 0, + "reversed": true +} + +
+
+ +   +
+
+

Deposit Transaction

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountsId}/transactions?command=deposit + POST recurringdepositaccounts/1/transactions?command=deposit +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "27 May 2013", + "transactionAmount": "500", + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 47, + "changes": { + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ +   +
+
+

Withdrawal Transaction

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountsId}/transactions?command=withdrawal + POST recurringdepositaccounts/1/transactions?command=withdrawal +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "27 May 2013", + "transactionAmount": "500", + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 48, + "changes": { + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ +   +
+
+

Adjust Transaction

+

This command modifies the given transaction.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountsId}/transactions/{transactionId}?command=modify + POST recurringdepositaccounts/1/transactions/1?command=modify +Content-Type: application/json +No Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "transactionDate": "27 May 2013", + "transactionAmount": "500", + "paymentTypeId": "14", + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 48, + "changes": { + "accountNumber": "acc123", + "checkNumber": "che123", + "routingCode": "rou123", + "receiptNumber": "rec123", + "bankNumber": "ban123" + } +} + +
+
+ +   +
+
+

Undo transaction

+

This command reverses the given transaction.

+
+
+ POST https://Domain Name/api/v1/recurringdepositaccounts/{accountsId}/transactions/{transactionId}?command=undo + POST recurringdepositaccounts/1/transactions/1?command=undo +Content-Type: application/json +No Request Body: +{ +} + + +{ + "officeId": 1, + "clientId": 2, + "savingsId": 1, + "resourceId": 1 +} + +
+
+ + + +  +
+
+

Account Transfers:

+

Ability to be able to transfer monetary funds from one account to another.

+

Note: At present only savings account to savings account transfers are supported.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Mandatory Parameters
fromOfficeId
The id of the office/branch from which the transfer is made.
fromClientId
The id of the client from which the transfer is made.
fromAccountType
The type of account from which the transfer is made. 1=Loan Account, 2=Savings Account
fromAccountId
The id of the account from which the transfer is made.
toOfficeId
The id of the office/branch to which the transfer is made.
toClientId
The id of the client to which the transfer is made.
toAccountType
The type of account to which the transfer is made. 1=Loan Account, 2=Savings Account
toAccountId
The id of the account to which the transfer is made. The accouont must be active and must have the same currency as that of the selected fromAccountId.
transferDate
The date of the transfer. Requires dateFormat and locale parameters.
transferAmount
The amount of the transfer. Requires locale parameter.
transferDescription
Description of the transfer itself.
+
+
+ +   +
+
+

Retrieve Account Transfer Template:

+

This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Requests:

+
accounttransfers/template?fromAccountType=2&fromOfficeId=1
+
+
accounttransfers/template?fromAccountType=2&fromOfficeId=1&fromClientId=1
+
+
accounttransfers/template?fromClientId=1&fromAccountType=2&fromAccountId=1
+
+
+
+ GET https://Domain Name/api/v1/accounttransfers/template?fromAccountType=2&fromOfficeId=1 + + +{ + "transferAmount": 0, + "transferDate": [ + 2013, + 8, + 15 + ], + "fromOffice": { + "id": 1, + "name": "HO", + "nameDecorated": "HO", + "externalId": "1", + "openingDate": [ + 2009, + 1, + 1 + ], + "hierarchy": "." + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromOfficeOptions": [ + { + "id": 1, + "name": "HO", + "nameDecorated": "HO" + }, + { + "id": 2, + "name": "Branch 1", + "nameDecorated": "....Branch 1" + } + ], + "fromClientOptions": [ + { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + { + "id": 3, + "displayName": "Third client", + "officeId": 1, + "officeName": "HO" + } + ], + "fromAccountTypeOptions": [ + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + } + ], + "toOfficeOptions": [ + { + "id": 1, + "name": "HO", + "nameDecorated": "HO" + }, + { + "id": 2, + "name": "Branch 1", + "nameDecorated": "....Branch 1" + } + ], + "toAccountTypeOptions": [ + { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + }, + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + } + ] +} + +
+ +
+ GET https://Domain Name/api/v1/accounttransfers/template?fromAccountType=2&fromOfficeId=1&fromClientId=1 + + +{ + "transferAmount": 0, + "transferDate": [ + 2013, + 8, + 15 + ], + "fromOffice": { + "id": 1, + "name": "HO", + "nameDecorated": "HO", + "externalId": "1", + "openingDate": [ + 2009, + 1, + 1 + ], + "hierarchy": "." + }, + "fromClient": { + "id": 1, + "accountNo": "000000001", + "status": { + "id": 300, + "code": "clientStatusType.active", + "value": "Active" + }, + "active": true, + "activationDate": [ + 2013, + 3, + 1 + ], + "fullname": "Small shop", + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO", + "groups": [] + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromOfficeOptions": [ + { + "id": 1, + "name": "HO", + "nameDecorated": "HO" + }, + { + "id": 2, + "name": "Branch 1", + "nameDecorated": "....Branch 1" + } + ], + "fromClientOptions": [ + { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + { + "id": 3, + "displayName": "Third client", + "officeId": 1, + "officeName": "HO" + } + ], + "fromAccountTypeOptions": [ + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + } + ], + "fromAccountOptions": [ + { + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "Small shop", + "productId": 1, + "productName": "Passbook", + "fieldOfficerId": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + { + "id": 3, + "accountNo": "000000003", + "clientId": 1, + "clientName": "Small shop", + "productId": 2, + "productName": "Shilling product", + "fieldOfficerId": 0, + "currency": { + "code": "KES", + "name": "Kenyan Shilling", + "decimalPlaces": 0, + "inMultiplesOf": 0, + "displaySymbol": "KSh", + "nameCode": "currency.KES", + "displayLabel": "Kenyan Shilling (KSh)" + } + } + ], + "toOfficeOptions": [ + { + "id": 1, + "name": "HO", + "nameDecorated": "HO" + }, + { + "id": 2, + "name": "Branch 1", + "nameDecorated": "....Branch 1" + } + ], + "toAccountTypeOptions": [ + { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + }, + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + } + ] +} + +
+ +
+ GET https://Domain Name/api/v1/accounttransfers/template?fromClientId=1&fromAccountType=2&fromAccountId=1 + + +{ + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "transferAmount": 0, + "transferDate": [ + 2013, + 8, + 15 + ], + "fromOffice": { + "id": 1, + "name": "HO", + "nameDecorated": "HO", + "externalId": "1", + "openingDate": [ + 2009, + 1, + 1 + ], + "hierarchy": "." + }, + "fromClient": { + "id": 1, + "accountNo": "000000001", + "status": { + "id": 300, + "code": "clientStatusType.active", + "value": "Active" + }, + "active": true, + "activationDate": [ + 2013, + 3, + 1 + ], + "fullname": "Small shop", + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO", + "groups": [] + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "Small shop", + "productId": 1, + "productName": "Passbook", + "fieldOfficerId": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + "fromOfficeOptions": [ + { + "id": 1, + "name": "HO", + "nameDecorated": "HO" + }, + { + "id": 2, + "name": "Branch 1", + "nameDecorated": "....Branch 1" + } + ], + "fromClientOptions": [ + { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + { + "id": 3, + "displayName": "Third client", + "officeId": 1, + "officeName": "HO" + } + ], + "fromAccountTypeOptions": [ + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + } + ], + "fromAccountOptions": [ + { + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "Small shop", + "productId": 1, + "productName": "Passbook", + "fieldOfficerId": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + { + "id": 3, + "accountNo": "000000003", + "clientId": 1, + "clientName": "Small shop", + "productId": 2, + "productName": "Shilling product", + "fieldOfficerId": 0, + "currency": { + "code": "KES", + "name": "Kenyan Shilling", + "decimalPlaces": 0, + "inMultiplesOf": 0, + "displaySymbol": "KSh", + "nameCode": "currency.KES", + "displayLabel": "Kenyan Shilling (KSh)" + } + } + ], + "toOfficeOptions": [ + { + "id": 1, + "name": "HO", + "nameDecorated": "HO" + }, + { + "id": 2, + "name": "Branch 1", + "nameDecorated": "....Branch 1" + } + ], + "toAccountTypeOptions": [ + { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + }, + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + } + ] +} + +
+ +
+ +   +
+
+

Create new Transfer

+

Ability to create new transfer of monetary funds from one account to another.

+
+
+ POST https://Domain Name/api/v1/accounttransfers + POST accounttransfers/ +Content-Type: application/json +No Request Body: +{ +"fromOfficeId": 1, +"fromClientId": 1, +"fromAccountType": 2, +"fromAccountId": 1, +"toOfficeId": 1, +"toClientId": 1, +"toAccountType": 2, +"toAccountId": 2, +"dateFormat": "dd MMMM yyyy", +"locale": "en", +"transferDate": "01 August 2011", +"transferAmount": "112.45", +"transferDescription": "A description of the transfer" +} + + +{ + "savingsId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

List account transfers

+

Example Requests:

+
accounttransfers
+
+
+
+ GET https://Domain Name/api/v1/accounttransfers + +{ + "totalFilteredRecords": 4, + "pageItems": [ + { + "id": 1, + "reversed": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "transferAmount": 200, + "transferDate": [ + 2013, + 4, + 1 + ], + "transferDescription": "pay off loan from savings.", + "fromOffice": { + "id": 1, + "name": "HO" + }, + "fromClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 1, + "accountNo": "000000001" + }, + "toOffice": { + "id": 1, + "name": "HO" + }, + "toClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "toAccountType": { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + }, + "toAccount": { + "id": 1, + "accountNo": "000000001" + } + }, + { + "id": 2, + "reversed": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "transferAmount": 112.45, + "transferDate": [ + 2013, + 6, + 1 + ], + "transferDescription": "A description of the transfer", + "fromOffice": { + "id": 1, + "name": "HO" + }, + "fromClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 1, + "accountNo": "000000001" + }, + "toOffice": { + "id": 1, + "name": "HO" + }, + "toClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "toAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "toAccount": { + "id": 3, + "accountNo": "000000003" + } + }, + { + "id": 3, + "reversed": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "transferAmount": 112.45, + "transferDate": [ + 2013, + 6, + 1 + ], + "transferDescription": "A description of the transfer", + "fromOffice": { + "id": 1, + "name": "HO" + }, + "fromClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 1, + "accountNo": "000000001" + }, + "toOffice": { + "id": 1, + "name": "HO" + }, + "toClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "toAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "toAccount": { + "id": 3, + "accountNo": "000000003" + } + }, + { + "id": 4, + "reversed": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "transferAmount": 112.45, + "transferDate": [ + 2013, + 6, + 1 + ], + "transferDescription": "A description of the transfer", + "fromOffice": { + "id": 1, + "name": "HO" + }, + "fromClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 1, + "accountNo": "000000001" + }, + "toOffice": { + "id": 1, + "name": "HO" + }, + "toClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "toAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "toAccount": { + "id": 3, + "accountNo": "000000003" + } + } + ] +} + +
+
+ +   +
+
+

Retrieve account transfer:

+

Example Requests :

+
accounttransfers/1
+
+
+
+ GET https://DomainName/api/v1/accounttransfers/{transferId} + +{ + "id": 1, + "reversed": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "transferAmount": 200, + "transferDate": [ + 2013, + 4, + 1 + ], + "transferDescription": "pay off loan from savings.", + "fromOffice": { + "id": 1, + "name": "HO" + }, + "fromClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 1, + "accountNo": "000000001" + }, + "toOffice": { + "id": 1, + "name": "HO" + }, + "toClient": { + "id": 1, + "displayName": "Small shop", + "officeId": 1, + "officeName": "HO" + }, + "toAccountType": { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + }, + "toAccount": { + "id": 1, + "accountNo": "000000001" + } +} + +
+
+ +   +
+
+

Retrieve Refund of an Active Loan by Transfer Template:

+

Example Requests :

+
accounttransfers/templateRefundByTransfer?fromAccountId=2&fromAccountType=1& + toAccountId=1&toAccountType=2&toClientId=1&toOfficeId=1
+
+
+
+ GET https://DomainName/api/v1/accounttransfers/templateRefundByTransfer + +{ +   "currency": { +      "code": "USD", +      "name": "US Dollar", +      "decimalPlaces": 0, +      "inMultiplesOf": 0, +      "displaySymbol": "$", +      "nameCode": "currency.USD", +      "displayLabel": "US Dollar ($)" +   }, +   "transferAmount": 130, +   "transferDate": [ +      2014, +      11, +      1 +   ], +   "fromOffice": { +      "id": 1, +      "name": "Head Office", +      "nameDecorated": "Head Office", +      "externalId": "1", +      "openingDate": [ +         2009, +         1, +         1 +      ], +      "hierarchy": "." +   }, +   "fromClient": { +      "id": 1, +      "accountNo": "000000001", +      "status": { +         "id": 300, +         "code": "clientStatusType.active", +         "value": "Active" +      }, +      "active": true, +      "activationDate": [ +         2012, +         2, +         1 +      ], +      "firstname": "Daniel", +      "lastname": "Owusu", +      "displayName": "Daniel Owusu", +      "gender": {}, +      "clientType": {}, +      "clientClassification": {}, +      "officeId": 1, +      "officeName": "Head Office", +      "timeline": { +         "submittedOnDate": [ +            2012, +            2, +            1 +         ], +         "submittedByUsername": "mifos", +         "submittedByFirstname": "App", +         "submittedByLastname": "Administrator", +         "activatedOnDate": [ +            2012, +            2, +            1 +         ], +         "activatedByUsername": "mifos", +         "activatedByFirstname": "App", +         "activatedByLastname": "Administrator" +      }, +      "groups": [] +   }, +   "fromAccountType": { +      "id": 1, +      "code": "accountType.loan", +      "value": "Loan Account" +   }, +   "fromAccount": { +      "id": 2, +      "accountNo": "000000002", +      "clientId": 1, +      "clientName": "Daniel Owusu", +      "productId": 1, +      "productName": "CTRL", +      "fieldOfficerId": 0, +      "currency": { +         "code": "USD", +         "name": "US Dollar", +         "decimalPlaces": 0, +         "inMultiplesOf": 0, +         "displaySymbol": "$", +         "nameCode": "currency.USD", +         "displayLabel": "US Dollar ($)" +      }, +      "amtForTransfer": 130 +   }, +   "toOffice": { +      "id": 1, +      "name": "Head Office", +      "nameDecorated": "Head Office", +      "externalId": "1", +      "openingDate": [ +         2009, +         1, +         1 +      ], +      "hierarchy": "." +   }, +   "toClient": { +      "id": 1, +      "displayName": "Daniel Owusu", +      "officeId": 1, +      "officeName": "Head Office" +   }, +   "toAccountType": { +      "id": 2, +      "code": "accountType.savings", +      "value": "Savings Account" +   }, +   "toAccount": { +      "id": 1, +      "accountNo": "000000001", +      "clientId": 1, +      "clientName": "Daniel Owusu", +      "productId": 1, +      "productName": "TEST", +      "fieldOfficerId": 0, +      "currency": { +         "code": "USD", +         "name": "US Dollar", +         "decimalPlaces": 0, +         "inMultiplesOf": 0, +         "displaySymbol": "$", +         "nameCode": "currency.USD", +         "displayLabel": "US Dollar ($)" +      } +   }, +   "fromOfficeOptions": [ +      { +         "id": 1, +         "name": "Head Office", +         "nameDecorated": "Head Office" +      } +   ], +   "fromClientOptions": [ +      { +         "id": 1, +         "displayName": "Daniel Owusu", +         "officeId": 1, +         "officeName": "Head Office" +      } +   ], +   "fromAccountTypeOptions": [ +      { +         "id": 2, +         "code": "accountType.savings", +         "value": "Savings Account" +      }, +      { +         "id": 1, +         "code": "accountType.loan", +         "value": "Loan Account" +      } +   ], +   "fromAccountOptions": [ +      { +         "id": 2, +         "accountNo": "000000002", +         "clientId": 1, +         "clientName": "Daniel Owusu", +         "productId": 1, +         "productName": "CTRL", +         "fieldOfficerId": 0, +         "currency": { +            "code": "USD", +            "name": "US Dollar", +            "decimalPlaces": 0, +            "inMultiplesOf": 0, +            "displaySymbol": "$", +            "nameCode": "currency.USD", +            "displayLabel": "US Dollar ($)" +         } +      } +   ], +   "toOfficeOptions": [ +      { +         "id": 1, +         "name": "Head Office", +         "nameDecorated": "Head Office" +      } +   ], +   "toClientOptions": [ +      { +         "id": 1, +         "displayName": "Daniel Owusu", +         "officeId": 1, +         "officeName": "Head Office" +      } +   ], +   "toAccountTypeOptions": [ +      { +         "id": 2, +         "code": "accountType.savings", +         "value": "Savings Account" +      } +   ], +   "toAccountOptions": [ +      { +         "id": 1, +         "accountNo": "000000001", +         "clientId": 1, +         "clientName": "Daniel Owusu", +         "productId": 1, +         "productName": "TEST", +         "fieldOfficerId": 0, +         "currency": { +            "code": "USD", +            "name": "US Dollar", +            "decimalPlaces": 0, +            "inMultiplesOf": 0, +            "displaySymbol": "$", +            "nameCode": "currency.USD", +            "displayLabel": "US Dollar ($)" +         } +      } +   ] +} + +
+
+ + +   +
+
+

Refund of an Active Loan by Transfer

+

Ability to refund an active loan by transferring to a savings account.

+
+
+ POST https://Domain Name/api/v1/accounttransfers + POST refundByTransfer/ +Content-Type: application/json +No Request Body: +{ + "fromAccountId": "2", + "fromAccountType": 1, + "toOfficeId": 1, + "toClientId": 1, + "toAccountType": 2, + "toAccountId": 1, + "transferAmount": 130, + "transferDate": "31 October 2014", + "transferDescription": "Transfer refund to my savings account", + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "fromClientId": 1, + "fromOfficeId": 1 + +} + + +{ + "savingsId": 1, + "resourceId": 1 +} + +
+
+ + + + +  +
+
+

Standing Instructions

+

Standing instructions (or standing orders) refer to instructions a bank account holder ("the payer") gives to his or her bank to pay a set amount at regular intervals to another's ("the payee's") account.

+

Note: At present only savings account to savings account and savings account to Loan account transfers are permitted.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Mandatory Parameters
name
A name for this Standing Instruction
fromOfficeId
The id of the office/branch from which the transfer is made.
fromClientId
The id of the client (payer) who makes the transfer
fromAccountType
The type of account from which the transfer is made. 1=Loan Account, 2=Savings Account
fromAccountId
The id of the account from which the transfer is made.
toOfficeId
The id of the office/branch to which the transfer is made.
toClientId
The id of the client (payee), to whose account the transfer is made.
toAccountType
The type of account to which the transfer is made. 1=Loan Account, 2=Savings Account
toAccountId
The id of the account to which the transfer is made. The account must be active and must be in the same currency as that of the selected fromAccountId.
priority
The priority of instruction while executing instructions. 1= URGENT,2 = HIGH, 3 = MEDIUM, 4 = LOW
transferType
Identifies the source and destination account types. 1=Account Transfer(savings to savings), 2=Loan Repayment
instructionType
Determines the amount to be transferred while executing a standing instruction. 1. FIXED, 2.DUES
status
The Standing instruction state. 1. Active, 2.Disabled, 3.Deleted
recurrenceType
Determines the recurrence of this standing instruction, can be either 1. Periodic or 2.As per dues
validFrom
The Standing instruction's Start date.
+ + + + + + + + + + + + + + + + + + + +
Optional Parameters
amount
Transfer amount while running the instruction. must be provided if the selected instructionType is fixed
validTill
The Standing instruction's end date.
recurrenceFrequency
The recurrence frequency of a Standing instruction's execution. Must be provided if the recurrenceType is Periodic. 0 = days, 1 = weekly, 2 = monthly, 3 = yearly
recurrenceInterval
The recurrence interval of a standing instruction execution, determines the recurrence schedule when combined with recurrenceFrequency. Must be provided if the recurrenceType is periodic
recurrenceOnMonthDay
The Month and Day of recurrence. Must be provided if the recurrenceFrequency is monthly or yearly
+
+
+ +   +
+
+

Retrieve Standing Instruction Template:

+

This is a convenience resource. It can be useful when building maintenance user interface screens for client applications. The template data returned consists of any or all of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Requests:

+
standinginstructions/template?fromAccountType=2&fromOfficeId=1
+
+
standinginstructions/template?fromAccountType=2&fromOfficeId=1&fromClientId=1&transferType=1
+
+
standinginstructions/template?fromClientId=1&fromAccountType=2&fromAccountId=1&transferType=1
+
+
+
+ GET https://Domain Name/api/v1/standinginstructions/template?fromAccountType=2&fromOfficeId=1 + + + { + "fromOffice": { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office", + "externalId": "1", + "openingDate": [ + 2009, + 1, + 1 + ], + "hierarchy": "." + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromOfficeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + } + ], + "fromClientOptions": [ + { + "id": 1, + "displayName": "Client_FirstName_2VRAG Client_LastName_9QCY", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 20, + "displayName": "Client_FirstName_9KYLE Client_LastName_I0GJ", + "officeId": 1, + "officeName": "Head Office" + } + ], + "fromAccountTypeOptions": [ + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + } + ], + "toOfficeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + } + ], + "toAccountTypeOptions": [ + { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + }, + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + } + ], + "transferTypeOptions": [ + { + "id": 1, + "code": "accountTransferType.account.transfer", + "value": "Account Transfer" + }, + { + "id": 2, + "code": "accountTransferType.loan.repayment", + "value": "Loan Repayment" + } + ], + "statusOptions": [ + { + "id": 1, + "code": "standingInstructionStatus.active", + "value": "Active" + }, + { + "id": 2, + "code": "standingInstructionStatus.disabled", + "value": "Disabled" + } + ], + "instructionTypeOptions": [ + { + "id": 1, + "code": "standingInstructionType.fixed", + "value": "Fixed" + }, + { + "id": 2, + "code": "standingInstructionType.dues", + "value": "Dues" + } + ], + "priorityOptions": [ + { + "id": 1, + "code": "standingInstructionPriority.urgent", + "value": "Urgent Priority" + }, + { + "id": 2, + "code": "standingInstructionPriority.high", + "value": "High Priority" + }, + { + "id": 3, + "code": "standingInstructionPriority.medium", + "value": "Medium Priority" + }, + { + "id": 4, + "code": "standingInstructionPriority.low", + "value": "Low Priority" + } + ], + "recurrenceTypeOptions": [ + { + "id": 1, + "code": "accountTransferRecurrenceType.periodic", + "value": "Periodic Recurrence" + }, + { + "id": 2, + "code": "accountTransferRecurrenceType.as.per.dues", + "value": "As Per Dues Recurrence" + } + ], + "recurrenceFrequencyOptions": [ + { + "id": 0, + "code": "frequencyperiodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "frequencyperiodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "frequencyperiodFrequencyType.months", + "value": "Months" + }, + { + "id": 3, + "code": "frequencyperiodFrequencyType.years", + "value": "Years" + } + ] +} + +
+ +
+ GET https://Domain Name/api/v1/standinginstructions/template?fromAccountType=2&fromOfficeId=1&fromClientId=1&transferType=1 + + + { + "fromOffice": { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office", + "externalId": "1", + "openingDate": [ + 2009, + 1, + 1 + ], + "hierarchy": "." + }, + "fromClient": { + "id": 1, + "accountNo": "000000001", + "externalId": "ID_UTMYOEQ", + "status": { + "id": 300, + "code": "clientStatusType.active", + "value": "Active" + }, + "active": true, + "activationDate": [ + 2011, + 1, + 1 + ], + "firstname": "Client_FirstName_2VRAG", + "lastname": "Client_LastName_9QCY", + "displayName": "Client_FirstName_2VRAG Client_LastName_9QCY", + "officeId": 1, + "officeName": "Head Office", + "timeline": { + "submittedOnDate": [ + 2011, + 1, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "activatedOnDate": [ + 2011, + 1, + 1 + ], + "activatedByUsername": "mifos", + "activatedByFirstname": "App", + "activatedByLastname": "Administrator" + }, + "groups": [] + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromOfficeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + } + ], + "fromClientOptions": [ + { + "id": 1, + "displayName": "Client_FirstName_2VRAG Client_LastName_9QCY", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 2, + "displayName": "Client_FirstName_ZYDN2 Client_LastName_XVOP", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 3, + "displayName": "Client_FirstName_89LYT Client_LastName_4EY6", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 4, + "displayName": "Client_FirstName_PRCBG Client_LastName_JZU2", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 5, + "displayName": "Client_FirstName_J37GR Client_LastName_1T3X", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 6, + "displayName": "Client_FirstName_ZVHM2 Client_LastName_RUGS", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 7, + "displayName": "Client_FirstName_RBALP Client_LastName_437P", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 8, + "displayName": "Client_FirstName_R7M4V Client_LastName_Q5ED", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 9, + "displayName": "Client_FirstName_WIBDE Client_LastName_U91T", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 10, + "displayName": "Client_FirstName_26QJT Client_LastName_BEHD", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 11, + "displayName": "Client_FirstName_W071M Client_LastName_L7Z2", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 12, + "displayName": "Client_FirstName_QUHDJ Client_LastName_S4C5", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 13, + "displayName": "Client_FirstName_MNP4W Client_LastName_J8Y3", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 14, + "displayName": "Client_FirstName_TL6I8 Client_LastName_5YHG", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 15, + "displayName": "Client_FirstName_LUTBO Client_LastName_DITS", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 16, + "displayName": "Client_FirstName_UE39Z Client_LastName_PUWZ", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 17, + "displayName": "Client_FirstName_M8SD2 Client_LastName_J6QK", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 18, + "displayName": "Client_FirstName_SG8NF Client_LastName_BM1J", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 19, + "displayName": "Client_FirstName_BW0C8 Client_LastName_LGV9", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 20, + "displayName": "Client_FirstName_9KYLE Client_LastName_I0GJ", + "officeId": 1, + "officeName": "Head Office" + } + ], + "fromAccountTypeOptions": [ + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + } + ], + "fromAccountOptions": [], + "toOfficeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + } + ], + "toAccountTypeOptions": [ + { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + } + ], + "transferTypeOptions": [ + { + "id": 1, + "code": "accountTransferType.account.transfer", + "value": "Account Transfer" + }, + { + "id": 2, + "code": "accountTransferType.loan.repayment", + "value": "Loan Repayment" + } + ], + "statusOptions": [ + { + "id": 1, + "code": "standingInstructionStatus.active", + "value": "Active" + }, + { + "id": 2, + "code": "standingInstructionStatus.disabled", + "value": "Disabled" + } + ], + "instructionTypeOptions": [ + { + "id": 1, + "code": "standingInstructionType.fixed", + "value": "Fixed" + }, + { + "id": 2, + "code": "standingInstructionType.dues", + "value": "Dues" + } + ], + "priorityOptions": [ + { + "id": 1, + "code": "standingInstructionPriority.urgent", + "value": "Urgent Priority" + }, + { + "id": 2, + "code": "standingInstructionPriority.high", + "value": "High Priority" + }, + { + "id": 3, + "code": "standingInstructionPriority.medium", + "value": "Medium Priority" + }, + { + "id": 4, + "code": "standingInstructionPriority.low", + "value": "Low Priority" + } + ], + "recurrenceTypeOptions": [ + { + "id": 1, + "code": "accountTransferRecurrenceType.periodic", + "value": "Periodic Recurrence" + }, + { + "id": 2, + "code": "accountTransferRecurrenceType.as.per.dues", + "value": "As Per Dues Recurrence" + } + ], + "recurrenceFrequencyOptions": [ + { + "id": 0, + "code": "frequencyperiodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "frequencyperiodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "frequencyperiodFrequencyType.months", + "value": "Months" + }, + { + "id": 3, + "code": "frequencyperiodFrequencyType.years", + "value": "Years" + } + ] +} + +
+ +
+ GET https://Domain Name/api/v1/standinginstructions/template?fromAccountType=2&fromOfficeId=1&fromClientId=1&transferType=2&fromAccountId=1 + + +{ + "fromOffice": { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office", + "externalId": "1", + "openingDate": [ + 2009, + 1, + 1 + ], + "hierarchy": "." + }, + "fromClient": { + "id": 3, + "accountNo": "000000003", + "externalId": "ID_ECEAKAP", + "status": { + "id": 300, + "code": "clientStatusType.active", + "value": "Active" + }, + "active": true, + "activationDate": [ + 2011, + 3, + 4 + ], + "firstname": "Client_FirstName_89LYT", + "lastname": "Client_LastName_4EY6", + "displayName": "Client_FirstName_89LYT Client_LastName_4EY6", + "officeId": 1, + "officeName": "Head Office", + "timeline": { + "submittedOnDate": [ + 2011, + 3, + 4 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "activatedOnDate": [ + 2011, + 3, + 4 + ], + "activatedByUsername": "mifos", + "activatedByFirstname": "App", + "activatedByLastname": "Administrator" + }, + "groups": [] + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 1, + "accountNo": "000000001", + "clientId": 3, + "clientName": "Client_FirstName_89LYT Client_LastName_4EY6", + "productId": 1, + "productName": "SAVINGS_PRODUCT_MVA619", + "fieldOfficerId": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 4, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + "fromOfficeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + } + ], + "fromClientOptions": [ + { + "id": 1, + "displayName": "Client_FirstName_2VRAG Client_LastName_9QCY", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 2, + "displayName": "Client_FirstName_ZYDN2 Client_LastName_XVOP", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 3, + "displayName": "Client_FirstName_89LYT Client_LastName_4EY6", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 4, + "displayName": "Client_FirstName_PRCBG Client_LastName_JZU2", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 5, + "displayName": "Client_FirstName_J37GR Client_LastName_1T3X", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 6, + "displayName": "Client_FirstName_ZVHM2 Client_LastName_RUGS", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 7, + "displayName": "Client_FirstName_RBALP Client_LastName_437P", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 8, + "displayName": "Client_FirstName_R7M4V Client_LastName_Q5ED", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 9, + "displayName": "Client_FirstName_WIBDE Client_LastName_U91T", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 10, + "displayName": "Client_FirstName_26QJT Client_LastName_BEHD", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 11, + "displayName": "Client_FirstName_W071M Client_LastName_L7Z2", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 12, + "displayName": "Client_FirstName_QUHDJ Client_LastName_S4C5", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 13, + "displayName": "Client_FirstName_MNP4W Client_LastName_J8Y3", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 14, + "displayName": "Client_FirstName_TL6I8 Client_LastName_5YHG", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 15, + "displayName": "Client_FirstName_LUTBO Client_LastName_DITS", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 16, + "displayName": "Client_FirstName_UE39Z Client_LastName_PUWZ", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 17, + "displayName": "Client_FirstName_M8SD2 Client_LastName_J6QK", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 18, + "displayName": "Client_FirstName_SG8NF Client_LastName_BM1J", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 19, + "displayName": "Client_FirstName_BW0C8 Client_LastName_LGV9", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 20, + "displayName": "Client_FirstName_9KYLE Client_LastName_I0GJ", + "officeId": 1, + "officeName": "Head Office" + } + ], + "fromAccountTypeOptions": [ + { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + } + ], + "fromAccountOptions": [ + { + "id": 1, + "accountNo": "000000001", + "clientId": 3, + "clientName": "Client_FirstName_89LYT Client_LastName_4EY6", + "productId": 1, + "productName": "SAVINGS_PRODUCT_MVA619", + "fieldOfficerId": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 4, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ], + "toOfficeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + } + ], + "toAccountTypeOptions": [ + { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + } + ], + "transferTypeOptions": [ + { + "id": 1, + "code": "accountTransferType.account.transfer", + "value": "Account Transfer" + }, + { + "id": 2, + "code": "accountTransferType.loan.repayment", + "value": "Loan Repayment" + } + ], + "statusOptions": [ + { + "id": 1, + "code": "standingInstructionStatus.active", + "value": "Active" + }, + { + "id": 2, + "code": "standingInstructionStatus.disabled", + "value": "Disabled" + } + ], + "instructionTypeOptions": [ + { + "id": 1, + "code": "standingInstructionType.fixed", + "value": "Fixed" + }, + { + "id": 2, + "code": "standingInstructionType.dues", + "value": "Dues" + } + ], + "priorityOptions": [ + { + "id": 1, + "code": "standingInstructionPriority.urgent", + "value": "Urgent Priority" + }, + { + "id": 2, + "code": "standingInstructionPriority.high", + "value": "High Priority" + }, + { + "id": 3, + "code": "standingInstructionPriority.medium", + "value": "Medium Priority" + }, + { + "id": 4, + "code": "standingInstructionPriority.low", + "value": "Low Priority" + } + ], + "recurrenceTypeOptions": [ + { + "id": 1, + "code": "accountTransferRecurrenceType.periodic", + "value": "Periodic Recurrence" + }, + { + "id": 2, + "code": "accountTransferRecurrenceType.as.per.dues", + "value": "As Per Dues Recurrence" + } + ], + "recurrenceFrequencyOptions": [ + { + "id": 0, + "code": "frequencyperiodFrequencyType.days", + "value": "Days" + }, + { + "id": 1, + "code": "frequencyperiodFrequencyType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "frequencyperiodFrequencyType.months", + "value": "Months" + }, + { + "id": 3, + "code": "frequencyperiodFrequencyType.years", + "value": "Years" + } + ] +} + +
+ +
+ +   +
+
+

Create new Standing Instruction

+

Ability to create new instruction for transfer of monetary funds from one account to another.

+
+
+ POST https://Domain Name/api/v1/standinginstructions + POST standinginstructions/ +Content-Type: application/json +No Request Body: +{ + "fromOfficeId":1, + "fromClientId":1, + "fromAccountType":2, + "name":"standing instruction", + "transferType":1, + "priority":2, + "status":1, + "fromAccountId":1, + "toOfficeId":1, + "toClientId":1, + "toAccountType":2, + "toAccountId":3, + "instructionType":1, + "amount":"221", + "validFrom":"08 April 2014", + "recurrenceType":1, + "recurrenceInterval":"1", + "recurrenceFrequency":2, + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "recurrenceOnMonthDay":"02 April", + "monthDayFormat":"dd MMMM" +} + + +{ + +"clientId":1, +"resourceId":65 +} + +
+
+ +   +
+
+

Update Standing Instruction

+

Ability to modify existing instruction for transfer of monetary funds from one account to another.

+
+
+ PUT https://Domain Name/api/v1/standinginstructions/1?command=update + PUT standinginstructions/1?command=update +Content-Type: application/json +No Request Body: +{ + "recurrenceInterval":"2" +} + + +{ + "resourceId":20, + "changes":{ + "recurrenceInterval":2 + } +} + +
+
+ +   +
+
+

Delete Standing Instruction

+

Ability to modify existing instruction for transfer of monetary funds from one account to another.

+
+
+ PUT https://Domain Name/api/v1/standinginstructions/1?command=delete + PUT standinginstructions/1?command=delete +Content-Type: application/json +No Request Body: +{ + +} + + +{ + "resourceId":20, + "changes":{ + "status":3 + } +} + +
+
+ +   +
+
+

List Standing Instructions

+

Example Requests:

+
standinginstructions
+
+
+
+ GET https://Domain Name/api/v1/standinginstructions + +{ + "totalFilteredRecords": 2, + "pageItems": [ + { + "id": 1, + "accountDetailId": 6, + "name": "test standing", + "fromOffice": { + "id": 1, + "name": "Head Office" + }, + "fromClient": { + "id": 1, + "displayName": "Test test", + "officeId": 1, + "officeName": "Head Office" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 14, + "accountNo": "000000014", + "productId": 1, + "productName": "savings old" + }, + "toOffice": { + "id": 1, + "name": "Head Office" + }, + "toClient": { + "id": 1, + "displayName": "Test test", + "officeId": 1, + "officeName": "Head Office" + }, + "toAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "toAccount": { + "id": 3, + "accountNo": "000000003", + "productId": 4, + "productName": "account overdraft" + }, + "transferType": { + "id": 1, + "code": "accountTransferType.account.transfer", + "value": "Account Transfer" + }, + "priority": { + "id": 3, + "code": "standingInstructionPriority.medium", + "value": "Medium Priority" + }, + "instructionType": { + "id": 1, + "code": "standingInstructionType.fixed", + "value": "Fixed" + }, + "status": { + "id": 3, + "code": "standingInstructionStatus.deleted", + "value": "Deleted" + }, + "amount": 150.000000, + "validFrom": [ + 2014, + 4, + 3 + ], + "recurrenceType": { + "id": 1, + "code": "accountTransferRecurrenceType.periodic", + "value": "Periodic Recurrence" + }, + "recurrenceFrequency": { + "id": 2, + "code": "recurrenceperiodFrequencyType.months", + "value": "Months" + }, + "recurrenceInterval": 1, + "recurrenceOnMonthDay": [ + 4, + 3 + ] + }, + { + "id": 2, + "accountDetailId": 7, + "name": "test standing 2", + "fromOffice": { + "id": 1, + "name": "Head Office" + }, + "fromClient": { + "id": 1, + "displayName": "Test test", + "officeId": 1, + "officeName": "Head Office" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 14, + "accountNo": "000000014", + "productId": 1, + "productName": "savings old" + }, + "toOffice": { + "id": 1, + "name": "Head Office" + }, + "toClient": { + "id": 1, + "displayName": "Test test", + "officeId": 1, + "officeName": "Head Office" + }, + "toAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "toAccount": { + "id": 3, + "accountNo": "000000003", + "productId": 4, + "productName": "account overdraft" + }, + "transferType": { + "id": 1, + "code": "accountTransferType.account.transfer", + "value": "Account Transfer" + }, + "priority": { + "id": 2, + "code": "standingInstructionPriority.high", + "value": "High Priority" + }, + "instructionType": { + "id": 1, + "code": "standingInstructionType.fixed", + "value": "Fixed" + }, + "status": { + "id": 3, + "code": "standingInstructionStatus.deleted", + "value": "Deleted" + }, + "amount": 100.000000, + "validFrom": [ + 2014, + 4, + 3 + ], + "recurrenceType": { + "id": 1, + "code": "accountTransferRecurrenceType.periodic", + "value": "Periodic Recurrence" + }, + "recurrenceFrequency": { + "id": 2, + "code": "recurrenceperiodFrequencyType.months", + "value": "Months" + }, + "recurrenceInterval": 1, + "recurrenceOnMonthDay": [ + 2, + 1 + ] + } + ] +} +
+
+ +   +
+
+

Retrieve Standing Instruction:

+

Example Requests :

+
standinginstructions/1
+
+
+
+ GET https://DomainName/api/v1/standinginstructions/{standingInstructionId} + +{ + "id": 1, + "accountDetailId": 6, + "name": "test standing", + "fromOffice": { + "id": 1, + "name": "Head Office" + }, + "fromClient": { + "id": 1, + "displayName": "Test test", + "officeId": 1, + "officeName": "Head Office" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 14, + "accountNo": "000000014", + "productId": 1, + "productName": "savings old" + }, + "toOffice": { + "id": 1, + "name": "Head Office" + }, + "toClient": { + "id": 1, + "displayName": "Test test", + "officeId": 1, + "officeName": "Head Office" + }, + "toAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "toAccount": { + "id": 3, + "accountNo": "000000003", + "productId": 4, + "productName": "account overdraft" + }, + "transferType": { + "id": 1, + "code": "accountTransferType.account.transfer", + "value": "Account Transfer" + }, + "priority": { + "id": 3, + "code": "standingInstructionPriority.medium", + "value": "Medium Priority" + }, + "instructionType": { + "id": 1, + "code": "standingInstructionType.fixed", + "value": "Fixed" + }, + "status": { + "id": 3, + "code": "standingInstructionStatus.deleted", + "value": "Deleted" + }, + "amount": 150.000000, + "validFrom": [ + 2014, + 4, + 3 + ], + "recurrenceType": { + "id": 1, + "code": "accountTransferRecurrenceType.periodic", + "value": "Periodic Recurrence" + }, + "recurrenceFrequency": { + "id": 2, + "code": "recurrenceperiodFrequencyType.months", + "value": "Months" + }, + "recurrenceInterval": 1, + "recurrenceOnMonthDay": [ + 4, + 3 + ] +} + +
+
+ +   +
+
+

Standing Instructions Logged History:

+

The list capability of history can support pagination and sorting.

+
Optional Arguments
+
+
offset
+
+ Integer optional, defaults to 0 +
+
Indicates from what result to start from.
+ +
limit
+
+ Integer optional, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
orderBy
+
+ String optional, one of name,standingInstructionId +
+
Orders the results by the field indicated.
+ +
sortBy
+
+ String optional, one of ASC, DESC +
+
Indicates what way to order results if orderBy is used.
+ +
clientId
+
+ Integer optional +
+
Use clientId of clients to restrict results.
+ +
clientName
+
+ String optional +
+
Use displayName of clients to restrict results.
+ +
fromAccountId
+
+ Integer optional +
+
Use fromAccountId of standing instruction transaction to restrict results. fromAccountId is id of fromAccountType.
+ +
fromAccountType
+
+ Integer optional +
+
Use fromAccountType of standing instruction transaction to restrict results. fromAccountType is enum value entity type Ex:Loan Account:1, Savings Account:2
+ +
transferType
+
+ Integer optional +
+
Use transferType of standing instruction transaction to restrict results. transferType is enum value transfer type Ex:Loan Repayment:2, Account Transfer:1
+ +
fromDate
+
+ Dateoptional +
+
Filters for transactions whose entry Date is greater than or equal to the passed in Date +
+
toDate
+
+ Date optional +
+
Filters for transactions whose entry Date is lesser than or equal to the passed in Date +
+ +
sqlSearch
+
+ String optional +
+
Use an sql fragment valid for the underlying standing instruction schema to filter results. e.g. name like %K%
+
+

Example Requests :

+
standinginstructionrunhistory
+
+
standinginstructionrunhistory?orderBy=name&sortOrder=DESC
+
+
standinginstructionrunhistory?offset=10&limit=50
+
+
+
+ GET https://DomainName/api/v1/standinginstructionrunhistory + +{ + "totalFilteredRecords": 2, + "pageItems": [ + { + "standingInstructionId": 1, + "name": "ACC Transfer", + "fromOffice": { + "id": 1, + "name": "Head Office" + }, + "fromClient": { + "id": 1, + "displayName": "Test client", + "officeId": 1, + "officeName": "Head Office" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 2, + "accountNo": "000000002", + "productId": 1, + "productName": "General Savings" + }, + "toAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "toAccount": { + "id": 1, + "accountNo": "000000001", + "productId": 1, + "productName": "General Savings" + }, + "toOffice": { + "id": 1, + "name": "Head Office" + }, + "toClient": { + "id": 1, + "displayName": "Test client", + "officeId": 1, + "officeName": "Head Office" + }, + "amount": 10, + "status": "success", + "executionTime": [ + 2014, + 6, + 30 + ], + "errorLog": "" + }, + { + "standingInstructionId": 2, + "name": "Pay overdues", + "fromOffice": { + "id": 1, + "name": "Head Office" + }, + "fromClient": { + "id": 1, + "displayName": "Test client", + "officeId": 1, + "officeName": "Head Office" + }, + "fromAccountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "fromAccount": { + "id": 1, + "accountNo": "000000001", + "productId": 1, + "productName": "General Savings" + }, + "toAccountType": { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + }, + "toAccount": { + "id": 1, + "accountNo": "000000001", + "productId": 1, + "productName": "Daily Loan" + }, + "toOffice": { + "id": 1, + "name": "Head Office" + }, + "toClient": { + "id": 1, + "displayName": "Test client", + "officeId": 1, + "officeName": "Head Office" + }, + "amount": 7038.01, + "status": "success", + "executionTime": [ + 2014, + 6, + 30 + ], + "errorLog": "" + } + ] +} + +
+
+ + + + +   +
+
+

Data Tables

+

The datatables API allows you to plug-in your own tables + (MySql) that have a relationship to a Apache Fineract core table. For + example, you might want to add some extra client fields and record + information about each of the clients' family members. Via the API + you can create, read, update and delete entries for each + 'plugged-in' table. The API checks for permission and for 'data + scoping' (only data within the users' office hierarchy can be + managed by the user).

+

The Apache Fineract Reference App uses a JQuery plug-in called + stretchydatatables (which in turn uses this datatables resource) + to provide a pretty flexible CRUD (Create, Read, Update, Delete) + User Interface.

+

+ More + Documentation +

+
+
+ +   +
+
+

Create Data Table

+

Create a new data table and registers it with the Apache Fineract Core application + table.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
Mandatory - datatableName
The name of the Data Table.
Mandatory - apptableName
+ Application table name. Must be one of the following: +
    +
  • m_client
  • +
  • m_group
  • +
  • m_loan
  • +
  • m_office
  • +
  • m_saving_account
  • +
  • m_product_loan
  • +
  • m_savings_product
  • +
+
Mandatory - columns
An array of columns in the new Data Table.
Optional - multiRow
Allows to create multiple entries in the Data Table. Optional, defaults to false. + If this property is not provided Data Table will allow only one entry. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions - columns
Mandatory - name
Name of the created column. Can contain only alphanumeric characters, underscores and spaces, but cannot start with a number. Cannot start or end with an underscore or space.
Mandatory - type
+ Column type. Must be one of the following: +
    +
  • Boolean
  • +
  • Date
  • +
  • DateTime
  • +
  • Decimal
  • +
  • Dropdown
  • +
  • Number
  • +
  • String
  • +
  • Text
  • +
+
Mandatory [type = Dropdown] - code
Used in Code Value fields. Column name becomes: code_cd_name. Mandatory if using type Dropdown, otherwise an error is returned.
Optional - mandatory
Determines whether this column must have a value in every entry. Optional, defaults to false.
Mandatory [type = String] - length
Length of the text field. Mandatory if type String is used, otherwise an error is returned.
+
+
+ +POST https://DomainName/api/v1/datatables + + +POST https://DomainName/api/v1/datatables + +Content-Type: application/json +Request Body: +{ + "datatableName": "extra_client_details", + "apptableName": "m_client", + "columns": [ + { + "name": "Gender", + "type": "Dropdown", + "code": "Gender" + }, + { + "name": "Some Decimal", + "type": "Decimal", + "mandatory": true + }, + { + "name": "Birth Date", + "type": "Date" + }, + { + "name": "Question 2", + "type": "String", + "length": 100, + "mandatory": false + } + ] +} + + +{ + "resourceIdentifier": "extra_client_details" +} + + +POST https://DomainName/api/v1/datatables + +Content-Type: application/json +Request Body: +{ + "datatableName": "client_address", + "apptableName": "m_client", + "multiRow":"true", + "columns": [ + { + "name": "Address1", + "type": "String", + "length": 100, + "mandatory": true + }, + { + "name": "Address2", + "length": 100, + "type": "String" + } + ] +} + + +{ + "resourceIdentifier": "client_address" +} + + +
+
+ +   +
+
+

List Data Tables

+

Lists registered data tables and the Apache Fineract Core + application table they are registered to.

+ +
Arguments
+
+
apptable
+
+ optional +
+
The Apache Fineract core application table.
+
+

Example Requests:

+
datatables?apptable=m_client
+
+
+
datatables
+
+
+ +GET https://DomainName/api/v1/datatables + + +[ + { + "applicationTableName": "m_client", + "registeredTableName": "extra_client_details", + "columnHeaderData": [ + { + "columnName": "client_id", + "columnType": "bigint", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": false, + "isColumnPrimaryKey": true, + "columnValues": [] + }, + { + "columnName": "Gender_cd_Question", + "columnType": "int", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Some Decimal", + "columnType": "decimal", + "columnLength": 0, + "columnDisplayType": "DECIMAL", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Birth Date", + "columnType": "date", + "columnLength": 0, + "columnDisplayType": "DATE", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + } + ] + } +] + +
+
+ +   +
+
+

Retrieve Data Table Details

+

Lists a registered data table details and the Apache Fineract Core + application table they are registered to.

+
+
+ +GET https://DomainName/api/v1/datatables/{datatable} + + +{ + "applicationTableName": "m_client", + "registeredTableName": "extra_client_details", + "columnHeaderData": [ + { + "columnName": "client_id", + "columnType": "bigint", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": false, + "isColumnPrimaryKey": true, + "columnValues": [] + }, + { + "columnName": "Gender_cd_Question", + "columnType": "int", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Some Decimal", + "columnType": "decimal", + "columnLength": 0, + "columnDisplayType": "DECIMAL", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Birth Date", + "columnType": "date", + "columnLength": 0, + "columnDisplayType": "DATE", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + } + ] +} + +
+
+ +   +
+
+

Update Data Table

+

Modifies fields of a data table. If the apptableName parameter is passed, + data table is deregistered and registered with the new application table.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
Optional - apptableName
+ Application table name. Only necessary if changing the application table this Data Table is registered to. Must be one of the following: +
    +
  • m_client
  • +
  • m_group
  • +
  • m_loan
  • +
  • m_office
  • +
  • m_saving_account
  • +
+
Optional - dropColumns
An array of columns to be deleted from the Data Table.
Optional - addColumns
An array of columns to be added to the Data Table.
Optional - changeColumns
An array of columns to be changed in the Data Table.
+ + + + + + + + + + +
Field Descriptions - dropColumns
Mandatory - name
Requires a full name of the deleted column to be provided.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions - addColumns
Mandatory - name
Name of the created column. Can contain only alphanumeric characters, underscores and spaces, but cannot start with a number. Cannot start or end with an underscore or space.
Mandatory - type
+ Column type. Must be one of the following: +
    +
  • Boolean
  • +
  • Date
  • +
  • DateTime
  • +
  • Decimal
  • +
  • Dropdown
  • +
  • Number
  • +
  • String
  • +
  • Text
  • +
+
Mandatory [type = Dropdown] - code
Used in Code Value fields. Column name becomes: code_cd_name. Mandatory if using type Dropdown, otherwise an error is returned.
Optional - mandatory
Determines whether this column must have a value in every entry. Optional, defaults to false.
Mandatory [type = String] - length
Length of the text field. Mandatory if type String is used, otherwise an error is returned.
Optional - after
Only used when re-ordering Data Table columns. Requires a full column name to be provided.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions - changeColumns
Mandatory - name
Name of the created column. Can contain only alphanumeric characters, underscores and spaces, but cannot start with a number. Cannot start or end with an underscore or space.
Optional - newName
New name of the created column. Can contain only alphanumeric characters, underscores and spaces, but cannot start with a number. Cannot start or end with an underscore or space.
Mandatory [type = Dropdown] - code
Used in Code Value fields. Column name becomes: code_cd_name. Mandatory if using type Dropdown, otherwise an error is returned.
Optional [type = Dropdown] - newCode
Used in Code Value fields. Column name becomes: code_cd_name. Optional if using type Dropdown, otherwise an error is returned.
Optional - mandatory
Determines whether this column must have a value in every entry. Optional, defaults to false.
Mandatory [type = String] - length
Length of the text field. Mandatory if type String is used, otherwise an error is returned.
Optional - after
Only used when re-ordering Data Table columns. Requires a full column name to be provided.
+
+
+ +PUT https://DomainName/api/v1/datatables/{datatables} + + +PUT https://DomainName/api/v1/datatables/extra_client_details + +Content-Type: application/json +Request Body: +{ + "apptableName": "m_client", + "dropColumns": [ + { + "name": "Gender_cd_Question" + } + ], + "addColumns": [ + { + "name": "Question", + "type": "Dropdown", + "code": "Gender", + "mandatory": true + }, + { + "name": "Some Number", + "type": "Number", + "after": "Some Field" + } + ], + "changeColumns": [ + { + "name": "Question", + "newName": "Question 2", + "mandatory": true, + "code": "Gender", + "newCode": "Gender2" + } + ] +} + + +{ + "resourceIdentifier": "extra_client_details" +} + +
+
+ +   +
+
+

Delete Data Table

+

Deletes a data table and deregisters it from the Apache Fineract Core + application table.

+
+
+ +DELETE https://DomainName/api/v1/datatables/{datatables} + + +DELETE https://DomainName/api/v1/datatables/extra_client_details + +Content-Type: application/json +No Request Body + + +{ + "resourceIdentifier": "extra_client_details" +} + +
+ +
+   +
+
+

Register Data Table

+

Registers a data table with the Apache Fineract Core application + table. This allows the data table to be maintained through the + API. + In case the datatable is a PPI (survey table), a parameter category should be pass along with the request. + The API currently support one category (200) +

+
+
+ +POST https://DomainName/api/v1/datatables/register/{datatable}/{apptable} + + +POST datatables/register/extra_client_details/m_client + +Content-Type: application/json +Request Body: +{} + + +{ + "resourceIdentifier": "extra_client_details" +} + +
+
+ +   +
+
+

Deregister Data Table

+

Deregisters a data table. It will no longer be available + through the API.

+
+
+ +POST https://DomainName/api/v1/datatables/deregister/{datatable} + + +POST datatables/deregister/extra_client_details + +Content-Type: application/json +Request Body: +{} + + +{ + "resourceIdentifier": "extra_client_details" +} + +
+
+ + +   +
+
+

Create Entry in Data Table

+

Adds a row to the data table.

+

Note that the default datatable UI functionality converts + any field name containing spaces to underscores when using the + API. This means the field name "Business Description" is + considered the same as "Business_Description". So you shouldn't + have both "versions" in any data table.

+
+
+ +POST https://DomainName/api/v1/datatables/{datatable}/{apptableId} + + +POST datatables/extra_client_details/1 + +Content-Type: application/json +Request Body: +{ + "Business Description": "Livestock sales", + "Comment": "First comment made", + "Education_cv": "Primary", + "Gender_cd": "6", + "Highest Rate Paid": "8.5", + "Next Visit": "01 October 2012", + "Years in Business": "5", + "dateFormat": "dd MMMM yyyy", + "locale": "en" +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve Entry(s) from Data Table

+

+ Gets the entry (if it exists) for data tables that are one to one + with the application table.
Gets the entries (if they + exist) for data tables that are one to many with the application + table. +

+

Note: The 'fields' parameter is not available for + datatables.

+ +
Arguments
+
+
order
+
+ optional +
+
Specifies the order in which data is returned.
+
genericResultSet
+
+ optional, defaults to false +
+
If 'true' an optimised JSON format is returned suitable for tabular display of data. + This format is used by the default data tables UI functionality.
+
+ +

Example Requests:

+
datatables/extra_client_details/1
+
+
+
datatables/extra_family_details/1?order=`Date of Birth` desc
+
+
+
datatables/extra_client_details/1?genericResultSet=true
+
+
+ +GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}?genericResultSet=true + + +{ + "columnHeaders": [ + { + "columnName": "client_id", + "columnType": "bigint", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": false, + "isColumnPrimaryKey": true, + "columnValues": [] + }, + { + "columnName": "Business Description", + "columnType": "varchar", + "columnLength": 100, + "columnDisplayType": "STRING", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Years in Business", + "columnType": "int", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Gender_cd", + "columnType": "int", + "columnLength": 0, + "columnDisplayType": "CODELOOKUP", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [ + { + "id": 5, + "value": "option.Male" + }, + { + "id": 6, + "value": "option.Female" + } + ] + }, + { + "columnName": "Education_cv", + "columnType": "varchar", + "columnLength": 60, + "columnDisplayType": "CODEVALUE", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [ + { + "id": 9, + "value": "Primary" + }, + { + "id": 10, + "value": "Secondary" + }, + { + "id": 11, + "value": "University" + } + ] + }, + { + "columnName": "Next Visit", + "columnType": "date", + "columnLength": 0, + "columnDisplayType": "DATE", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Highest Rate Paid", + "columnType": "decimal", + "columnLength": 0, + "columnDisplayType": "DECIMAL", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Comment", + "columnType": "text", + "columnLength": 65535, + "columnDisplayType": "TEXT", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + } + ], + "data": [ + { + "row": [ + "1", + "Livestock sales", + "5", + "6", + "Primary", + "2012-10-01", + "8.500000", + "First\tcomment made" + ] + } + ] +} + +
+
+ + +   +
+
+

Update Entry in Data Table (One to One)

+

Updates the row (if it exists) of the data table.

+
+
+ +PUT https://DomainName/api/v1/datatables/{datatable}/{apptableId} + + +PUT datatables/extra_client_details/1 + +Content-Type: application/json +Request Body: +{ + "Business Description": "Livestock sales updated", +} + + +{ + "resourceId": 1, + "changes": { + "Business Description": "Livestock sales updated" + } +} + +
+
+ +   +
+
+

Update Entry in Data Table (One to Many)

+

Updates the row (if it exists) of the data table.

+
+
+ +PUT https://DomainName/api/v1/datatables/{datatable}/{apptableId}/{datatableId} + + +PUT datatables/Extra Family Details Data/1/2 + +Content-Type: application/json +Request Body: +{ + "Date of Birth": "01 June 1982", + Education_cdHighest: "5", + Name: "June", + "Other Notes": "More\nnotes", + "Points Score": "20", + dateFormat: "dd MMMM yyyy", + locale: "en" +} + + { "resourceId": 1 } +
+
+ +   +
+
+

Delete Entry(s) in Data Table

+

+ Deletes the entry (if it exists) for data tables that are one-to-one with the application table.
Deletes the entries (if they exist) for data tables that are one-to-many with the application table. +

+
+
+ +DELETE https://DomainName/api/v1/datatables/{datatable}/{apptableId} + + +DELETE datatables/extra_client_details/1 + +Content-Type: application/json +Request Body: +{} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Delete Entry in Datatable (One to Many)

+

Deletes the entry (if it exists) for data tables that are + one to many with the application table.

+
+
+ +DELETE https://DomainName/api/v1/datatables/{datatable}/{apptableId}/{datatableId} + + +DELETE datatables/extra_family_details/1/2 + +Content-Type: application/json +Request Body: +{} + + +{ + "resourceId": 1 +} + +
+
+ + + + +   +
+
+

Retrieve surveys

+

Retrieve surveys. This allows to retrieve the list of survey tables registered . +

+
+
+ + GET https://DomainName/api/v1/survey/ + + + GET survey/ + + Content-Type: application/json + Request Body: + {} + + + [ + { + "datatableData": { + "applicationTableName": "m_client", + "registeredTableName": "ppi_kenya_2005", + "columnHeaderData": [ + { + "columnName": "id", + "columnType": "bigint", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": false, + "isColumnPrimaryKey": true, + "columnValues": [] + }, + { + "columnName": "client_id", + "columnType": "int", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "ppi_household_members_cd_q1_householdmembers", + "columnType": "int", + "columnLength": 0, + "columnDisplayType": "CODELOOKUP", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [ + { + "id": 167, + "value": "Nine or More", + "score": 0 + }, + { + "id": 168, + "value": "Seven or eight", + "score": 5 + }, + { + "id": 169, + "value": "Six", + "score": 8 + }, + + ], + "columnCode": "ppi_household_members" + }, + { + "columnName": "date", + "columnType": "datetime", + "columnLength": 0, + "columnDisplayType": "DATETIME", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [] + } + ] + }, + "enabled": false + }, + { + "datatableData": { + "applicationTableName": "m_client", + "registeredTableName": "ppi_tanzania_20012", + "columnHeaderData": [ + { + "columnName": "id", + "columnType": "bigint", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": false, + "isColumnPrimaryKey": true, + "columnValues": [] + }, + { + "columnName": "client_id", + "columnType": "int", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "ppi_youngerthan17_cd_q1_youngerthan17", + "columnType": "int", + "columnLength": 0, + "columnDisplayType": "CODELOOKUP", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [ + { + "id": 204, + "value": "four or More", + "score": 0 + }, + + ], + "columnCode": "ppi_youngerthan17" + }, + ], + "columnCode": "ppi_how_many_tables" + }, + ] + }, + "enabled": true + } + ] + +
+
+ + +   +
+
+

Retrieve survey

+

Lists a registered survey table details and the Apache Fineract Core application table they are registered to. +

+
+
+ + GET https://DomainName/api/v1/survey/ppi_kenya_2005 + + + GET survey/{surveyName} + + Content-Type: application/json + Request Body: + {} + + + { + "applicationTableName": "m_client", + "registeredTableName": "extra_client_details", + "columnHeaderData": [ + { + "columnName": "client_id", + "columnType": "bigint", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": false, + "isColumnPrimaryKey": true, + "columnValues": [] + }, + { + "columnName": "Gender_cd_Question", + "columnType": "int", + "columnLength": 0, + "columnDisplayType": "INTEGER", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Some Decimal", + "columnType": "decimal", + "columnLength": 0, + "columnDisplayType": "DECIMAL", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Birth Date", + "columnType": "date", + "columnLength": 0, + "columnDisplayType": "DATE", + "isColumnNullable": true, + "isColumnPrimaryKey": false, + "columnValues": [] + } + enabled:false + ] + } + +
+
+ +   +
+
+

Create an entry in the survey table

+

Insert and entry in a survey table (full fill the survey). + +

+
+
+ + POST https://DomainName/api/v1/survey/ppi_kenya_2005/87 + + + POST survey/{surveyName}/{clientId} + + Content-Type: application/json + Request Body: + { + + ppi_household_members_cd_q1_householdmembers : 167, + ppi_highestschool_cd_q2_highestschool : 174 , + ppi_businessoccupation_cd_q3_businessoccupation : 180, + ppi_habitablerooms_cd_q4_habitablerooms :184, + ppi_floortype_cd_q5_floortype : 188, + ppi_lightingsource_cd_q6_lightingsource :190, + ppi_irons_cd_q7_irons:193, + ppi_mosquitonets_cd_q8_mosquitonets:195, + ppi_towels_cd_q9_towels:198, + ppi_fryingpans_cd_q10_fryingpans:201, + date:"2014-12-02 20:30:00", + dateFormat:"Y-m-d H:i:s", + locale:"en_GB" + + } + + + { + "officeId": 2, + "clientId": 87, + "resourceId": 87 + } + +
+
+ + + + + +   +
+
+

Notes

+

Notes API allows to enter notes for supported resources.

+ + + + + + + + + + + +
Field Descriptions
note
A simple text note created for supported resources.
+
+
+ + + + + + + +
Supported Resources
+ Client +
+ Loan +
+ Group +
+ Savings Account +
+
+
+ +   +
+
+

Add a Resource Note

+

Adds a new note to a supported resource.

+ + + + + + + +
Mandatory Fields
note
+

Example Requests:

+
clients/1/notes
+
+
+
groups/1/notes
+
+
+ +POST https://DomainName/api/v1/{resource}/{resourceId}/notes + + +POST clients/1/notes +Content-Type: application/json +Request Body: +{ + "note": "a note about the client" +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 76 +} + +
+
+ +   +
+
+

Retrieve a Resource's Notes

+

+ Note: Notes are returned in descending createOn order. +

+

Example Requests:

+
clients/2/notes
+
+
+
groups/2/notes?fields=note,createdOn,createdByUsername
+
+
+ +GET https://DomainName/api/v1/{resource}/{resourceId}/notes + + +[ + { + "id": 2, + "clientId": 1, + "noteType": { + "id": 100, + "code": "noteType.client", + "value": "Client note" + }, + "note": "First note edited", + "createdById": 1, + "createdByUsername": "mifos", + "createdOn": 1342498505000, + "updatedById": 1, + "updatedByUsername": "mifos", + "updatedOn": 1342498517000 + } +] + +
+
+ +   +
+
+

Retrieve a Resource Note

+

Example Requests:

+
clients/1/notes/76
+
+
+
groups/1/notes/20
+
+
+
clients/1/notes/76?fields=note,createdOn,createdByUsername
+
+
+
groups/1/notes/20?fields=note,createdOn,createdByUsername
+
+
+ +GET https://DomainName/api/v1/{resource}/{resourceId}/notes/{noteId} + + +{ + "id": 76, + "clientId": 1, + "noteType": { + "id": 100, + "code": "noteType.client", + "value": "Client note" + }, + "note": "a note about the client", + "createdById": 1, + "createdByUsername": "mifos", + "createdOn": 1359463135000, + "updatedById": 1, + "updatedByUsername": "mifos", + "updatedOn": 1359463135000 +} + +
+
+ +   +
+
+

Update a Resource Note

+
+
+ +PUT https://DomainName/api/v1/{resource}/{resourceId}/notes/{noteId} + + +PUT clients/1/notes/76 +Content-Type: application/json +Request Body: +{ + "note": "and here the note is updated nicely." +} + + +{ + "officeId": 1, + "clientId": 1, + "resourceId": 76, + "changes": { + "note": "and here the note is updated nicely." + } +} + +
+
+ +   +
+
+

Delete a Resource Note

+
+
+ +DELETE https://DomainName/api/v1/{resource}/{resourceId}/notes/{noteId} + + +DELETE clients/1/notes/76 +Content-Type: application/json +No Request Body: + + +{ + "resourceId": 76 +} + +
+
+ + + + +   +
+
+

Documents

+

Multiple Documents (a combination of a name, description + and a file) may be attached to different Entities + like Clients, Groups, Staff, Loans, Savings and Client + Identifiers in the system +

+

Note: The currently allowed Entities are +

    +
  • Clients: URL Pattern as clients
  • +
  • Staff: URL Pattern as staff
  • +
  • Loans: URL Pattern as loans
  • +
  • Savings: URL Pattern as savings
  • +
  • Client Identifiers: URL Pattern as client_identifiers
  • +
  • Groups: URL Pattern as groups
  • +
+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
parentEntityType
The type of the Entity + with which this document is associated +
parentEntityId
The ID of the entity (client, + loan etc) with which this document is + associated
name
User Defined name for the + document, need not be the same as the name + of the file associated with the document +
fileName
The name of the file associated + with this document
size
The size (in bytes) of the file + associated with this document
type
Mime Type of the file + associated with this document +
description
A description of this document +
+
+
+ +   +
+
+

List documents

+

Example Requests:

+
clients/1/documents
+
+
client_identifiers/1/documents
+
+
loans/1/documents?fields=name,description
+
+
+ +GET https://DomainName/api/v1/{entityType}/{entityId}/documents + + +[ + { + "id": 1, + "parentEntityType": "clients", + "parentEntityId": 1, + "name": "Client Details Form ", + "fileName": "CGAP.pdf", + "size": 5246719, + "type": "application/pdf", + "description": "A signed form signed by new member" + } +] + +
+
+ +   +
+
+

Retrieve a Document

+

Example Requests:

+
clients/1/documents/1
+
+
+
loans/1/documents/1
+
+
+
client_identifiers/1/documents/1?fields=name,description
+
+
+ +GET https://DomainName/api/v1/documents/{clientId} + + +{ + "id": 1, + "parentEntityType": "clients", + "parentEntityId": 1, + "name": "Client Details Form ", + "fileName": "CGAP.pdf", + "size": 5246719, + "type": "application/pdf", + "description": "A signed form signed by new member" +} + +
+
+ +   +
+
+

Create a Document

+

+ Note: A document is created using a Multi-part form upload +
+ + + + + + + + + + + + + + + + + + + + + + +
Body Parts
name
Name or summary of the document +
description
Description of the document +
file
The file to be uploaded +
+

+ + + + + + + +
Mandatory Fields
file and description
+
+
+ +POST https://DomainName/api/v1/{entityType}/{entityId}/documents + + +POST clients/1/documents +Content-Type: multipart/form-data +Request Body: +Not Shown (multi-part form data) + + +{ + "resourceId":3, + "resourceIdentifier":"3" +} + +
+
+ +   +
+
+

Update a Document

+

+ Note: A document is updated using a Multi-part form upload +
+ + + + + + + + + + + + + + + + + + + + + + +
Body Parts
name
Name or summary of the document +
description
Description of the document +
file
The file to be uploaded +
+

+
+
+ +PUT https://DomainName/api/v1/{entityType}/{entityId}/documents/{documentId} + + +PUT clients/1/documents/1 +Content-Type: multipart/form-data +Request Body: +Not Shown (multi-part form data) + + +{ + "resourceId":3, + "changes":{}, + "resourceIdentifier":"3" +} + +
+
+ +   +
+
+

Retrieve Binary File associated with Document

+

Request used to download the file associated with the document

+

Example Requests:

+
clients/1/documents/1/attachment
+
+
+
loans/1/documents/1/attachment
+
+
+ +GET https://DomainName/api/v1/{entityType}/{entityId}/documents/{documentId}/attachment + + +Not Shown: The corresponding Binary file + +
+
+ +   +
+
+

Remove a Document

+
+
+ +DELETE https://DomainName/api/v1/{entityType}/{entityId}/documents/{documentId} + + +DELETE clients/1/documents/1 +Content-Type: application/json +No Request Body: + + +{ + "resourceId":1, + "changes":{}, + "resourceIdentifier":"1" +} + +
+
+ +DELETE https://DomainName/api/v1/{entityType}/{entityId}/documents/{documentId} + + +DELETE loans/1/documents/1 +Content-Type: application/json +No Request Body: + + +{ + "resourceId":1, + "changes":{}, + "resourceIdentifier":"1" +} + +
+ +
+ + + +   +
+
+

Reports

+

+ Non-core reports can be added, updated and deleted. +

+

+ Core reports (supplied at installation/upgrade time) can only have their "useReport" updated. + "useReport" is used, for example, in the reference UI report page to 'show'/'not show' reports. + Reports that have useReport set to false can still be run. + Reports only used for workflow purposes are examples of reports that would have their useReport set to false. +

+

+ Placeholders can be put in the reportSql to act as parameters. They have the format ${paramName}. + The runreports api will translate the value of any query parameter beginning R_ with the equivalent placeholder.
+ e.g. query parameter R_myName=john will replace ${myName} with john +

+

+ There is a special 'automatic' placeholder ${currentUserHierarchy} - if this is included in reportSql + it gets replaced by the requesting users' office hierarchy value. This enables data scoping.
+ Usage example "where o.hierarchy like CONCAT('${currentUserHierarchy}', '%')" +

+

+ Note:
+ The reports api allows parameters (not just placeholders in reportSql) to be associated with reports. + These associated parameters are only required to allow the reference UI reporting functionality implement + user-friendly parameter input. +

+
+
+ +   +
+
+

Retrieve Report Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
reports/template
+
+
+ +GET https://DomainName/api/v1/reports/template + + +{ + "allowedReportTypes": [ + "Table", + "Pentaho", + "Chart" + ], + "allowedReportSubTypes": [ + "Bar", + "Pie" + ], + "allowedParameters": [ + { + "id": 1, + "parameterName": "startDateSelect" + }, + { + "id": 2, + "parameterName": "endDateSelect" + }, + { + "id": 3, + "parameterName": "obligDateTypeSelect" + }, + { + "id": 5, + "parameterName": "OfficeIdSelectOne" + }, + { + "id": 6, + "parameterName": "loanOfficerIdSelectAll" + }, + { + "id": 10, + "parameterName": "currencyIdSelectAll" + }, + { + "id": 20, + "parameterName": "fundIdSelectAll" + }, + { + "id": 25, + "parameterName": "loanProductIdSelectAll" + }, + { + "id": 26, + "parameterName": "loanPurposeIdSelectAll" + }, + { + "id": 100, + "parameterName": "parTypeSelect" + } + ] +} + +
+
+ +   +
+
+

Create a Report

+
+
+ +POST https://DomainName/api/v1/reports + + +POST reports +Content-Type: application/json +Request Body: +{ + "reportName":"Completely New Report", + "reportType":"Table", + "reportSubType":"", + "reportCategory":"Loan", + "useReport":"false", + "description":"Just\nAn\nExample", + "reportSql":"select 'very good sql' as AComment", + "reportParameters":[{"id":"","parameterId":"5","reportParameterName":""},{"id":"","parameterId":"6","reportParameterName":""}] +} + + +{ + "resourceId": 132 +} + +
+
+ +   +
+
+

List Reports

+

Lists all reports and their parameters.

+ +

Example Request:

+
reports
+
+
+ +GET https://DomainName/api/v1/reports + + +[ + { + "id": 1, + "reportName": "Client Listing", + "reportType": "Table", + "reportCategory": "Client", + "description": "Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \u0027one to one\u0027 additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\u0027d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\u0027t \n\nhave that client browser/memory impact).", + "coreReport": true, + "useReport": true, + "reportParameters": [ + { + "id": 1, + "parameterId": 5, + "parameterName": "OfficeIdSelectOne" + } + ] + }, + { + "id": 2, + "reportName": "Client Loans Listing", + "reportType": "Table", + "reportCategory": "Client", + "description": "Individual Client Report\n\nPretty \n\nwide report that lists the basic details of client loans. \n\nCan be run for any size MFI but you\u0027d expect it only to be run within a branch for larger ones. \n\nThere is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\u0027t have that client browser/memory impact).", + "coreReport": false, + "useReport": true, + "reportParameters": [ + { + "id": 2, + "parameterId": 5, + "parameterName": "OfficeIdSelectOne" + }, + { + "id": 3, + "parameterId": 6, + "parameterName": "loanOfficerIdSelectAll" + }, + { + "id": 4, + "parameterId": 10, + "parameterName": "currencyIdSelectAll" + }, + { + "id": 5, + "parameterId": 20, + "parameterName": "fundIdSelectAll" + }, + { + "id": 6, + "parameterId": 25, + "parameterName": "loanProductIdSelectAll" + }, + { + "id": 7, + "parameterId": 26, + "parameterName": "loanPurposeIdSelectAll" + } + ] + },... + ] + +
+
+ + +   +
+
+

Retrieve a Report

+

Example Requests:

+
reports/1


+
reports/1?template=true
+
+
+ +GET https://DomainName/api/v1/reports/{id} + + +{ + "id": 1, + "reportName": "Client Listing", + "reportType": "Table", + "reportCategory": "Client", + "description": "Individual Client Report\r\n\r\nLists the small number of defined fields on the client table. Would expect to copy this \n\nreport and add any \u0027one to one\u0027 additional data for specific tenant needs.\r\n\r\nCan be run for any size MFI but you\u0027d expect it only to be run within a branch for \n\nlarger ones. Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn\u0027t \n\nhave that client browser/memory impact).", + "reportSql": "select \nconcat(repeat(\"..\", \n ((LENGTH(ounder.`hierarchy`) - LENGTH(REPLACE(ounder.`hierarchy`, \u0027.\u0027, \u0027\u0027)) - 1))), ounder.`name`) as \"Office/Branch\",\n c.account_no as \"Client Account No.\", \nc.display_name as \"Name\", \nr.enum_message_property as \"Status\",\nc.activation_date as \"Activation\", c.external_id as \"External Id\"\nfrom m_office o \njoin m_office ounder on ounder.hierarchy like concat(o.hierarchy, \u0027%\u0027)\nand ounder.hierarchy like concat(\u0027${currentUserHierarchy}\u0027, \u0027%\u0027)\njoin m_client c on c.office_id \u003d ounder.id\nleft join r_enum_value r on r.enum_name \u003d \u0027status_enum\u0027 and r.enum_id \u003d c.status_enum\nwhere o.id \u003d ${officeId}\norder by ounder.hierarchy, c.account_no", + "coreReport": true, + "useReport": true, + "reportParameters": [ + { + "id": 1, + "parameterId": 5, + "parameterName": "OfficeIdSelectOne" + } + ] +} + +
+
+ +   +
+
+

Update a Report

+

+ Only the useReport value can be updated for core reports. +

+
+
+ +PUT https://DomainName/api/v1/reports/{id} + + +PUT reports/129 +Content-Type: application/json +Request Body: +{ + "reportName": "New rpt name", + "reportParameters": [ + { + "id": 194, + "parameterId": 5, + "reportParameterName": "m" + } + ] +} + + +{ + "resourceId": 129, + "changes": { + "reportName": "New rpt name", + "reportParameters": "[{\"id\":194,\"parameterId\":5,\"reportParameterName\":\"m\"}]" + } +} + +
+
+ + +   +
+
+

Delete a Report

+

+ Only non-core reports can be deleted. +

+
+
+ +DELETE https://DomainName/api/v1/reports/{id} + + +DELETE reports/100 +Content-Type: application/json +Request Body: +{} + + +{ + "resourceId": 100 +} + +
+
+ + +   +
+
+

Run Reports

+
+
+   +
+
+

Running a Report

+

This resource allows you to run and receive output from pre-defined Apache Fineract reports.

+

Reports can also be used to provide data for searching and workflow functionality.

+

+ The default output is a JSON formatted "Generic Resultset". The Generic Resultset contains + Column Heading as well as Data information. However, you can + export to CSV format by simply adding "&exportCSV=true" to the end + of your URL.

+

If Pentaho reports have been pre-defined, they can also be + run through this resource. Pentaho reports can return HTML, PDF or + CSV formats.

+

The Apache Fineract reference application uses a + JQuery plugin called stretchyreporting which, itself, uses this + reports resource to provide a pretty flexible reporting User + Interface (UI).

+
Arguments
+
+
R_'parameter names' ...
+
+ optional, No defaults +
+
The number and names of the parameters depend on the + specific report and how it has been configured. R_officeId is an + example parameter name.
+
Note: the prefix R_ stands for Reporting
+
genericResultSet
+
+ optional, defaults to true +
+
If 'true' an optimised JSON format is returned suitable for tabular display of data. +
If 'false' a simple JSON format is returned. +
parameterType
+
+ optional, The only valid value is 'true'. If any + other value is provided the argument will be ignored +
+
Determines whether the request looks in the list of + reports or the list of parameters for its data. Doesn't apply to + Pentaho reports.
+
exportCSV
+
+ optional, The only valid value is 'true'. If any + other value is provided the argument will be ignored +
+
Output will be delivered as a CSV file instead of JSON. + Doesn't apply to Pentaho reports.
+
output-type
+
+ optional, Defaults to HTML. +
+
Valid Values are HTML, XLS, XSLX, CSV and PDF for html, Excel, Excel 2007+, + CSV and PDF formats respectively.
+
Only applies to Pentaho reports.
+
locale
+
+ optional +
+
Any valid locale Ex: en_US, en_IN, fr_FR etc
+
Only applies to Pentaho reports.
+
+

Example Requests:

+
runreports/Client%20Listing?R_officeId=1
+
+
+
runreports/Client%20Listing?R_officeId=1&exportCSV=true
+
+
+
runreports/OfficeIdSelectOne?R_officeId=1&parameterType=true
+
+
+
runreports/OfficeIdSelectOne?R_officeId=1&parameterType=true&exportCSV=true
+
+
+
runreports/Expected%20Payments%20By%20Date%20-%20Formatted?R_endDate=2013-04-30&R_loanOfficerId=-1&R_officeId=1&R_startDate=2013-04-16&output-type=HTML&R_officeId=1
+
+
+
runreports/Expected%20Payments%20By%20Date%20-%20Formatted?R_endDate=2013-04-30&R_loanOfficerId=-1&R_officeId=1&R_startDate=2013-04-16&output-type=XLS&R_officeId=1
+
+
+
runreports/Expected%20Payments%20By%20Date%20-%20Formatted?R_endDate=2013-04-30&R_loanOfficerId=-1&R_officeId=1&R_startDate=2013-04-16&output-type=CSV&R_officeId=1
+
+
+
runreports/Expected%20Payments%20By%20Date%20-%20Formatted?R_endDate=2013-04-30&R_loanOfficerId=-1&R_officeId=1&R_startDate=2013-04-16&output-type=PDF&R_officeId=1
+
+
+ +GET https://DomainName/api/v1/runreports/{reportName} + + +{ + "columnHeaders": [ + { + "columnName": "Office/Branch", + "columnType": "VARCHAR", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Client Account No.", + "columnType": "VARCHAR", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Name", + "columnType": "VARCHAR", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "Joined", + "columnType": "DATE", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [] + }, + { + "columnName": "External Id", + "columnType": "VARCHAR", + "isColumnNullable": false, + "isColumnPrimaryKey": false, + "columnValues": [] + } + ], + "data": [ + { + "row": [ + "Head Office", + "000000001", + "Petra Yton", + "2009-03-04", + "786YYH7" + ] + }, + { + "row": [ + "Head Office", + "000000002", + "Keith(changed) Yton", + "2009-03-04", + null + ] + }, + { + "row": [ + "Head Office", + "000000003", + "Jorge lastname", + "2013-02-05", + null + ] + } + ] +} + +
+
+ + +   +
+
+

Authentication HTTP Basic

+

An API capability that allows client applications to verify + authentication details using HTTP Basic Authentication.

+ + + + + + + + + + + +
Field Descriptions
base64EncodedAuthenticationKey
HTTP Basic Auth key. See Authentication Overview for + an example of its use. +
+
+
+ +   +
+
+

Verify authentication

+

Authenticates the credentials provided and returns the set roles and permissions allowed.

+
+
+ +POST https://DomainName/api/v1/authentication?username={username}&password={password} + + +POST authentication?username=mifos&password=password +Content-Type: application/json +No Request Body + +

Example response of autentication for user that is not linked with any staff.

+ +{ + "username": "mifos", + "userId": 1, + "base64EncodedAuthenticationKey": "bWlmb3M6cGFzc3dvcmQ=", + "authenticated": true, + "officeId": 1, + "officeName": "Head Office", + "roles": [ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } + ], + "permissions": [ + "ALL_FUNCTIONS" + ] +} + +

Example response of autentication for user that is linked with a staff member and role.

+ +{ + "username": "mifos", + "userId": 1, + "base64EncodedAuthenticationKey": "bWlmb3M6cGFzc3dvcmQ=", + "authenticated": true, + "officeId": 1, + "officeName": "Head Office", + "staffId": 1, + "staffDisplayName": "Director, Program", + "organisationalRole": { + "id": 100, + "code": "staffOrganisationalRoleType.programDirector", + "value": "Program Director" + }, + "roles": [ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } + ], + "permissions": [ + "ALL_FUNCTIONS" + ] +} + + + + + + + +POST authentication?username=mifos&password=fail +Content-Type: application/json +No Request Body + + +{ + "developerMessage": "Invalid authentication details were passed in api request.", + "developerDocLink": "https://github.com/openMF/mifosx/wiki/HTTP-API-Error-codes", + "httpStatusCode": "401", + "defaultUserMessage": "Unauthenticated. Please login.", + "userMessageGlobalisationCode": "error.msg.not.authenticated", + "errors": [] +} + +
+
+ +   +
+
+

Authentication Oauth2

+

An API capability that allows client applications to fetch current user details details using Oauth2.

+ + + + + + + + + + + +
Field Descriptions
accessToken
HTTP Auth bearer key. See Authentication Overview for + an example of its use. +
+
+
+ +   +
+
+

Authentication via OAuth2

+

API for requesting OAuth2 access token and refresh token.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
grant_type
Mandatory field. + Indicates the requested grant type. Supported values: + password. +
client_id
Mandatory field. + Indicates the client application identity. +
client_secret
Optional field. + Indicates the client application password. +
username
Mandatory field. + Application User(resource) login name. +
password
Mandatory field. + Application User(resource) password. +
+
+
+ +   +
+
+

OAuth2 Refresh and Access Token Request

+
+
+ +POST https://DomainName/api/oauth/token?username={username}&password={password}&client_id={clientId}&grant_type={grant_type}&client_secret={client_secret} + + +POST api/oauth/token?username=mifos&password=password&client_id=community-app&grant_type=password&client_secret=123 +Content-Type: application/json +No Request Body + + +{ + ""access_token": "b771987f-82fc-45ba-b521-bfe280c4e603", + "token_type": "bearer", + "refresh_token":"a2a89b23-8d22-4d90-8585-8f464db433b0", + "expires_in": 3599, + "scope": "all" +} + +
+
+ + +   +
+
+

Authentication via OAuth2

+

API for requesting OAuth2 access tokens through oAuth2 refresh tokens.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
grant_type
Mandatory field. + Indicates the requested grant type. Supported values: + refresh_token. +
client_id
Mandatory field. + Indicates the client application identity. +
client_secret
Optional field. + Indicates the client application password. +
refresh_token
Mandatory field. + Application refresh token to generate access token. +
+
+
+ +   +
+
+

OAuth2 Token Request through Refresh Token

+
+
+ +POST https://DomainName/api/oauth/token?refresh_token={refresh_token}&client_id={clientId}&grant_type={grant_type}&client_secret={client_secret} + + +POST api/oauth/token?client_id=community-app&grant_type=refresh_token&client_secret=123&refresh_token=a2a89b23-8d22-4d90-8585-8f464db433b0 +Content-Type: application/json +No Request Body + + +{ + ""access_token": "b771987f-82fc-45ba-b521-bfe280c4e643", + "token_type": "bearer", + "refresh_token":"a2a89b23-8d22-4d90-8585-8f464db433b0", + "expires_in": 3599, + "scope": "all" +} + +
+
+ +   +
+
+

Fetch authenticated user details

+

checks the Authentication and returns the set roles and permissions allowed.

+
+
+ +POST https://DomainName/api/v1/userdetails?access_token={access_token} + + +POST userdetails?access_token=bWlmb3M6cGFzc3dvcmQ= +Content-Type: application/json +No Request Body + +

Example response of authenticated user user that is not linked with any staff.

+ +{ + "username": "mifos", + "userId": 1, + "accessToken": "bWlmb3M6cGFzc3dvcmQ=", + "authenticated": true, + "officeId": 1, + "officeName": "Head Office", + "roles": [ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } + ], + "permissions": [ + "ALL_FUNCTIONS" + ] +} + +

Example response of authenticated user that is linked with a staff member and role.

+ +{ + "username": "mifos", + "userId": 1, + "accessToken": "bWlmb3M6cGFzc3dvcmQ=", + "authenticated": true, + "officeId": 1, + "officeName": "Head Office", + "staffId": 1, + "staffDisplayName": "Director, Program", + "organisationalRole": { + "id": 100, + "code": "staffOrganisationalRoleType.programDirector", + "value": "Program Director" + }, + "roles": [ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } + ], + "permissions": [ + "ALL_FUNCTIONS" + ] +} + + + + + + + +POST api/oauth/token?username=mifos&password=password&client_id=community-app&grant_type=password&client_secret=123 +Content-Type: application/json +No Request Body + + +{ + "developerMessage": "Invalid authentication details were passed in api request.", + "developerDocLink": "https://github.com/openMF/mifosx/wiki/HTTP-API-Error-codes", + "httpStatusCode": "401", + "defaultUserMessage": "Unauthenticated. Please login.", + "userMessageGlobalisationCode": "error.msg.not.authenticated", + "errors": [] +} + +
+
+ + +   +
+
+

Users

+

An API capability to support administration of application users.

+
+
+ +   +
+
+

Retrieve list of users

+

Example Requests:

+
users
+
+
+
users?fields=id,username,email,officeName
+
+
+ +GET https://DomainName/api/v1/users + + +[ + { + "id": 1, + "username": "mifos", + "officeId": 1, + "officeName": "Head Office", + "firstname": "App", + "lastname": "Administrator", + "email": "demomfi@mifos.org", + "passwordNeverExpires": false, + "staff": { + "id": 1, + "firstname": "Test", + "lastname": "123", + "displayName": "123, Test", + "mobileNo": "12312312", + "officeId": 1, + "officeName": "Head Office", + "isLoanOfficer": true, + "isActive": true + } + "selectedRoles": [ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } + ] + } +] + +
+
+ +   +
+
+

Retrieve User Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
users/template
+
+
+ +GET https://DomainName/api/v1/users/template + + +{ + "allowedOffices": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + } + ], + "availableRoles": [ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } + ] +} + +
+
+ +   +
+
+

Retrieve a User

+

Example Requests:

+
users/1
+
+
+
users/1?template=true
+
+
+
users/1?fields=username,officeName
+
+
+ +GET https://DomainName/api/v1/users/{userId} + + +{ + "id": 1, + "username": "mifos", + "officeId": 1, + "officeName": "Head Office", + "firstname": "App", + "lastname": "Administrator", + "email": "demomfi@mifos.org", + "passwordNeverExpires": true, + "staff": { + "id": 1, + "firstname": "Test", + "lastname": "123", + "displayName": "123, Test", + "mobileNo": "12312312", + "officeId": 1, + "officeName": "Head Office", + "isLoanOfficer": true, + "isActive": true + } + "availableRoles": [], + "selectedRoles": [ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } + ] +} + +
+
+ +   +
+
+

Create a User

+

Adds new application user.

+

+ Note: Password information is not required (or processed). + Password details at present are auto-generated and then sent to + the email account given (which is why it can take a few seconds to + complete). +

+ + + + + + + +
Mandatory Fields
username, firstname, lastname, email, officeId, roles, sendPasswordToEmail
+
+ + + + + + + +
Optional Fields
staffId,passwordNeverExpires,isSelfServiceUser,clients
+
+
+ +POST https://DomainName/api/v1/users + + +POST users +Content-Type: application/json +Request body: +{ + "username": "newuser", + "firstname": "Test", + "lastname": "User", + "email": "whatever@mifos.org", + "officeId": 1, + "staffId": 1, + "roles": [2,3], + "sendPasswordToEmail": true +} + + +{ + "officeId": 1, + "resourceId": 11 +} + + +POST users +Content-Type: application/json +Request body: +{ + "username": "newuser", + "firstname": "Test", + "lastname": "User", + "email": "whatever@mifos.org", + "officeId": 1, + "staffId": 1, + "roles": [2,3], + "sendPasswordToEmail": false, + "password": "123", + "repeatPassword": "123" +} + + +{ + "officeId": 1, + "resourceId": 12 +} + + +POST https://DomainName/api/v1/users + + +POST users +Content-Type: application/json +Request body: +{ + "username": "newuser", + "firstname": "Test", + "lastname": "User", + "email": "whatever@mifos.org", + "officeId": 1, + "staffId": 1, + "roles": [2,3], + "sendPasswordToEmail": true, + "isSelfServiceUser": true, + "clients": [1,2,3] +} + + +{ + "officeId": 1, + "resourceId": 11 +} + +
+
+ +   +
+
+

Update a User

+

+ Note: When updating a password you must provide the + repeatPassword parameter also. +

+
+
+ +PUT https://DomainName/api/v1/users/{userId) + + +PUT users/3 +Content-Type: application/json +Request body: +{ + "firstname": "Test", + "password": "window75", + "repeatPassword": "window75" +} + + +{ + "officeId": 1, + "resourceId": 3, + "changes": { + "firstname": "Test", + "passwordEncoded": "abc3326b1bb376351c7baeb4175f5e0504e33aadf6a158474a6d71de1befae51" + } +} + +
+
+ +   +
+
+

Delete a User

+

Removes the user and the associated roles and permissions.

+
+
+ +DELETE https://DomainName/api/v1/users/{userId} + + +DELETE users/20 +Content-Type: application/json +No Request Body + + +{ + "officeId": 1, + "resourceId": 20, + "changes": {} +} + +
+
+ + + +   +
+
+

Roles

+

An API capability to support management of application roles for user administration.

+
+
+ +   +
+
+

List Roles

+

Example Requests:

+
roles
+
+
+
roles?fields=name
+
+
+ +GET https://DomainName/api/v1/roles + + +[ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } +] + +
+
+ + +   +
+
+

Delete a Role

+

Description : Delete the role in case role is not associated with any users.

+
+
+ +DELETE https://DomainName/api/v1/roles/{roleId} + + +DELETE roles/20 +Content-Type: application/json +No Request Body + + +{ + "resourceId":1 +} + +
+
+ +   +
+
+

Retrieve a Role

+

Example Requests:

+
roles/1
+
+
+
roles/1?fields=name
+
+
+ +GET https://DomainName/api/v1/roles/{roleId} + + +{ + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." +} + +
+
+ +   +
+
+

Create a New Role

+ + + + + + + +
Mandatory Fields
name, description
+
+
+ +POST https://DomainName/api/v1/roles + + +POST roles +Content-Type: application/json +Request body: +{ + "name": "Another Role Name", + "description": "A description outlining the purpose of this role in relation to the application." +} + + { "resourceId": 2} +
+
+ +   +
+
+

Update a Role

+
+
+ +PUT https://DomainName/api/v1/roles/{roleId} + + +PUT roles/1 +Content-Type: application/json +Request body: +{ + "description": "some description(changed)" +} + + +{ + "resourceId": 1, + "changes": { + "description": "some description(changed)" + } +} + +
+
+ +   +
+
+

Retrieve a Role's Permissions

+

Example Requests:

+
roles/1/permissions
+
+
+ +GET https://DomainName/api/v1/roles/{roleId}/permissions + + +{ + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions.", + "permissionUsageData": [ + { + "grouping": "authorisation", + "code": "READ_PERMISSION", + "entityName": "PERMISSION", + "actionName": "READ", + "selected": false + }, + ... + { + "grouping": "transaction_loan", + "code": "WRITEOFF_LOAN_CHECKER", + "entityName": "LOAN", + "actionName": "WRITEOFF", + "selected": false + } + ] +} + +
+
+ +   +
+
+

Enable Role

+

Description : Enable role in case role is disabled.

+
+
+ +POST https://DomainName/api/v1/roles/{roleId}?command=enable + + +POST roles/1?command=enable +Content-Type: application/json +No Request Body + + +{ + "resourceId":1 +} + +
+
+ +   +
+
+

Disable Role

+

Description : Disable the role in case role is not associated with any users.

+
+
+ +POST https://DomainName/api/v1/roles/{roleId}?command=disable + + +POST roles/1?command=disable +Content-Type: application/json +No Request Body + + +{ + "resourceId":1 +} + +
+
+ +   +
+
+

Update a Role's Permissions

+
+
+ +PUT https://DomainName/api/v1/roles/{roleId}/permissions + + +PUT roles/8 +Content-Type: application/json +Request body: +{ + "permissions": { + "ALL_FUNCTIONS_READ": "true" + } +} + + +{ + "resourceId": 8, + "changes": { + "permissions": { + "ALL_FUNCTIONS_READ": true + } + } +} + +
+
+ + +   +
+
+

Permissions

+

An API capability to support management of application permissions for user administration.

+

There is no Apache Fineract functionality for creating or deleting permissions. Permissions come pre-installed.

+

Permissions are not updated, except in the case of enabling or disabling non-read transactions for + Maker Checker functionality

+
+
+ +   +
+
+

List Application Permissions

+
Arguments
+
+
makerCheckerable
+
optional, + Values are true, false. Default is false. +

If makerCheckerable=false or not supplied then a list of application permissions is returned. The "selected" + attribute is always true in this case. +

+

If makerCheckerable=true then the "selected" attribute shows whether the permission is + enabled for Maker Check functionality. +

+

+ Note: Each Apache Fineract transaction is associated with a permission. +

+
+
+

Example Requests:

+
permissions


+
permissions?makerCheckerable=true


+
permissions?fields=grouping,code
+
+
+ +GET https://DomainName/api/v1/permissions + + +[ + { + "grouping": "authorisation", + "code": "READ_PERMISSION", + "entityName": "PERMISSION", + "actionName": "READ", + "selected": true + }, + .... + { + "grouping": "transaction_loan", + "code": "WRITEOFF_LOAN", + "entityName": "LOAN", + "actionName": "WRITEOFF", + "selected": true + } +] + +
+
+ +   +
+
+

Enable/Disable Permissions for Maker Checker

+
+
+ +PUT https://DomainName/api/v1/permissions + + +PUT permissions +Content-Type: application/json +Request Body: +{ + "permissions":{ + "CREATE_GUARANTOR":true, + "CREATE_CLIENT":true + } +} + +
+
+ + +   +
+
+

Password preferences

+

This API enables management of password policy for user administration.

+

There is no Apache Fineract functionality for creating a validation policy. The validation policies come pre-installed.

+

Validation policies may be updated

+
+
+ +   +
+
+

List Application Password validation policies

+
Arguments
+
+ + +
+

Example Requests:

+
passwordpreferences


+
+
+ +GET https://DomainName/api/v1/passwordpreferences/template + + +[ +{ +"id": 1, +"description": "Password must be at least 1 character and not more that 50 characters long", +"active": true, +"key" : "simple" +}, +{ +"id": 2, +"description": "Password must be at least 6 characters, no more than 50 characters long, must include at least one upper case letter, one lower case letter, one numeric digit and no space", +"active": false, +"key" : "secure" +} +] + +
+ +
+ +GET https://DomainName/api/v1/passwordpreferences/ + + +{ +"id": 1, +"description": "Password most be at least 1 character and not more that 50 characters long", +"active": true, +"key" : "simple" +} + +
+
+ +   +
+
+

Update password preferences

+
+
+ +PUT https://DomainName/api/v1/passwordpreferences/ + + +PUT passwordpreferences +Content-Type: application/json +Request Body: +{ + "validationPolicyId" : 1, +} + +
+
+ +   +
+
+

General Ledger Account

+

Ledger accounts represent an Individual account within an Organizations Chart + Of Accounts(COA) and are assigned a name and unique number by which they can + be identified.
+ All transactions relating to a company's assets, liabilities, owners' equity, + revenue and expenses are recorded against these accounts +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
The name of the account
glCode
The ledger code associated with the + Account
These codes are mandatory and should be unique within + an organization
disabled
A boolean flag that indicates whether an account + is currently in use
type
Classifies the account into one of the following Types +
Asset: represent the different types of economic resources + owned or controlled by business, common examples of Asset accounts are cash, + cash in bank, building, inventory, prepaid rent, goodwill, accounts receivable
+ Liability: represent the different types of economic obligations + by a business, such as accounts payable, bank loan, bonds payable
+ Income: represent the company's gross earnings and common examples + include Interest Income, Sales and Service revenue
+ Expense: represent the company's expenditures to enable itself to + operate. Common examples are electricity and water, rentals, depreciation, + doubtful accounts, insurance.
+ Equity: represent the residual equity of a business (after + deducting from Assets all the liabilities) including Retained Earnings + and Appropriations

+ The options are fully listed in Retrieve + General Ledger Accounts Template. +
usage
Determines how the account shall be used
+ "Header" accounts specify the title of a group of accounts. They are used + only for grouping together detail accounts that have a similar purpose; that is, detail accounts + are assigned to specific header accounts +
+ "Detail" accounts may have transactions logged against them

+ The options are fully listed in Retrieve + General Ledger Accounts Template. +
manualEntriesAllowed
Specifies if manual entries can be made + against this account using the + Create Journal Entries API
description
Human understandable description for the Ledger Account +
parentId
To assign a parent for this GLAccount +
tagId
Used for tagging the Account Heads, based on GLAccount types. +
+
+
+ +   +
+
+

List General Ledger Accounts

+
Arguments
+
+
type
+
+ Integer optional +
+
manualEntriesAllowed
+
+ boolean optional +
+
usage
+
+ Integer optional +
+
disabled
+
+ boolean optional +
+
parentId
+
+ Long optional +
+
tagId
+
+ Long optional +
+
+

Example Requests:

+
glaccounts
+
+
+
glaccounts?type=1&manualEntriesAllowed=true&usage=1&disabled=false
+
+
glaccounts?fetchRunningBalance=true
+
+
+ +GET https://DomainName/api/v1/glaccounts + + +[ + { + "id": 16, + "name": "Cash", + "parentId": 1, + "glCode": "100001", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "description": "Desc", + "nameDecorated": "....Cash", + "tagId": { + "id": 10, + "name": "asset tag" + }, + "organizationRunningBalance": 118437, + }, + { + "id": 15, + "name": "Fund Source For Loan", + "glCode": "100002", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "description": "Desc", + "organizationRunningBalance": 118437, + } +] + +
+
+ +   +
+
+

Retrieve GL Accounts Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for client + applications. The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+

Example Request:

+
glaccounts/template
+
glaccounts/template?type=1
+
+ type is optional and integer value from 1 to 5.
+


1.Assets +
2.Liabilities +
3.Equity +
4.Income +
5.Expenses

+
+
+ +GET https://DomainName/api/v1/glaccounts/template
+GET https://DomainName/api/v1/glaccounts/template?type=1 +
+ +{ + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "accountTypeOptions": [ + { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + { + "id": 2, + "code": "accountType.liability", + "value": "LIABILITY" + }, + { + "id": 3, + "code": "accountType.equity", + "value": "EQUITY" + }, + { + "id": 4, + "code": "accountType.income", + "value": "INCOME" + }, + { + "id": 5, + "code": "accountType.expense", + "value": "EXPENSE" + } + ], + "usageOptions": [ + { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + { + "id": 2, + "code": "accountUsage.header", + "value": "HEADER" + } + ], + "assetHeaderAccountOptions": [ + { + "id": 1, + "name": "Two wheeler loan", + "glCode": "10001", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 2, + "code": "accountUsage.header", + "value": "HEADER" + }, + "nameDecorated": "Two wheeler loan", + "tagId": { + "id": 10, + "name": "asset tag" + } + }, + { + "id": 2, + "name": "VEHICLE LOAN", + "parentId": 1, + "glCode": "10002", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "usage": { + "id": 2, + "code": "accountUsage.header", + "value": "HEADER" + }, + "nameDecorated": "....VEHICLE LOAN", + "tagId": { + "id": 10, + "name": "asset tag" + } + } + ], + "liabilityHeaderAccountOptions": [ + { + "id": 15, + "name": "liabilitieschild", + "glCode": "ltchild", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 2, + "code": "accountType.liability", + "value": "LIABILITY" + }, + "usage": { + "id": 2, + "code": "accountUsage.header", + "value": "HEADER" + }, + "nameDecorated": "liabilitieschild", + "tagId": { + "id": 11, + "name": "liability tag" + } + } + ], + "equityHeaderAccountOptions": [ + { + "id": 13, + "name": "testajax", + "glCode": "12345678", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 3, + "code": "accountType.equity", + "value": "EQUITY" + }, + "usage": { + "id": 2, + "code": "accountUsage.header", + "value": "HEADER" + }, + "nameDecorated": "testajax", + "tagId": { + "id": 12, + "name": "Equity tag" + } + } + ], + "expenseHeaderAccountOptions": [ + { + "id": 8, + "name": "Salary", + "glCode": "450098", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 5, + "code": "accountType.expense", + "value": "EXPENSE" + }, + "usage": { + "id": 2, + "code": "accountUsage.header", + "value": "HEADER" + }, + "nameDecorated": "Salary", + "tagId": { + "id": 14, + "name": "Expenses Tag" + } + } + ], + "allowedAssetsTagOptions": [ + { + "id": 10, + "name": "asset tag", + "position": 0 + } + ], + "allowedLiabilitiesTagOptions": [ + { + "id": 11, + "name": "liability tag", + "position": 0 + } + ], + "allowedEquityTagOptions": [ + { + "id": 12, + "name": "Equity tag", + "position": 0 + } + ], + "allowedIncomeTagOptions": [ + { + "id": 13, + "name": "Income Tag", + "position": 0 + } + ], + "allowedExpensesTagOptions": [ + { + "id": 14, + "name": "Expenses Tag", + "position": 0 + } + ] +} + +
+
+ + +   +
+
+

Retrieve a General Ledger Account

+

Example Requests:

+
glaccounts/1
+
+
+
glaccounts/1?template=true
+
+
+
glaccounts/1?fields=name,glCode
+
+
+
glaccounts/1?fetchRunningBalance=true
+
+
+ +GET https://DomainName/api/v1/glaccounts/{glaccountsId} + + +{ + "id": 1, + "name": "Cash", + "glCode": "100001", + "disabled": false, + "manualEntriesAllowed": true, + "type": { + "id": 1, + "code": "accountType.asset1", + "value": "ASSET" + }, + "usage": { + "id": 1, + "code": "accountUsage.detail", + "value": "DETAIL" + }, + "description": "Desc", + "organizationRunningBalance": 118437, +} + +
+
+ +   +
+
+

Create a General Ledger Account

+

+ Note: You may optionally + create Hierarchical Chart of Accounts by using the "parentId" + property of an Account
+

+ + + + + + + +
Mandatory Fields
name, glCode, type, usage and manualEntriesAllowed +
+
+
+ +POST https://DomainName/api/v1/glaccounts + + +POST glaccounts +Content-Type: application/json +Request Body: +{ + "name": "Cash at Bangalore", + "glCode": "100017", + "manualEntriesAllowed": true, + "type": 1, + "tagId": "10", + "parentId": "18", + "usage": 1, + "description": "Cash at Bangalore Branch" +} + + +{ + "resourceId": 22 +} + +
+
+ +   +
+
+

Update a General Ledger Account

+
+
+ +PUT https://DomainName/api/v1/glaccounts/{glaccountId} + + +PUT glaccounts/22 +Content-Type: application/json +Request Body: +{ + "name": "Cash at Bangalore rural" +} + + +{ + "resourceId": 22, + "changes": { + "name": "Cash at Bangalore rural" + } +} + +
+
+ +PUT glaccounts/1 +Content-Type: application/json +Request Body: +{ + "disabled": true +} + + +{ + "resourceId": 1, + "changes": { + "disabled": true + } +} + +
+
+ +   +
+
+

Delete a General Ledger Account

+

+ Note: Only Ledger Accounts against which no transactions have been logged + (either manually or by the loan or Savings portfolio) can be deleted. +

+
+
+ +DELETE https://DomainName/api/v1/glaccounts/{glaccountId} + + +DELETE glaccounts/1 +Content-Type: application/json +No Request Body: + + +{ + "resourceId": 1, + "changes": {} +} + +
+
+ +   +
+
+

Accounting Closure

+

An accounting closure indicates that no more journal + entries may be logged (or reversed) in the system, + either manually or via the portfolio with an entry date + prior to the defined closure date +

+ + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
closingDate
The date for which the + accounting closure is defined
officeId
The identifer of the branch for + which accounting has been closed
comments
Description associated with an + Accounting closure
+
+
+ +   +
+
+

List Accounting closures

+

Example Requests:

+
glclosures
+
+
+
+
+ +GET https://DomainName/api/v1/glclosures + + +[ + { + "id": 7, + "officeId": 1, + "officeName": "Head Office", + "closingDate": [ + 2013, + 1, + 2 + ], + "deleted": false, + "createdDate": [ + 2013, + 1, + 3 + ], + "lastUpdatedDate": [ + 2013, + 1, + 3 + ], + "createdByUserId": 1, + "createdByUsername": "mifos", + "lastUpdatedByUserId": 1, + "lastUpdatedByUsername": "mifos", + "comments": "closed", + }, + { + "id": 6, + "officeId": 1, + "officeName": "Head Office", + "closingDate": [ + 2012, + 12, + 13 + ], + "deleted": false, + "createdDate": [ + 2012, + 12, + 14 + ], + "lastUpdatedDate": [ + 2012, + 12, + 14 + ], + "createdByUserId": 1, + "createdByUsername": "mifos", + "lastUpdatedByUserId": 1, + "lastUpdatedByUsername": "mifos", + "comments": "hello", + } +] + +
+
+ +   +
+
+

Retrieve an Accounting Closure

+

Example Requests:

+
glclosures/1
+
+
+
/glclosures/1?fields=officeName,closingDate
+
+
+ +GET https://DomainName/api/v1/glclosures/{glclosureId} + + +{ + "id": 7, + "officeId": 1, + "officeName": "Head Office", + "closingDate": [ + 2013, + 1, + 2 + ], + "deleted": false, + "createdDate": [ + 2013, + 1, + 3 + ], + "lastUpdatedDate": [ + 2013, + 1, + 3 + ], + "createdByUserId": 1, + "createdByUsername": "mifos", + "lastUpdatedByUserId": 1, + "lastUpdatedByUsername": "mifos", + "comments": "closed", +} + +
+
+ +   +
+
+

Create an Accounting Closure

+ + + + + + + +
Mandatory Fields
officeId,closingDate +
+
+
+ +POST https://DomainName/api/v1/glclosures + + +POST glclosures +Content-Type: application/json +Request Body: +{ + "officeId": 1, + "closingDate": "06 December 2012", + "comments": "The accountants are heading for a carribean vacation", + "locale": "en" , + "dateFormat": "dd MMMM yyyy" +} + + +{ + "officeId": 1, + "resourceId": 9 +} + +
+
+ +   +
+
+

Update an Accounting closure

+

Once an accounting closure is created, only the comments associated with it may be edited +

+
+
+ +PUT https://DomainName/api/v1/glclosures/{glclosureId} + + +PUT glclosures/1 +Content-Type: application/json +Request Body: +{ + "comments": "All transactions verified by Johnny Cash" +} + + +{ + "officeId": 1, + "resourceId": 1, + "changes": { + "comments": "All transactions verified by Johnny Cash" + } +} + +
+
+ +   +
+
+

Delete an accounting closure

+

+ Note: Only the latest accounting closure + associated with a branch may be deleted. +

+
+
+ +DELETE https://DomainName/api/v1/glclosures/{glclosureId} + + +DELETE glclosures/1 +Content-Type: application/json +No Request Body: + + +{ + "officeId": 1, + "resourceId": 1 +} + +
+
+ +   +
+
+

Journal Entries

+

A journal entry refers to the logging of + transactions against general ledger accounts. A journal + entry may consist of several line items, each of which is either a "debit" or a "credit". The total amount of the + debits must equal the total amount of the credits or the + journal entry is said to be "unbalanced"

+ A journal entry directly changes the account balances on + the general ledger +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
officeId
The identifier of the office ( + cost center) at which the financial activity + occured
currencyCode
A three letter ISO code of currency.
glAccountId
The identifier of the account ( + Ledger Account) against which this journal entry + was made +
transactionDate
The target date for which this + entry was recorded
amount
The Monetary amount associated + with this entry +
comments
A description associated with + this entry
entryType
Either a Credit(1) or a Debit(2)
transactionId
A unique Identifier for a set + of related Credit and Debit entries that make up + a "balanced" jounral Entry. For a manual entry, + this feild is a unique string.
+ For a system generated entry, the combination + of transactionId and entityId is unique +
manualEntry
Flag determines if an entry is + generated by the portfolio (posted automatically by + the system during the lifecycle of loan or saving + products) or manually created by using the Create (Balanced) Journal + Entries API +
reversed
Flag determines if this manual + journal entry has been reversed using the Reverse a Journal Entry + API.
+ Note: A journal entry is reversed by logging debits + for all credits that make up the Journal entry and + vice-versa +
referenceNumber
An additional field that is used to store additional information about the entry (Ex: chequeNo) +
accountingRule
Denotes the accounting rule id for posting journal entries. +
officeRunningBalance
Describes office balance after the journal entry for the Ledger Account. +
organizationRunningBalance
Describes complete organization balances after the journal entry for the Ledger Account. +
runningBalanceComputed
Describes whether account balances computed for the journal entry. +
transactionDetails
Additional details of transaction like payment details and notes . +
paymentTypeId
Maps to a Code value of a system defined Code with the name "PaymentType". This is used to optionally identify the mode of payment (Ex: checks, Cash etc) associated with a Journal Entry +
accountNumber, checkNumber, routingCode, receiptNumber, bankNumber
Various properties associated with a payment type +
+
+
+ +   +
+
+

List Journal Entries

+

The list capability of journal entries can support pagination and sorting.

+
Optional Arguments
+
+
offset
+
+ Integer optional, defaults to 0 +
+
Indicates from what result to start from.
+ +
limit
+
+ Integer optional, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
orderBy
+
+ String optional, one of displayName, accountNo, officeId, officeName +
+
Orders the results by the field indicated.
+ +
sortBy
+
+ String optional, one of ASC, DESC +
+
Indicates what way to order results if orderBy is used.
+ +
officeId
+
+ Integer optional +
+
Provides ability to restrict list of centers returned based on the office there associated with.
+ +
glAccountId
+
+ Integer optional +
+
manualEntriesOnly
+
+ Boolean optional +
+
Flag determines if only manually created journal entries + are to be returned( journal entries created by + the system during lifecycle of loan or saving + products etc shall be excluded) +
+ Set to "false" by default if not passed in explicity +
+
fromDate
+
+ Dateoptional +
+
Filters for Journal entries whose entry Date + is greater than or equal to the passed in Date +
+
toDate
+
+ Date optional +
+
Filters for Journal entries whose entry Date + is lesser than or equal to the passed in Date +
+
transactionId
+
+ String optional +
+
transactionDetails
+
+ Boolean optional +
+
Flag determines if additional transactional details + to be returned(like payment details and notes). +
+
runningBalance
+
+ Boolean optional +
+
Flag determines whether running balances + to be returned +
+
loanId
+
+ Integer optional +
+
Provides ability to restrict journal entries based on the loan they are associated with +
+
savingsId
+
+ Integer optional +
+
Provides ability to restrict journal entries based on the savings account they are associated with +
+
+

Example Requests:

+
journalentries
+
+
journalentries?transactionId=PB37X8Y21EQUY4S
+
+
journalentries?officeId=1&manualEntriesOnly=true&fromDate=1 July 2013&toDate=15 July 2013&dateFormat=dd MMMM yyyy&locale=en
+
+
journalentries?fields=officeName,glAccountName,transactionDate
+
+
journalentries?offset=10&limit=50
+
+
journalentries?orderBy=transactionId&sortOrder=DESC
+
+
journalentries?runningBalance=true
+
+
journalentries?transactionDetails=true
+
+
journalentries?loanId=12
+
+
journalentries?savingsId=24
+
+
+ +GET https://DomainName/api/v1/journalentries?transactionId=PB37X8Y21EQUY4S + + +{ + "totalFilteredRecords": 24, + "pageItems": [ + { + "id": 1, + "officeId": 1, + "officeName": "Head Office", + "glAccountName": "ACCOUNT_NAME_WTYRB", + "glAccountId": 98, + "glAccountCode": "ASSET_C01367768735188", + "glAccountType": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "transactionDate": [ + 2011, + 3, + 4 + ], + "entryType": { + "id": 2, + "code": "journalEntrytType.debit", + "value": "DEBIT" + }, + "amount": 10000, + "transactionId": "33", + "manualEntry": false, + "entityType": { + "id": 1, + "code": "productType.loan", + "value": "LOAN" + }, + "entityId": 7, + "createdByUserId": 1, + "createdDate": [ + 2013, + 5, + 5 + ], + "createdByUserName": "mifos", + "reversed": false, + }, + { + "id": 2, + "officeId": 1, + "officeName": "Head Office", + "glAccountName": "ACCOUNT_NAME_WTYRB", + "glAccountId": 98, + "glAccountCode": "ASSET_C01367768735188", + "glAccountType": { + "id": 1, + "code": "accountType.asset", + "value": "ASSET" + }, + "transactionDate": [ + 2011, + 3, + 4 + ], + "entryType": { + "id": 1, + "code": "journalEntryType.credit", + "value": "CREDIT" + }, + "amount": 10000, + "transactionId": "33", + "manualEntry": false, + "entityType": { + "id": 1, + "code": "productType.loan", + "value": "LOAN" + }, + "entityId": 7, + "createdByUserId": 1, + "createdDate": [ + 2013, + 5, + 5 + ], + "createdByUserName": "mifos", + "reversed": false, + + } + ] +} + +
+
+ +   +
+
+

Create "Balanced" Journal Entries

+

+ Note: A Balanced (simple) Journal entry would + have atleast one "Debit" and one "Credit" entry whose + amounts are equal
+ Compound Journal entries may have "n" debits and "m" + credits where both "m" and "n" are greater than 0 + and the net sum or all debits and credits are equal +
+

+ + + + + + + + + + + + + + + + + + + + + + +
Mandatory Fields
officeId, transactionDate +
credits
Details of the credits contained + in the journal entry. Each credit entry contains + the following items
+ glAccountId: Identifier of the general ledger + account against which the credit entry shall be + made
+ amount: Amount of money credited +
+ comments: Optional description associated with + a credit entry + . +
debits
Details of the debits contained + in the journal entry. Each debit entry contains the + following items
+ glAccountId: Identifier of the general ledger account + against which the debit entry shall be + made
+ amount: Amount of money debited +
+ comments: Optional description associated with + a debit entry + . +
+
+ + + + + + + +
Optional Fields
paymentTypeId, accountNumber, checkNumber, routingCode, receiptNumber, bankNumber
+
+
+ +POST https://DomainName/api/v1/journalentries + + +POST journalentries +Content-Type: application/json +Request Body: +{ +"officeId": 1, +"transactionDate": "06 December 2012", +"comments": "Gifts for staff", +"locale": "en" , +"currencyCode": "USD", +"dateFormat": "dd MMMM yyyy", +"credits":[{"glAccountId":1, + "amount":5000}, + {"glAccountId":2, + "amount":5000} + ], +"debits":[{"glAccountId":3, + "amount":5000}, + {"glAccountId":4, + "amount":5000} + ], +"paymentTypeId": "12", +"accountNumber": "accno123", +"checkNumber": "chec123", +"routingCode": "rou123", +"receiptNumber": "rec123", +"bankNumber": "ban123" +} + + +{ + "officeId": 1, + "transactionId": "DNEEMS2LPD0NJ9O" +} + + +POST https://DomainName/api/v1/journalentries + + +POST journalentries +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "officeId": "1", + "transactionDate": "23 May 2013", + "referenceNumber": "547", + "currencyCode": "USD", + "comments": "asdf", + "accountingRule": "2", + "amount": "547" +} + + +{ + "officeId":1, + "transactionId":"RS9MCISID4WK1ZM" +} + + +POST https://DomainName/api/v1/journalentries + + +POST journalentries +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "officeId": "1", + "transactionDate": "23 May 2013", + "referenceNumber": "547", + "comments": "asdf", + "accountingRule": "2", + "credits":[{"glAccountId":1, + "amount":5000}, + {"glAccountId":2, + "amount":5000} + ], + "debits":[{"glAccountId":3, + "amount":5000}, + {"glAccountId":4, + "amount":5000} + ] +} + + +{ + "officeId":1, + "transactionId":"RS9MCISID4WK1ZM" +} + + +POST https://DomainName/api/v1/journalentries + + +POST journalentries +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "officeId": "1", + "transactionDate": "23 May 2013", + "referenceNumber": "547", + "comments": "asdf", + "accountingRule": "3", + "credits":[{"glAccountId":1, + "amount":5000}, + {"glAccountId":2, + "amount":5000} + ], + "amount": "10000" +} + + +{ + "officeId":1, + "transactionId":"RS9MCISID4WK1ZM" +} + +
+
+ +   +
+
+

Update Running balances for Journal Entries

+

+ This API calculates the running balances for office. If office ID not provided this API calculates running balances for all offices. +
+

+ + + + + + + +
Mandatory Fields
officeId +
+
+
+ +POST https://DomainName/api/v1/journalentries?command=updateRunningBalance + + +POST journalentries?command=updateRunningBalance +Content-Type: application/json +Request Body: +{ +"officeId": 1, +} + + +{ + "officeId": 1, +} + + +
+
+ + +   +
+
+

Retrieve a single Entry

+

Example Requests:

+
journalentries/1
+
+
+
+
journalentries/1?fields=officeName,glAccountId,entryType,amount
+
+
journalentries/1?runningBalance=true
+
+
journalentries/1?transactionDetails=true
+
+
+ +GET https://DomainName/api/v1/journalentries/{entryId} + + +{ + "id": 1, + "officeId": 2, + "officeName": "sub branch 1", + "glAccountName": "Income from interest", + "glAccountId": 14, + "glAccountCode": "400001", + "glAccountType": { + "id": 4, + "code": "accountType.income", + "value": "INCOME" + }, + "transactionDate": [ + 2012, + 11, + 2 + ], + "entryType": { + "id": 1, + "code": "journalEntryType.credit", + "value": "CREDIT" + }, + "amount": 900, + "transactionId": "13", + "manualEntry": true, + "createdByUserId": 1, + "createdDate": [ + 2012, + 11, + 2 + ], + "createdByUserName": "mifos", + "reversed": false, +} + +
+
+ +   +
+
+

Reverse a Journal Entry

+

+ Note: A journal entry is reversed by logging debits + for all credits that constitute the Journal entry and + vice-versa. The transactionId of the "reversal Entry" is returned + as the methods response +

+
Arguments
+
+
command
+
+ String Mandatory, case-insensitive +
+
'reverse' : Reverse the Journal Entry
+
+
Optional Arguments
+
+
comments
+
+ String optional +
+
Optional string to be applied as a comment for the created reversal entry, + default comment is used if this field is not supplied
+
+
+
+ +GET https://DomainName/api/v1/journalentries/{transactionId}?command=reverse + + +POST journalentries/C1MAE935K0IAEYA?command=reverse +Content-Type: application/json + + +{ + "transactionId": "YFDYMPBVVI9TRJP" +} + +
+
+ + + +  +
+
+

Mapping Financial Activities to Accounts

+

+ Organization Level Financial Activities like Asset and Liability Transfer can be mapped to GL Account. Integrated accounting takes these accounts into consideration when an Account transfer is made between a savings to loan/savings account and vice-versa +

+ + + + + + + + + + + + + + + + +
Field Descriptions
financialActivityId
The identifier of the Financial Activity +
glAccountId
The identifier of a GL Account ( + Ledger Account) which shall be used as the default account for the selected Financial Activity +
+
+
+ +   +
+
+

List Financial Activities to Accounts Mappings

+

Example Requests:

+
financialactivityaccounts
+
+
+ +GET https://DomainName/api/v1/financialactivityaccounts + + + +[ + { + "id": 1, + "financialActivityData": { + "id": 200, + "name": "liabilityTransfer", + "mappedGLAccountType": "LIABILITY" + }, + "glAccountData": { + "id": 55, + "name": "Liability Transfer (Temp)", + "glCode": "220004-Temp" + } + }, + { + "id": 2, + "financialActivityData": { + "id": 100, + "name": "assetTransfer", + "mappedGLAccountType": "ASSET" + }, + "glAccountData": { + "id": 33, + "name": "Petty Cash", + "glCode": "20302" + } + } +] + +
+
+ +   +
+
+

Create a new Financial Activity to Accounts Mapping

+ + + + + + + + +
Mandatory Fields
financialActivityId, glAccountId +
+
+ +
+
+ +POST https://DomainName/api/v1/financialactivityaccounts + + +POST financialactivityaccounts +Content-Type: application/json +Request Body: +{ +"financialActivityId": 200, +"glAccountId":2 +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Update a Financial Activity to Account Mapping

+

+ the API updates the Ledger account linked to a Financial Activity +
+

+ +
+
+ +PUT https://DomainName/api/v1/financialactivityaccounts/{financialactivityaccountId} + + +PUT financialactivityaccounts +Content-Type: application/json +Request Body: +{ +"financialActivityId": 200, +"glAccountId":3 +} + + +{ + "resourceId": 2, + "changes": { + "glAccountId": 3 + } +} + + +
+
+ + +   +
+
+

Retrieve a Financial Activity to Account Mapping

+

Example Requests:

+
financialactivityaccounts/1
+
+
+
+ +GET https://DomainName/api/v1/financialactivityaccounts/{financialactivityaccountId} + + +{ + "id": 1, + "financialActivityData": { + "id": 200, + "name": "liabilityTransfer", + "mappedGLAccountType": "LIABILITY" + }, + "glAccountData": { + "id": 55, + "name": "Liability Transfer (Temp)", + "glCode": "220004-Temp" + } +} + +
+
+ +   +
+
+

Delete a Financial Activity to Account Mapping

+
+
+ +DELETE https://DomainName/api/v1/financialactivityaccounts/{financialactivityaccountId} + + +DELETE financialactivityaccounts/1? +Content-Type: application/json + + +{ + "resourceId": "2" +} + +
+
+ + + + +   +
+
+

Periodic Accrual Accounting

+

+ Periodic Accrual is to accrue the loan income till the specific date or till batch job scheduled time. +

+ + + + + + + + + + + +
Field Descriptions
tillDate
which specifies periodic accruals should happen till the given Date +
+
+
+ + + +   +
+
+

Executes Periodic Accrual Accounting

+ + + + + + + + +
Mandatory Fields
tillDate +
+
+ +
+
+ +POST https://DomainName/api/v1/runaccruals + + +POST financialactivityaccounts +Content-Type: application/json +Request Body: +{ + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "tillDate":"04 June 2014" +} + + + +
+
+ + +   +
+
+

Provisioning Entries

+

This defines the Provisioning Entries for all active loan products + + + + + + + + + + + + + + + + + +
Field Descriptions
date
Date on which day provisioning entries should be created +
createjournalentries
+ Boolean variable whether to add journal entries for generated provisioning entries +
+

+
+ +   +
+
+

Create new Provisioning Entries

+

Creates a new Provisioning Entries

+ + + + + + + + + + + + + +
Mandatory Fields
date
dateFormat
locale
+ + + + + + + +
Optional Fields
createjournalentries
+
+
+ + POST https://DomainName/api/v1/provisioningentries + + + POST provisioningentries + Content-Type: application/json + Request Body: + { + "date":"16 October 2015", + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "createjournalentries":true + } + + + { + "resourceId": 1 + } + +
+
+ +   +
+
+

List all Provisioning Entries

+

List all Provisioning Entries

+ +
+
+ + GET https://DomainName/api/v1/provisioningentries + + + GET provisioningentries + Content-Type: application/json + Request Body: + { + + } + + + {[ + {"id":1, "journalEntry":true, "createdUser":"mifos", "createdDate":"16 October 2014"}, + {"id":2, "journalEntry":true, "createdUser":"mifos", "createdDate":"16 October 2015"} + ] + } + +
+
+ +   +
+
+

Retrieves a Provisioning Entry

+

Returns the details of a generated Provisioning Entry.

+ +
+
+ + GET https://DomainName/api/v1/provisioningentries/{privisioningEntryId} + + + GET provisioningentries + Content-Type: application/json + Request Body: + { + + } + + + { + "id":1, + "journalEntry":true, + "createdUser":"mifos", + "createdDate":"16 October 2014", + "provisioningEntries":[ + {"historyId":1, + "officeId:":1 + "officeName:":"Head Office", + "currencyCode:":"USD", + "productId:":12, + "productName:":"Loan Product Name1", + "categoryId":4, + "categoryName":"LOSS", + "amountReserved":63098.29, + "liabilityAccount":4, + "liabilityCode":"Liability Account Name", + "expenseAccount":6, + "expenseCode":"Expense Account Name" + }, + {"id":2, + "journalEntry":true, + "createdUser":"mifos", + "createdDate":"16 October 2014", + "provisioningEntries":[ + {"historyId":1, + "officeId:":2 + "officeName:":"Branch Office", + "currencyCode:":"USD", + "productId:":12, + "productName:":"Loan Product Name1", + "categoryId":2, + "categoryName":"SUB-STANDARD", + "amountReserved":63098.29, + "liabilityAccount":1, + "liabilityCode":"Liability Account Name", + "expenseAccount":2, + "expenseCode":"Expense Account Name" + } + ] + + } + +
+
+ + +   +
+
+

Recreates Provisioning Entry

+

Recreates Provisioning Entry.

+ +
+
+ + POST https://DomainName/api/v1/provisioningentries/{privisioningEntryId}?command=recreateprovisioningentry + + + POST provisioningentries + Content-Type: application/json + Request Body: + { + "command":"recreateprovisioningentry" + } + + + { + "resourceId": 1 + } + +
+
+ +   +
+
+

Retrieves a Provisioning Entry

+

Returns the details of a generated Provisioning Entry.

+ +
+
+ + POST https://DomainName/api/v1/provisioningentries/{privisioningEntryId}?command=createjournalentry + + + POST provisioningentries + Content-Type: application/json + Request Body: + { + "command":"createjournalentry" + } + + + + { + "resourceId": 1 + } + +
+
+ + + + + +   +
+
+

Search

+

Search API allows to search scoped resources clients, loans and groups on specified fields.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Scoped Resources
Scoped fields
ClientDisplay Name
Account Number
External Id
LoanAccount Number
Client IdentifiersDocument Key
GroupName
Account Number
External Id
+
+
+   +
+
+

Search Resources

+

Example Requests:

+
search?query=000000001
+
+
search?query=Petra&resource=clients,groups
+
+
search?query=Petra&resource=clients,groups&exactMatch=true
+
+ + + + + + + + + + + + + + + + + +
Parameters
Description
+ query +
(mandatory) +
+ String which is searched on scoped resources +
+ resource +
(non-mandatory) +
+ Scoped resources on which search can be performed. If there is no resource parameter passed then search will be performed on all scoped resources. +
+ exactMatch +
(non-mandatory) +
+ Scoped resources on which search can be performed. If there is no exactMatch parameter passed then search will be performed for all partial matches scoped resources. +
+
+ + + + + + + + + + +
Order of Search results
+ List exact match results in following order +
    +
  1. 1. Clients
  2. +
  3. 2. Loans
  4. +
  5. 3. Client Identifiers
  6. +
  7. 4. Groups
  8. +
+
+ List partial match results in following order +
    +
  1. 1. Clients
  2. +
  3. 2. Loans
  4. +
  5. 3. Client Identifiers
  6. +
  7. 4. Groups
  8. +
+
+
+
+ +GET https://DomainName/api/v1/search?query=000000111 + + +[ + { + "entityId": 111, + "entityAccountNo": "000000111", + "entityName": "12-A Flat Loan", + "entityType": "LOAN", + "parentId": 65, + "parentName": "aaaa aaaaa", + "parentType": "client" + } +] + + + +GET https://DomainName/api/v1/search?query=000000001&exactMatch=true + + +[{ + "entityId": 1, + "entityAccountNo": "000000001", + "entityExternalId": "ID_JKZGEXF", + "entityName": "Group_Name_HVCU5", + "entityType": "GROUP", + "parentId": 1, + "parentName": "Head Office", + "entityStatus": { + "id": 300, + "code": "groupingStatusType.active", + "value": "Active" + } +}, +{ + "entityId": 1, + "entityAccountNo": "000000001", + "entityExternalId": "ID_UOZAGPZ", + "entityName": "Client_FirstName_KJ5B6 Client_LastName_KDGX", + "entityType": "CLIENT", + "parentId": 1, + "parentName": "Head Office", + "entityStatus": { + "id": 300, + "code": "clientStatusType.active", + "value": "Active" + } +}] + +
+
+   +
+
+

Advance Search

+

AdHoc Query search supported parameters and field descriptions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
entities
Entities to be included for search.(presently support added only for loans)
loanStatus
Loan status values to be included for search.
+ Supported loan status:["all","active","overpaid","closed","writeoff"] +
loanProducts
Array of loanproduct ids. +
offices
Array of office ids. +
loanDateOption
Date condition name for search query.
+ Supported values "approvalDate" or "createdDate" or "disbursalDate". +
loanFromDate
Start date for 'loanDateOption' in 'yyyy-MM-dd' format.
loanToDate
End date for 'loanDateOption' in 'yyyy-MM-dd' format.
includeOutStandingAmountPercentage
It is a Boolean value, allows to search percentage of loan outstanding amount with in a given range
outStandingAmountPercentageCondition
Condition type for outstanding amount percentage. + Supported values: between or <= or >= or < or > or =
+ When 'outStandingAmountPercentageCondition' is between required fields minOutStandingAmountPercentage and maxOutStandingAmountPercentage +
minOutStandingAmountPercentage
Minimum percentage of outstanding amount.
Mandatory when 'outStandingAmountPercentageCondition' type is 'between'
maxOutStandingAmountPercentage
Maximum percentage of outstanding amount.
Mandatory when 'outStandingAmountPercentageCondition' type is 'between'
outStandingAmountPercentage
Percentage of outstanding amount for search.
Mandatory when 'outStandingAmountPercentageCondition' type is otherthan 'between'
includeOutstandingAmount
Boolean value, allows user to search loan outstanding amount with in a given range
outstandingAmountCondition
Condition type to search outstanding amount. + Supported values: between or <= or >= or < or > or =
+ When 'outstandingAmountCondition' is between required fields minOutStandingAmount and maxOutStandingAmount +
minOutStandingAmount
Minimum value of outstanding amount for outstandingAmountCondition type between.
Mandatory when 'outstandingAmountCondition' type is 'between'
maxOutStandingAmount
Maximum value of outstanding amount for outstandingAmountCondition type between.
Mandatory when 'outstandingAmountCondition' type is 'between'
outStandingAmount
Default value of outstanding amount for search.
Mandatory when 'outstandingAmountCondition' type is otherthan 'between'
+
+
+   +
+
+

AdHoc Query Search

+

+ AdHocQuery search has more search options, it is a POST request, it uses request body to send search parameters
+

+ + + + + + + +
Mandatory Fields
entities
+
+ + + + + + + +
Optional Fields
+ loanStatus, loanProducts, offices, loanDateOption, loanFromDate, loanToDate,
includeOutStandingAmountPercentage, outStandingAmountPercentageCondition,
+ minOutStandingAmountPercentage and maxOutStandingAmountPercentage OR outStandingAmountPercentage,
includeOutstandingAmount, outstandingAmountCondition,
+ minOutstandingAmount and maxOutstandingAmount OR outstandingAmount
+
+
+ +POST https://DomainName/api/v1/search/advance + + +POST search/advance +Content-Type: application/json Request Body: +{ + "locale": "en", + "dateFormat": "yyyy-MM-dd", + "entities": ["loans"], + "loanStatus": ["all","active","overpaid"], + "loanProducts": ["65","97","73","82"], + "offices": ["1","10","100"], + "loanDateOption": "approvalDate", + "loanFromDate": "2013-01-01", + "loanToDate": "2014-01-27", + "includeOutStandingAmountPercentage": true, + "outStandingAmountPercentageCondition": "<=", + "outStandingAmountPercentage": "80", + "includeOutstandingAmount": true, + "outstandingAmountCondition": "between", + "minOutstandingAmount": "100", + "maxOutstandingAmount": "10000" +} + + +[{ + "officeName": "HFC", + "loanProductName": "01 BC3M", + "count": 86, + "loanOutStanding": 5692.41, + "percentage": 76.4 +}, +{ + "officeName": "keithoffice", + "loanProductName": "IGL", + "count": 3, + "loanOutStanding": 4168.23, + "percentage": 56.9 +}, +{ + "officeName": "Rio", + "loanProductName": "IGL", + "count": 1, + "loanOutStanding": 1681.12, + "percentage": 55.56 +}] + +
+
+ + + +   +
+
+

Interest Rate Chart

+

This defines an interest rate scheme that can be associated to a term deposit product. This will have a slab (band or range) of deposit periods and the associated interest rates applicable along with incentives for each band.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name of the interest rate chart. +
description
+ Description of Interest rate chart. +
fromDate
+ Date from when the chart is valid. The fromDate is mandatory and used to find out applicable interest rate chart for Accounts creation (FD & RD accounts). There should not be any overlapping of fromDate and endDate of charts for a product. +
endDate
+ Validity end date of the chart. This is optional, if not provided means it is the current chart applicable. +
+
+
+ +   +
+
+

Create a Chart

+

Creats a new chart which can be attached to a term deposit products (FD or RD).

+ + + + + + + +
Mandatory Fields
fromDate
+ + + + + + + +
Optional Fields
name, description and endDate
+ +
+
+ +POST https://DomainName/api/v1/interestratecharts + + +POST interestratecharts +Content-Type: application/json +Request Body: +{ + "name": "Chart - 2014", + "description": "This chart is applicable for year 2014", + "type": "Document", + "locale": "en", + "dateFormat": "dd MMMM yyyy", + "fromDate": "01 Jan 2014" +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve all Charts

+

Retrieve list of charts associated with a term deposit product(FD or RD).

+
Arguments
+
+
productId
+
+ Integer mandatory +
+
Retrieves Interest rate charts to a deposit product.
+
+

Example Requests:

+
interestratecharts?productId=1
+
+
+
+ +GET https://DomainName/api/v1/interestratecharts?productId={productId) + + +[ + { + "id": 1, + "fromDate": [ + 2014, + 1, + 1 + ], + "savingsProductId": 1, + "savingsProductName": "Fixed Deposit Product 001", + "chartSlabs": [ + { + "id": 1, + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 1, + "annualInterestRate": 6, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ] + } +] + +
+
+ +   +
+
+

Retrieve a Chart

+ +

Example Requests:

+
interestratecharts/1
+
+
+ +GET https://DomainName/api/v1/interestratecharts/{chartId} + + +{ + "id": 1, + "fromDate": [ + 2014, + 1, + 1 + ], + "savingsProductId": 1, + "savingsProductName": "Fixed Deposit Product 001", + "chartSlabs": [ + { + "id": 1, + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 1, + "annualInterestRate": 6, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ] +} + +
+
+ +   +
+
+

Update a Chart

+

+

+
+ +PUT https://DomainName/api/v1/interestratecharts/{chartId} + + +PUT interestratecharts/1 +Content-Type: application/json +Request Body: +{ + "name": "Interest rate chart for 2014", + "description": "Interest rate chart for 2014", +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Delete a Chart

+
+
+ +DELETE https://DomainName/api/v1/interestratecharts/{chartId} + + +DELETE interestratecharts/1 +Content-Type: application/json +No Request Body: + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve Chart Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for creating a chart. + The template data returned consists of any or all + of: +

    +
  • Field Defaults
  • +
  • Allowed Value Lists
  • +
+

+ +

Example Request:

+
interestratecharts/template
+
+
+ +GET https://DomainName/api/v1/interestratecharts/template + + +{ + "periodTypes": [ + { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + { + "id": 1, + "code": "interestChartPeriodType.weeks", + "value": "Weeks" + }, + { + "id": 2, + "code": "interestChartPeriodType.months", + "value": "Months" + }, + { + "id": 3, + "code": "interestChartPeriodType.years", + "value": "Years" + } + ] +} + +
+
+ + + + +   +
+
+

Interest Rate Slab (A.K.A interest bands)

+

The slabs a.k.a interest bands are associated with Interest Rate Chart. These bands allow to define different interest rates for different deposit term periods.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
periodType
The period type is used to define the different deposit term intervals. 0=Daily, 1=Weekly, 2=Monthly, 3=Yearly +
fromPeriod
Start of the period for defining deposit term interval. +
e.g. for 1 day to 180 days applicable interest rate is 5% +
then startPeriod=1, endPeriod=180 and periodType=0 +
toPeriod
End of the period for defining deposit term interval. +
e.g. for 1 day to 180 days applicable interest rate is 5% +
annualInterestRate
The applicable annual interest rate for defined term interval +
description
+ provide a description about the slab. +
incentives
+ Represents incentives on interest for a perticular period. +
+
+
+ +   +
+
+

Create a Slab

+

Creats a new interest rate slab for an interest rate chart.

+ + + + + + + +
Mandatory Fields
periodType, fromPeriod, annualInterestRate
+ + + + + + + +
Optional Fields
toPeriod and description
+

Example Requests:

+
interestratecharts/1/chartslabs
+
+
+ +POST https://DomainName/api/v1/interestratecharts/{chartId}/chartslabs + + +POST interestratecharts/{chartId}/chartslabs +Content-Type: application/json +Request Body: +{ + "periodType": "0", + "fromPeriod": "1", + "toPeriod": "180", + "annualInterestRate": "5", + "description": "5% interest from 1 day till 180 days of deposit", + "locale":"en", + "incentives":[{ + "entityType":"2", + "attributeName":2, + "conditionType":2, + "attributeValue":11, + "incentiveType":3, + "amount":"-1" + }] +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve all Slabs

+

Retrieve list of slabs associated with a chart

+ +

Example Requests:

+
interestratecharts/1/chartslabs
+
+
+
+ +GET https://DomainName/api/v1/interestratecharts/{chartId}/chartslabs + + +[ + { + "id": 1, + "description": "5% interest from 1 day till 180 days of deposit", + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 1, + "toPeriod": 180, + "annualInterestRate": 5, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "incentives":[{ + "id":1, + "entityType":{"id":2,"code":"InterestIncentiveEntityType.customer","value":"Customer"}, + "attributeName":{"id":2,"code":"InterestIncentiveAttributeName.gender","value":"Gender"}, "conditionType":{"id":2,"code":"incentiveConditionType.equal","value":"equal"}, + "attributeValue":"11","attributeValueDesc":"FEMALE", + "incentiveType":{"id":3,"code":"InterestIncentiveType.incentive","value":"Incentive"}, + "amount":-1.000000 + }] + } +] + +
+
+ +   +
+
+

Retrieve a Slab

+

Retrieve a slab associated with an Interest rate chart

+ +

Example Requests:

+
interestratecharts/1/chartslabs/1
+
+
+ +GET https://DomainName/api/v1/interestratecharts/{chartId}/chartslabs/{slabId} + + +{ + "id": 1, + "description": "changed to 6% interest ", + "periodType": { + "id": 0, + "code": "interestChartPeriodType.days", + "value": "Days" + }, + "fromPeriod": 1, + "toPeriod": 180, + "annualInterestRate": 6, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "incentives":[{ + "id":1, + "entityType":{"id":2,"code":"InterestIncentiveEntityType.customer","value":"Customer"}, + "attributeName":{"id":2,"code":"InterestIncentiveAttributeName.gender","value":"Gender"}, "conditionType":{"id":2,"code":"incentiveConditionType.equal","value":"equal"}, + "attributeValue":"11","attributeValueDesc":"FEMALE", + "incentiveType":{"id":3,"code":"InterestIncentiveType.incentive","value":"Incentive"}, + "amount":-1.000000 + }] +} + +
+
+ +   +
+
+

Update a Slab

+
+
+ +PUT https://DomainName/api/v1/interestratecharts/{chartId}/chartslabs/{slabId} + + +PUT interestratecharts/1/chartslabs/1 +Content-Type: application/json +Request Body: +{ + "annualInterestRate": "6", + "description": "Interest rate changed to 6%", +} + + +{ + "resourceId": 1, + "changes": { + "description": "Interest rate changed to 6%", + "annualInterestRate": 6 + } +} + +
+
+ +   +
+
+

Delete a Slab

+

Delete a Slab from a chart

+
+
+ +DELETE https://DomainName/api/v1/interestratecharts/{chartId}/chartslabs/{slabId} + + +DELETE interestratecharts/1/chartslabs/1 +Content-Type: application/json +No Request Body: + + +{ + "resourceId": 1 +} + +
+
+ + + + +   +
+
+

Teller Cash Management

+

Teller cash management which will allow an organization to manage their cash transactions at branches or head office more effectively.

+
+
+   +
+
+

List all tellers

+

Retrieves list tellers.


+
+
+ + GET https://DomainName/api/v1/tellers + + + [ + { + "id": 3, + "officeId": 1, + "debitAccountId": 0, + "creditAccountId": 0, + "name": "Teller3", + "description": "cash handling", + "startDate": [ + 2015, + 2, + 1 + ], + "status": "ACTIVE", + "officeName": "Head Office" + }, + { + "id": 2, + "officeId": 1, + "debitAccountId": 0, + "creditAccountId": 0, + "name": "Teller2", + "description": "abcc", + "startDate": [ + 2015, + 2, + 19 + ], + "endDate": [ + 2015, + 3, + 30 + ], + "status": "ACTIVE", + "officeName": "Head Office" + }, + { + "id": 1, + "officeId": 1, + "debitAccountId": 0, + "creditAccountId": 0, + "name": "Teller1", + "description": "abc", + "startDate": [ + 2015, + 2, + 20 + ], + "status": "ACTIVE", + "officeName": "Head Office" + }, + { + "id": 4, + "officeId": 2, + "debitAccountId": 0, + "creditAccountId": 0, + "name": "Teller4", + "description": "cash handling", + "startDate": [ + 2015, + 2, + 1 + ], + "status": "ACTIVE", + "officeName": "Office1" + } + ] + +
+
+ +   +
+
+

Create teller

+

+ + + + + + + +
Mandatory Fields
Teller name, OfficeId, Description, Start Date, Status
+ + + + + + + +
Optional Fields
End Date
+


+
+
+ + POST https://DomainName/api/v1/tellers + + + POST tellers + Content-Type: application/json + Request Body: + { + "officeId":2, + "name":"Teller4", + "description":"cash handling", + "status":300, + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "startDate":"01 February 2015" + } + + + { + "officeId": 2, + "resourceId": 5 + } + +
+
+ +   +
+
+

Retrieve tellers

+


+
+
+ + GET https://DomainName/api/v1/tellers/5 + + + { + "id": 5, + "officeId": 2, + "debitAccountId": 0, + "creditAccountId": 0, + "name": "Teller5", + "description": "cash handling", + "startDate": [ + 2015, + 2, + 1 + ], + "status": "ACTIVE", + "officeName": "Office1" + } + +
+
+ +   +
+
+

Update teller

+


+
+
+ + PUT https://DomainName/api/v1/tellers/{tellerId} + + + PUT tellers/5 + Content-Type: application/json + Request Body: + { + "name":"Teller5", + "officeId":2, + "description":"teller cash handling", + "status":300, + "endDate":"28 February 2015", + "startDate":"01 February 2015", + "locale":"en", + "dateFormat":"dd MMMM yyyy" + } + + + { + "officeId":2, + "resourceId":5, + "changes":{ + "description":"teller cash handling", + "endDate":"28 February 2015", + "dateFormat":"dd MMMM yyyy", + "locale":"en" + } + } + +
+
+ + +   +
+
+

List Cashiers

+


+
+
+ + GET https://DomainName/api/v1/tellers/{tellerId}/cashiers + + + { + "tellerId": 1, + "tellerName": "Teller1", + "officeId": 1, + "officeName": "Head Office", + "cashiers": [ + { + "id": 1, + "tellerId": 1, + "staffId": 1, + "description": "", + "startDate": "Feb 20, 2015 12:00:00 AM", + "endDate": "Feb 27, 2015 12:00:00 AM", + "isFullDay": true, + "startTime": "", + "endTime": "", + "tellerName": "Teller1", + "staffName": "Staff1, Test" + } + ] + } + +
+
+ +   +
+
+

Create Cashiers

+

+ + + + + + + +
Mandatory Fields
Cashier/staff, Fromm Date, To Date, Full Day or From time and To time
+ + + + + + + +
Optional Fields
Description/Notes
+


+
+
+ + POST https://DomainName/api/v1/tellers/{tellerId}/cashiers + + + POST tellers/1/cashiers + { + "endDate":"28 February 2015", + "description":"Cashier created", + "isFullDay":true, + "staffId":3, + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "startDate":"01 February 2015" + } + + + { + "resourceId":1, + "subResourceId":2 + } + +
+
+ +   +
+
+

Retrieve a cashier

+


+
+
+ + GET https://DomainName/api/v1/tellers/{tellerId}/cashiers/{cashierId} + + + { + "id": 1, + "tellerId": 1, + "staffId": 1, + "description": "", + "startDate": "Feb 20, 2015 12:00:00 AM", + "endDate": "Feb 27, 2015 12:00:00 AM", + "isFullDay": true, + "startTime": "", + "endTime": "", + "tellerName": "Teller1", + "staffName": "Staff1, Test" + } + +
+
+ + +   +
+
+

Update Cashier

+


+
+
+ + PUT https://DomainName/api/v1/tellers/{tellerId}/cashiers/{cashierId} + + + + + PUT tellers/1/cashiers/1 + { + "endDate":"25 February 2015", + "description":"Cashier updated.", + "isFullDay":true, + "staffId":4, + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "startDate":"01 February 2015" + } + + + { + "resourceId": 1, + "subResourceId": 1, + "changes": { + "description": "Cashier updated.", + "endDate": "25 February 2015", + "dateFormat": "dd MMMM yyyy", + "locale": "en" + } + } + +
+
+ +   +
+
+

Delete Cashier

+

+
+
+ + DELETE tellers/{tellerId}/cashiers/{cashierId} + + + DELETE tellers/1/cashiers/3 + Content-Type: application/json + Request Body: + { + } + + + { + "resourceId": 3 + } + +
+
+ +   +
+
+

Find Cashiers

+


+
+
+ + GET https://DomainName/api/v1/tellers/{tellerId}/cashiers/template + + + { + "tellerId":1, + "officeId":1, + "officeName":"Head Office", + "tellerName":"Teller1", + "staffOptions":[ + { + "id":1, + "displayName":"Staff1, Test" + }, + { + "id":2, + "displayName":"Staff, 2" + }, + { + "id":3, + "displayName":"Staff, 3" + } + ] + } + +
+
+ + +   +
+
+

Retrieve Cashier Transaction

+


+
+
+ + GET https://DomainName/api/v1/tellers/{tellerId}/cashiers/{cashierId}/transactions + + + [ + { + "id": 8, + "cashierId": 15, + "txnType": { + "id": 104, + "value": "Cash Out" + }, + "txnAmount": 10000, + "txnDate": "Feb 25, 2015 12:00:00 AM", + "entityId": 2, + "entityType": "loans", + "txnNote": "Disbursement, Loan:2-000000002,Client:1-Test 1", + "createdDate": "Feb 25, 2015 12:00:00 AM", + "officeId": 1, + "officeName": "Head Office", + "tellerId": 0, + "cashierName": "B, Ramesh" + }, + { + "id": 10, + "cashierId": 15, + "txnType": { + "id": 104, + "value": "Cash Out" + }, + "txnAmount": 8500, + "txnDate": "Feb 25, 2015 12:00:00 AM", + "entityId": 3, + "entityType": "loans", + "txnNote": "Disbursement, Loan:3-000000003,Client:3-Client 1", + "createdDate": "Feb 25, 2015 12:00:00 AM", + "officeId": 1, + "officeName": "Head Office", + "tellerId": 0, + "cashierName": "B, Ramesh" + }, + { + "id": 12, + "cashierId": 15, + "txnType": { + "id": 104, + "value": "Cash Out" + }, + "txnAmount": 10000, + "txnDate": "Feb 1, 2015 12:00:00 AM", + "entityId": 4, + "entityType": "loans", + "txnNote": "Disbursement, Loan:4-000000004,Client:4-Client 2", + "createdDate": "Feb 25, 2015 12:00:00 AM", + "officeId": 1, + "officeName": "Head Office", + "tellerId": 0, + "cashierName": "B, Ramesh" + }, + { + "id": 14, + "cashierId": 15, + "txnType": { + "id": 103, + "value": "Cash In" + }, + "txnAmount": 1266.52, + "txnDate": "Feb 1, 2015 12:00:00 AM", + "entityId": 4, + "entityType": "loans", + "txnNote": "Repayment, Loan:4-000000004,Client:4-Client 2", + "createdDate": "Feb 25, 2015 12:00:00 AM", + "officeId": 1, + "officeName": "Head Office", + "tellerId": 0, + "cashierName": "B, Ramesh" + }, + { + "id": 13, + "cashierId": 15, + "txnType": { + "id": 101, + "value": "Allocate Cash" + }, + "txnAmount": 50000, + "txnDate": "Feb 1, 2015 12:00:00 AM", + "entityId": 0, + "entityType": "", + "txnNote": "cash allocated on 1st Feb 2015", + "createdDate": "Feb 25, 2015 12:00:00 AM", + "officeId": 1, + "officeName": "Head Office", + "tellerId": 10, + "tellerName": "Ramesh(Teller/Cashier)", + "cashierName": "B, Ramesh" + }, + { + "id": 15, + "cashierId": 15, + "txnType": { + "id": 104, + "value": "Cash Out" + }, + "txnAmount": 10000, + "txnDate": "Feb 1, 2015 12:00:00 AM", + "entityId": 5, + "entityType": "loans", + "txnNote": "Disbursement, Loan:5-000000005,Client:5-Suresh D", + "createdDate": "Feb 25, 2015 12:00:00 AM", + "officeId": 1, + "officeName": "Head Office", + "tellerId": 0, + "cashierName": "B, Ramesh" + }, + { + "id": 17, + "cashierId": 15, + "txnType": { + "id": 103, + "value": "Cash In" + }, + "txnAmount": 1266.52, + "txnDate": "Feb 1, 2015 12:00:00 AM", + "entityId": 5, + "entityType": "loans", + "txnNote": "Repayment, Loan:5-000000005,Client:5-Suresh D", + "createdDate": "Feb 25, 2015 12:00:00 AM", + "officeId": 1, + "officeName": "Head Office", + "tellerId": 0, + "cashierName": "B, Ramesh" + }, + { + "id": 14, + "cashierId": 15, + "txnType": { + "id": 102, + "value": "Settle Cash" + }, + "txnAmount": 10000, + "txnDate": "Feb 1, 2015 12:00:00 AM", + "entityId": 0, + "entityType": "", + "txnNote": "cash settlement on 1 feb with 10k", + "createdDate": "Feb 25, 2015 12:00:00 AM", + "officeId": 1, + "officeName": "Head Office", + "tellerId": 10, + "tellerName": "Ramesh(Teller/Cashier)", + "cashierName": "B, Ramesh" + } + ] + +
+
+ + + +   +
+
+

Allocate Cash To Cashier

+

+ + + + + + + +
Mandatory Fields
Date, Amount, Currency, Notes/Comments
+


+
+
+ + POST https://DomainName/api/v1/tellers/{tellerId}/cashiers/{cashierId}/allocate + + + POST tellers/1/cashiers/1/allocate?command=allocate + { + "currencyCode":"USD", + "txnAmount":"5000", + "txnNote":"allocating cash", + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "txnDate":"01 February 2015" + } + + + { + "resourceId":1, + "subResourceId":4 + } + +
+
+ + +   +
+
+

Settle Cash From Cashier

+

+ + + + + + + +
Mandatory Fields
Date, Amount, Currency, Notes/Comments
+


+
+
+ + POST https://DomainName/api/v1/tellers/{tellerId}/cashiers/{cashierId}/settle + + + POST tellers/1/cashiers/1/settle?command=settle + { + "currencyCode":"USD", + "txnAmount":"2000", + "txnNote":"cash settlement", + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "txnDate":"20 February 2015" + } + + + { + "resourceId":1, + "subResourceId":5 + } + +
+
+ +   +
+
+

Transactions Wtih Summary For Cashier

+


+
+
+ + GET https://DomainName/api/v1/tellers/{tellerId}/cashiers/{cashierId}/summaryandtransactions + + + { + "sumCashAllocation":7000.000000, + "sumInwardCash":0, + "sumOutwardCash":0, + "sumCashSettlement":50.000000, + "netCash":6950.000000, + "officeName":"Head Office", + "tellerId":1, + "tellerName":"Teller1", + "cashierId":1, + "cashierName":"Staff1, Test", + "cashierTransactions":[ + { + "id":2, + "cashierId":1, + "txnType":{ + "id":101, + "value":"Allocate Cash" + }, + "txnAmount":2000.000000, + "txnDate":"Feb 20, 2015 12:00:00 AM", + "entityId":0, + "entityType":"", + "txnNote":"aaaa", + "createdDate":"Feb 20, 2015 12:00:00 AM", + "officeId":1, + "officeName":"Head Office", + "tellerId":1, + "tellerName":"Teller1", + "cashierName":"Staff1, Test" + }, + { + "id":3, + "cashierId":1, + "txnType":{ + "id":102, + "value":"Settle Cash" + }, + "txnAmount":50.000000, + "txnDate":"Feb 20, 2015 12:00:00 AM", + "entityId":0, + "entityType":"", + "txnNote":"bbbbbb", + "createdDate":"Feb 20, 2015 12:00:00 AM", + "officeId":1, + "officeName":"Head Office", + "tellerId":1, + "tellerName":"Teller1", + "cashierName":"Staff1, Test" + }, + { + "id":4, + "cashierId":1, + "txnType":{ + "id":101, + "value":"Allocate Cash" + }, + "txnAmount":5000.000000, + "txnDate":"Feb 1, 2015 12:00:00 AM", + "entityId":0, + "entityType":"", + "txnNote":"allocating cash", + "createdDate":"Feb 23, 2015 12:00:00 AM", + "officeId":1, + "officeName":"Head Office", + "tellerId":1, + "tellerName":"Teller1", + "cashierName":"Staff1, Test" + } + ] + } + +
+
+ + +   +
+
+

Retrieve Cashier Transaction Template

+


+
+
+ + GET https://DomainName/api/v1/tellers/{tellerId}/cashiers/{cashierId}/transactions/template + + + { + "cashierId":1, + "officeName":"Head Office", + "tellerId":1, + "tellerName":"Teller1", + "cashierName":"Staff1, Test", + "cashierData":{ + "id":1, + "tellerId":1, + "staffId":1, + "description":"", + "startDate":"Feb 20, 2015 12:00:00 AM", + "endDate":"Feb 27, 2015 12:00:00 AM", + "isFullDay":true, + "startTime":"", + "endTime":"", + "tellerName":"Teller1", + "staffName":"Staff1, Test" + }, + "startDate":"Feb 20, 2015 12:00:00 AM", + "endDate":"Feb 27, 2015 12:00:00 AM", + "currencyOptions":[ + { + "code":"USD", + "name":"US Dollar", + "decimalPlaces":2, + "displaySymbol":"$", + "nameCode":"currency.USD", + "displayLabel":"US Dollar ($)" + } + ] + } + +
+
+ + + + + + +   +
+
+

Payment Type

+

This defines the payment type + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name the payment type +
description
+ Description of payment type +
isCashPayment
+ Determines weather the payment type is cash or not. +
position
+ Can set the order in which the payment type should be displayed. +
+

+
+   +
+
+

Create a Payment Type

+

Creates a new Payment type

+ + + + + + + +
Mandatory Fields
name
+ + + + + + + +
Optional Fields
Description, isCashPayment,Position
+
+
+ + POST https://DomainName/api/v1/paymenttypes + + + POST paymenttype + Content-Type: application/json + Request Body: + { + "name":"cash", + "description":"cash payment type", + "isCashPayment":true, + "position":1 + } + + + { + "resourceId": 1 + } + +
+
+   +
+
+

Retrieve all Payment Types

+

Retrieve list of payment types

+ + +
+
+
+ + GET https://DomainName/api/v1/paymenttypes + + + [ + { + "id": 24, + "name": "PTC", + "description": "Cash", + "isCashPayment": true, + "position": 0 + }, + { + "id": 25, + "name": "mPay", + "description": "not chash payment", + "isCashPayment": false, + "position": 0 + }, + { + "id": 26, + "name": "mPesa", + "description": "non cash payment", + "isCashPayment": false, + "position": 0 + }, + { + "id": 27, + "name": "Mobile Money", + "description": "money transferred through mobile", + "isCashPayment": false, + "position": 0 + }, + { + "id": 13, + "name": "cash", + "description": "cash Payment", + "isCashPayment": true, + "position": 1 + } + ] + +
+
+   +
+
+

Retrieve a Payment Type

+

Retrieves a payment type

+
+
+ + GET https://DomainName/api/v1/paymenttypes/{paymentTypeId} + + + { + "id": 13, + "name": "cash", + "description": "cash Payment", + "isCashPayment": true, + "position": 1 + } + +
+
+   +
+
+

Update a Payment Type

+
+
+ + PUT https://DomainName/api/v1/paymenttypes/{paymnetTypeId} + + + PUT /paymenttypes/13 + { + "name":"mPay", + "description":"not a cash payment type", + "isCashPayment":false, + "position":3 + } + + + { + "resourceId": 13 + } + +
+
+   +
+
+

Delete a Payment Type

+

Deletes payment type

+
+
+ + DELETE https://DomainName/api/v1/paymenttypes/{paymentTypeId} + + + DELETE paymnettypes/13 + Content-Type: application/json + No Request Body: + + + { + "resourceId": 13 + } + +
+
+ +   +
+
+

Provisioning Criteria

+

This defines the Provisioning Criteria + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
Provisioning Criteria Name
Name the Provisioning Criteria +
Loan Products
+ Select all loan products for which provisioning criteria to be associated +
Provisioning Categories
+ Define minimum, maximum, percentage, liability account, expense account for all provisioning categories +
+

+
+ +   +
+
+

Create a new Provisioning Criteria

+

Creates a new Provisioning Criteria

+ + + + + + + + + + +
Mandatory Fields
criteriaName
provisioningcriteria
+ + + + + + + +
Optional Fields
loanProducts
+
+
+ + POST https://DomainName/api/v1/provisioningcriteria + + + POST provisioningcriteria + Content-Type: application/json + Request Body: + { + "criteriaName":"High Risk Products Criteria", + "loanProducts": [ + {"id": 1, + "name": "LOAN_PRODUCT_3ODPK1", + "includeInBorrowerCycle": false}, + {"id": 2, + "name": "LOAN_PRODUCT_BXW8NC", + includeInBorrowerCycle": false} + ], + "provisioningcriteria": [ + {"categoryId": 1, + "categoryName": "STANDARD", + "minAge": 0, + "maxAge": 3, + "provisioningPercentage": 1, + "liabilityAccount": 8, + "expenseAccount": 14}, + {"categoryId": 2, + "categoryName": "SUB-STANDARD", + "minAge": 1, + "maxAge": 5, + "provisioningPercentage": 2, + "liabilityAccount": 13, + "expenseAccount": 13}, + {"categoryId": 3, + "categoryName": "DOUBTFUL", + "minAge": 2, + "maxAge": 6, + "provisioningPercentage": 3, + "liabilityAccount": 9, + "expenseAccount": 10}, + {"categoryId": 4, + "categoryName": "LOSS", + "minAge": 3, + "maxAge": 7, + "provisioningPercentage": 4, + "liabilityAccount": 10, + "expenseAccount": 9}] + } + + + { + "resourceId": 1 + } + +
+
+   +
+
+

Retrieves all created Provisioning Criterias

+

Retrieves all created Provisioning Criterias

+
+
+ + GET https://DomainName/api/v1/provisioningcriteria + + + GET provisioningcriteria + Content-Type: application/json + Request Body: + { + } + + + { + [ + {"criteriaId":1, + "criteriaName":"High Risk Products Criteria", + "createdBy":"mifos"}, + {"criteriaId":2, + "criteriaName":"Low Risk Products Criteria", + "createdBy":"mifos"} + ] + } + +
+
+   +
+
+

Retrieves a Provisioning Criteria

+

Retrieves a Provisioning Criteria

+
+
+ + GET https://DomainName/api/v1/provisioningcriteria/{criteriaId} + + + GET provisioningcriteria/{criteriaId} + Content-Type: application/json + Request Body: + { + } + + + { + "criteriaId":1 + "criteriaName":"High Risk Products Criteria", + "loanProducts": [ + {"id": 1, + "name": "LOAN_PRODUCT_3ODPK1", + "includeInBorrowerCycle": false}, + {"id": 2, + "name": "LOAN_PRODUCT_BXW8NC", + includeInBorrowerCycle": false} + ], + "provisioningcriteria": [ + {"categoryId": 1, + "categoryName": "STANDARD", + "minAge": 0, + "maxAge": 3, + "provisioningPercentage": 1, + "liabilityAccount": 8, + "expenseAccount": 14}, + {"categoryId": 2, + "categoryName": "SUB-STANDARD", + "minAge": 1, + "maxAge": 5, + "provisioningPercentage": 2, + "liabilityAccount": 13, + "expenseAccount": 13}, + {"categoryId": 3, + "categoryName": "DOUBTFUL", + "minAge": 2, + "maxAge": 6, + "provisioningPercentage": 3, + "liabilityAccount": 9, + "expenseAccount": 10}, + {"categoryId": 4, + "categoryName": "LOSS", + "minAge": 3, + "maxAge": 7, + "provisioningPercentage": 4, + "liabilityAccount": 10, + "expenseAccount": 9}] + } + +
+
+   +
+
+

Updates a new Provisioning Criteria

+

Updates a new Provisioning Criteria

+ + + + + + + +
Optional Fields
criteriaName, loanProducts, provisioningcriteria
+
+
+ + PUT https://DomainName/api/v1/provisioningcriteria/{criteriaId} + + + PUT provisioningcriteria/{criteriaId} + Content-Type: application/json + Request Body: + { + "criteriaName":"High Risk Products Criteria1", + "loanProducts": [ + {"id": 1, + "name": "LOAN_PRODUCT_3ODPK1", + "includeInBorrowerCycle": false}, + {"id": 2, + "name": "LOAN_PRODUCT_BXW8NC", + includeInBorrowerCycle": false} + ], + "provisioningcriteria": [ + {"categoryId": 1, + "categoryName": "STANDARD", + "minAge": 0, + "maxAge": 3, + "provisioningPercentage": 1, + "liabilityAccount": 8, + "expenseAccount": 14}, + {"categoryId": 2, + "categoryName": "SUB-STANDARD", + "minAge": 1, + "maxAge": 5, + "provisioningPercentage": 2, + "liabilityAccount": 13, + "expenseAccount": 13}, + {"categoryId": 3, + "categoryName": "DOUBTFUL", + "minAge": 2, + "maxAge": 6, + "provisioningPercentage": 3, + "liabilityAccount": 9, + "expenseAccount": 10}, + {"categoryId": 4, + "categoryName": "LOSS", + "minAge": 3, + "maxAge": 7, + "provisioningPercentage": 4, + "liabilityAccount": 10, + "expenseAccount": 9}] + } + + + { + "resourceId": 1, + "changes": { + "criteriaName": "High Risk Products Criteria1" + } + } + +
+
+   +
+
+

Deletes Provisioning Criteria

+

Deletes Provisioning Criteria

+
+
+ + DELETE https://DomainName/api/v1/provisioningcriteria/{criteriaId} + + + DELETE provisioningcriteria/{criteriaId} + Content-Type: application/json + Request Body: + { + } + + + { + "resourceId": 1, + } + +
+
+ + +   +
+
+

Floating Rates

+

This defines the Floating Rates

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name of the Floating Rate, must be unique +
isBaseLendingRate
+ Identifies the Floating Rate scheme to be Base Lending Rate. Only one scheme can be Base Lending Rate at any given point of time. default is false. +
isActive
+ Identify if Floating Rate scheme is active or not. default is true. +
ratePeriods
+ Array of ratePeriod JSON objects as defined in below section. +
+

This defines the Floating Rates Periods

+ + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions for ratePeriods
fromDate
Start date from which this rate has to be considered. Should be a future date. +
interestRate
+ Interest Rate applicable. +
isDifferentialToBaseLendingRate
+ If false, interestRate field is considered absolute. + If true, interestRate field is considered differential to Base Lending Rate as of the startDate. + Cannot be used if there is no scheme defined as Base Lending Rate. +
+
+
+ +   +
+
+

Create a new Floating Rate

+

Creates a new Floating Rate

+ + + + + + + +
Mandatory Fields
name
+ + + + + + + + + + + + + +
Optional Fields
isBaseLendingRate
isActive
ratePeriods
+
+
+ + POST https://DomainName/api/v1/floatingrates + + + POST floatingrates + Content-Type: application/json + Request Body: + { + "name":"Floating Rate 1", + "isBaseLendingRate":true, + "isActive":true, + "ratePeriods":[ + { + "fromDate":"19 November 2015", + "interestRate":10, + "locale":"en", + "dateFormat":"dd MMMM yyyy" + }, + { + "fromDate":"15 December 2015", + "interestRate":11, + "locale":"en", + "dateFormat":"dd MMMM yyyy" + } + ] + } + + + { + "resourceId": 1 + } + +
+
+   +
+
+

List Floating Rates

+

List Floating Rates

+
+
+ + GET https://DomainName/api/v1/floatingrates + + + GET floatingrates + Content-Type: application/json + + + { + [ + { + "id": 1, + "name": "Floating Rate 1", + "isBaseLendingRate": true, + "isActive": true, + "createdBy": "mifos", + "createdOn": "Nov 18, 2015", + "modifiedBy": "mifos", + "modifiedOn": "Nov 18, 2015" + }, + { + "id": 2, + "name": "Floating Rate 2", + "isBaseLendingRate": false, + "isActive": true, + "createdBy": "mifos", + "createdOn": "Nov 18, 2015", + "modifiedBy": "mifos", + "modifiedOn": "Nov 18, 2015" + } + ] + } + +
+
+   +
+
+

Retrieve Floating Rate

+

Retrieve Floating Rate

+
+
+ + GET https://DomainName/api/v1/floatingrates/1 + + + GET floatingrates + Content-Type: application/json + + + { + "id": 1, + "name": "Floating Rate 1", + "isBaseLendingRate": true, + "isActive": true, + "createdBy": "mifos", + "createdOn": "Nov 18, 2015", + "modifiedBy": "mifos", + "modifiedOn": "Nov 18, 2015", + "ratePeriods": + [ + { + "id": 1, + "fromDate": "Dec 15, 2015", + "interestRate": 11, + "isDifferentialToBaseLendingRate": false, + "isActive": true, + "createdBy": "mifos", + "createdOn": "Nov 18, 2015", + "modifiedBy": "mifos", + "modifiedOn": "Nov 18, 2015" + }, + { + "id": 2, + "fromDate": "Nov 19, 2015", + "interestRate": 10, + "isDifferentialToBaseLendingRate": false, + "isActive": true, + "createdBy": "mifos", + "createdOn": "Nov 18, 2015", + "modifiedBy": "mifos", + "modifiedOn": "Nov 18, 2015" + } + ] + } + +
+
+   +
+
+

Update Floating Rate

+

Updates new Floating Rate. Rate Periods in the past cannot be modified. + All the future rateperiods would be replaced with the new ratePeriods data sent.

+
+
+ + PUT https://DomainName/api/v1/floatingrates/1 + + + PUT floatingrates + Content-Type: application/json + Request Body: + { + "name":"Floating Rate 1", + "isBaseLendingRate":true, + "isActive":true, + "ratePeriods":[ + { + "fromDate":"19 November 2015", + "interestRate":10, + "locale":"en", + "dateFormat":"dd MMMM yyyy" + }, + { + "fromDate":"15 December 2015", + "interestRate":11, + "locale":"en", + "dateFormat":"dd MMMM yyyy" + } + ] + } + + + { + "resourceId": 1, + "changes": + { + "ratePeriods": "[ + { + "fromDate":"19 November 2015", + "interestRate":10, + "locale":"en", + "dateFormat":"dd MMMM yyyy" + }, + { + "fromDate":"15 December 2015", + "interestRate":11, + "locale":"en", + "dateFormat":"dd MMMM yyyy" + } + ]" + } + } + +
+
+ + + +   +
+
+

User Generated Documents

+

User Generated Documents(alternatively, Templates) are used for end-user features such as custom user defined document generation (AKA UGD). They are based on {{ moustache }} templates. Think of them as a sort of built-in "mail merge" functionality.

+ +

User Generated Documents (and other types of templates) can aggregate data from several Apache Fineract back-end API calls via mappers. Mappers can even access non-Apache Fineract REST services from other servers. UGDs can render such data in tables, show images, etc. TBD: Please have a look at some of the Example UGDs included in Apache Fineract (or the Wiki page, for now.).

+ +

UGDs can be assigned to an entity like client or loan and be of a type like Document or SMS. The entity and type of a UGD is only there for the convenience of user agents (UIs), in order to know where to show UGDs for the user (i.e. which tab). The Template Engine back-end runner does not actually need this metadata.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Describes the document which will be created. + It must be unique and appears listed in a tab at the assigned entity.
type
+ For now only the types Document and SMS are supported. + In a next version, UGDs may be created for e-mails as well. +
entity
+ Indicates the primary resource reference. + UGDs may be filtered by entity and type so the relevant UGDs may be listed at the belonging position. +
text
+ The actual UGD which may be any html-text containing mustache tags. +
mappers
+ By default one mapper is assigned to the UGD depending on the entity. + Mappers are used to create requests and get tags wich may be used in the UGD. + Also mappery are in order and may depend on the previous mappers. + For now mappers expect a response in JSON or plain/text. + JSON contains the keys and the values. + If the response is plain/text it can be accessed by {{$mapperskey.src}} +
+
+
+ +   +
+
+

Retrieve UGD Details Template

+

This is a convenience resource. It can be useful when + building maintenance user interface screens for UGDs. + The UGD data returned consists of any or all of: +

+
Arguments
+
+
name
+
+ String +
+
entity
+
+ String +
+
type
+
+ String +
+
text
+
+ String optional +
+
mappers
+
+ Mapper optional +
+
+

Example Request:

+
templates/template
+
+
+ +GET https://DomainName/api/v1/templates/template + + +{ + "id": 1, + "name": "Test", + "entity": 1, + "type": 0, + "text": "This is a loan for {{loan.clientName}}", + "mappers": [ + { + "mappersorder": 0, + "mapperskey": "loan", + "mappersvalue": "loans/{{loanId}}?associations=all&tenantIdentifier={{tenantIdentifier}}", + "id": 1 + } + ] +} + +
+
+ +   +
+
+

Add a UGD

+

Adds a new UGD.

+ + + + + + + +
Mandatory Fields
name
+

Example Requests:

+
templates/1
+
+
+ +POST https://DomainName/api/v1/templates + + +POST templates +Content-Type: application/json +Request Body: +{ + "id": 1, + "name": "Test", + "entity": 1, + "type": 0, + "text": "This is a loan for {{loan.clientName}}", + "mappers": [ + { + "mappersorder": 0, + "mapperskey": "loan", + "mappersvalue": "loans/{{loanId}}?associations=all&tenantIdentifier={{tenantIdentifier}}", + "id": 1 + } + ] +} + + +{ + "resourceId": 1 +} + +
+
+ +   +
+
+

Retrieve all UGDs

+ +

Example Requests:

+
templates
+
+

+ It is also possible to get specific UGDs by entity and type: +

+
templates?type=0&entity=0
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Entity
Id
Type
Id
client0Document0
loan1E-Mail (not yet)1
SMS2
+
+
+ +GET https://DomainName/api/v1/templates + + +[ + { + "id": 1, + "name": "Test", + "entity": 1, + "type": 0, + "text": "This is a loan for {{loan.clientName}}", + "mappers": [ + { + "mappersorder": 0, + "mapperskey": "loan", + "mappersvalue": "loans/{{loanId}}?associations=all&tenantIdentifier={{tenantIdentifier}}", + "id": 1 + } + ] + } +] + +
+
+ +   +
+
+

Retrieve a UGD

+

Example Requests:

+
templates/1
+
+
+ +GET https://DomainName/api/v1/templates/{Id} + + +{ + "id": 1, + "name": "Test", + "entity": 1, + "type": 0, + "text": "This is a loan for {{loan.clientName}}", + "mappers": [ + { + "mappersorder": 0, + "mapperskey": "loan", + "mappersvalue": "loans/{{loanId}}?associations=all&tenantIdentifier={{tenantIdentifier}}", + "id": 1 + } + ] +} + +
+
+ +   +
+
+

Update a UGD

+
+
+ +PUT https://DomainName/api/v1/templates/{templateId} + + +PUT templates/1 +Content-Type: application/json +Request Body: +{ + "id": 1, + "name": "Test", + "entity": 1, + "type": 0, + "text": "This is a loan for {{loan.clientName}}", + "mappers": [ + { + "mappersorder": 0, + "mapperskey": "loan", + "mappersvalue": "loans/{{loanId}}?associations=all&tenantIdentifier={{tenantIdentifier}}", + "id": 1 + } + ] +} + + +{ + "resourceId": 1 +} + +
+
+ + + + +   +
+
+

Client Charges

+

It is typical for MFI's to directly associate charges with an implicit Client account. These + can be either fees or penalties

+

Client Charges are client specific instances of Charges. Refer Charges for documentation of the various properties of a charge, Only additional properties ( + specific to the context of a Charge being associated with a Client account) are + described here

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
amountPaid
The total amount which has been paid for this Charge +
amountWaived
The total amount that has been waived for this Charge +
amountOutstanding
The Total outstanding amount for this Charge +
dueDate
it specifies the due date
+
+
+ +   +
+
+

Client Transaction

+

Client Transactions refer to transactions made directly againt a Client's internal account. Currently, these transactions are only created as a result of charge payments/waivers. You are allowed to undo a transaction, however you cannot explicitly create one. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
id
This ia an unique Id associate with a Transaction. +
officeId
Identifier of the office in which the transaction was made
reversed
Boolean Flag that indicates if this transaction is reversed. +
amount
Transaction amount. +
currency
Details of the currency involved with the Transaction. Currently defaults + to the currency of the Client Charge this transaction pays
date
Effective date of the transaction
+
+
+   +
+
+

List Client Transactions

+

The list capability of client transaction can support pagination.

+
Mandatory Arguments
+
+
offset
+
+ Integer Mandatory, defaults to 0 +
+
Indicates the result from which pagination starts
+ +
limit
+
+ Integer Mandatory, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+
+

Example Requests:

+
clients/189/transactions
+
clients/189/transactions?offset=10&limit=50
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/transactions?limit=5&offset=0 + + +GET clients/226/transactions?limit=5&offset=0 +Content-Type: application/json +No Request Body: + + + +{ + "totalFilteredRecords": 20, + "pageItems": [ + { + "id": 226, + "officeId": 1, + "officeName": "Head Office", + "type": { + "id": 1, + "code": "clientTransactionType.payCharge", + "value": "PAY_CHARGE" + }, + "date": [ + 2015, + 9, + 2 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 22, + "submittedOnDate": [ + 2015, + 9, + 2 + ], + "reversed": false + } + ] +} + +
+
+ +   +
+
+

Retrieve a Client Transaction

+

Example Requests:

+
clients/1/transactions/1
+
+
+
clients/1/transactions/1?fields=id,officeName
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/transaction/{transactionId} + + +{ + "id": 1, + "officeId": 1, + "officeName": "Head Office", + "type": { + "id": 1, + "code": "clientTransactionType.payCharge", + "value": "PAY_CHARGE" + }, + "date": [ + 2015, + 8, + 17 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 60.000000, + "submittedOnDate": [ + 2015, + 8, + 19 + ], + "reversed": true +} + +
+
+ +   +
+
+

Add Client Charge

+

+ This API associates a Client charge with an implicit Client account +

+ + + + + + + +
Mandatory Fields
chargeId and dueDate
+ + + + + + + +
Optional Fields
amount
+
+
+ +POST https://DomainName/api/v1/clients/{clientId}/charges + + +POST clients/226/charges +Content-Type: application/json +Request Body: +{ + "amount" : "100", + "chargeId" : "226", + "dateFormat" : "dd MMMM yyyy", + "dueDate" : "01 September 2015", + "locale" : "en" +} + + +{ + "officeId": 1, + "clientId": 189, + "resourceId":164 +} + +
+
+   +
+
+

List Client Charges

+ +

The list capability of client charges supports pagination.

+
Optional Arguments
+
+
offset
+
+ Integer Mandatory, defaults to 0 +
+
Indicates the result from which pagination starts
+ +
limit
+
+ Integer Mandatory, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
pendingPayment
+
+ String optional +
+
Filters charges that are pending payment (neither paid or waived).
+
+

Example Requests:

+
clients/1/charges
+
clients/1/charges?offset=0&limit=5
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/charges?limit=5&offset=0 + + +GET clients/1/charges?limit=5&offset=0 +Content-Type: application/json +No Request Body + + +{ + "totalFilteredRecords": 4, + "pageItems": [ + { + "id": 5, + "clientId": 1, + "chargeId": 6, + "name": "Client Fees 2", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2015, + 9, + 1 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 550.000000, + "amountPaid": 0.000000, + "amountWaived": 0.000000, + "amountWrittenOff": 0, + "amountOutstanding": 550.000000, + "penalty": false, + "isActive": true, + "isPaid": false, + "isWaived": false + }, + { + "id": 4, + "clientId": 1, + "chargeId": 5, + "name": "Client Fee 1", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2015, + 8, + 31 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 120.000000, + "amountPaid": 0.000000, + "amountWaived": 120.000000, + "amountWrittenOff": 0, + "amountOutstanding": 120.000000, + "penalty": true, + "isActive": true, + "isPaid": false, + "isWaived": true + }, + { + "id": 3, + "clientId": 1, + "chargeId": 5, + "name": "Client Fee 1", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2015, + 8, + 17 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100.000000, + "amountPaid": 0.000000, + "amountWaived": 100.000000, + "amountWrittenOff": 0, + "amountOutstanding": 0.000000, + "penalty": true, + "isActive": true, + "isPaid": false, + "isWaived": true + }, + { + "id": 2, + "clientId": 1, + "chargeId": 2, + "name": "Recurring savings Charge", + "chargeTimeType": { + "id": 7, + "code": "chargeTimeType.monthlyFee", + "value": "Monthly Fee" + }, + "dueDate": [ + 2015, + 8, + 17 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100.000000, + "amountPaid": 0, + "amountWaived": 100.000000, + "amountWrittenOff": 0, + "amountOutstanding": 0.000000, + "penalty": false, + "isActive": true, + "isPaid": false, + "isWaived": true + } + ] +} + + +
+
+   +
+
+

Retrieve a Client Charge

+
Arguments
+
+
associations
+
+ optional, Either 'all' or a comma separated list of + loan 'associations' (itemised below). +
+
+
Associations are just extra pieces of data that you + might or might not want to retrieve.
+
+
+
+ 'all': Gets all association data. +
+
+ 'transactions': Retrieves all transactions made on this client charge. +
+
+

Example Requests:

+
clients/1/charges/1
+
+
+
clients/1/charges/1?fields=name,id
+
+
+ +GET https://DomainName/api/v1/clients/{clientId}/charges/{clientChargeId} + + +{ + "id": 3, + "clientId": 1, + "chargeId": 5, + "name": "Client Fee 1", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2015, + 8, + 17 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100.000000, + "amountPaid": 0.000000, + "amountWaived": 100.000000, + "amountWrittenOff": 0, + "amountOutstanding": 0.000000, + "penalty": true, + "isActive": true, + "isPaid": false, + "isWaived": true +} + +
+
+ +   +
+
+

Delete a Client Charge

+

+ Deletes a Client Charge on which no transactions have taken place (either payments or waivers).

+
+
+ +DELETE https://DomainName/api/v1/clients/{clientId}/charges/{clientChargeId} + + +POST clients/189/charges/164 +Content-Type: application/json +No Request Body + + +{ + "officeId": 1, + "clientId": 189, + "resourceId":164 +} + +
+
+   +
+
+

Pay a Client Charge

+

+
Pay either a part of or the entire due amount for a charge. +

+ + + + + + + +
Mandatory Fields
+ transactionDate and amount +
+
+
+
+ +POST https://DomainName/api/v1/clients/{clientId}/charges/{clientChargeId}?command=paycharge + + +POST clients/189/charges/157?command=payCharge +Content-Type: application/json +Request Body: +{ + + "amount":200, + "locale":"en", + "dateFormat":"dd MMMM yyyy", + "transactionDate":"01 September 2015" +} + + + +{ + "officeId":1, + "clientId":189, + "resourceId":157, + "transactionId":"221" +} + +
+
+   +
+
+

Waive a Client Charge

+

+
This API provides the facility of waiving off the remaining amount on a client charge +

+ +
+
+ +POST https://DomainName/api/v1/clients/{clientId}/charges/{clientChargeId}?command=waive + + +POST clients/189/charges/157?command=waive +Content-Type: application/json +No Request Body + + + +{ + "clientId":"189", + "resourceId":157 +} + +
+
+ +   +
+
+

Undo a Client Transaction

+
+
+ +POST https://DomainName/api/v1/clients/{clientId}/transactions/{transactionId}?command=undo + + +POST clients/189/transactions/222?command=undo +Content-Type: application/json +No Request Body + + + +{ +"officeId":1, +"clientId":189, +"resourceId":222 +} + +
+
+ +   +
+
+

Delete a UGD

+
+
+ +DELETE https://DomainName/api/v1/templates/{templateId} + + +DELETE templates/1 +Content-Type: application/json +No Request Body: + + +{ + "resourceId": 1 +} + +
+
+ + + +   +
+
+

SPM API

+

+ The Apache Fineract SPM API provides the ability to create custom surveys to collect social performance measurentment data or any additional questionnaire a financial institute want to collect. +

+
+
+   +
+
+

Create a Survey

+

Adds a new survey to collect client related data.

+ + + + + + + +
Mandatory Fields
countryCode, key, name, questions, responses, sequenceNo, text, value
+
+
+ +POST https://DomainName/api/v1/surveys + + +POST surveys +Content-Type: application/json +Request Body: +{ + "key":"ppi-kenya-2010", + "name":"PPI Survey for Kenya, version 2010", + "description":null, + "countryCode":"KE", + "validFrom":null, + "validTo":null, + "componentDatas": + [ + { + "key":"Household", + "text":"Information about the household.", + "description":null, + "sequenceNo":1 + } + ], + "questionDatas": + [ + { + "componentKey":"Household", + "key":"Familiy members", + "text":"How many persons live in the household?", + "description":null, + "sequenceNo":1, + "responseDatas": + [ + { + "text":"1 to 3", + "value":1, + "sequenceNo":1 + }, + { + "text":"3 to 7", + "value":5, + "sequenceNo":2 + }, + { + "text":"more than 7", + "value":13, + "sequenceNo":3 + } + ] + } + ] +} + + +200 OK + +
+
+   +
+
+

List all Surveys

+
+
+ +GET https://DomainName/api/v1/surveys + + +GET surveys +Content-Type: application/json +No Request Body + + +[ + { + "id": 1, + "componentDatas": [ + { + "id": 1, + "key": "Household", + "text": "Information about the household.", + "description": null, + "sequenceNo": 1 + } + ], + "questionDatas": [ + { + "id": 1, + "responseDatas": [ + { + "id": 1, + "text": "1 to 3", + "value": 1, + "sequenceNo": 1 + }, + { + "id": 2, + "text": "3 to 7", + "value": 5, + "sequenceNo": 2 + }, + { + "id": 3, + "text": "more than 7", + "value": 13, + "sequenceNo": 3 + } + ], + "componentKey": "Household", + "key": "Familiy members", + "text": "How many persons live in the household?", + "description": null, + "sequenceNo": 1 + } + ], + "key": "ppi-kenya-2010", + "name": "PPI Survey for Kenya, version 2010", + "description": null, + "countryCode": "KE", + "validFrom": 1450047600000, + "validTo": 4607276399000 + } +] + +
+
+   +
+
+

Retrieve a Survey

+
+
+ +GET https://DomainName/api/v1/surveys/1 + + +GET surveys/1 +Content-Type: application/json +No Request Body + + +{ + "id": 1, + "componentDatas": [ + { + "id": 1, + "key": "Household", + "text": "Information about the household.", + "description": null, + "sequenceNo": 1 + } + ], + "questionDatas": [ + { + "id": 1, + "responseDatas": [ + { + "id": 1, + "text": "1 to 3", + "value": 1, + "sequenceNo": 1 + }, + { + "id": 2, + "text": "3 to 7", + "value": 5, + "sequenceNo": 2 + }, + { + "id": 3, + "text": "more than 7", + "value": 13, + "sequenceNo": 3 + } + ], + "componentKey": "Household", + "key": "Familiy members", + "text": "How many persons live in the household?", + "description": null, + "sequenceNo": 1 + } + ], + "key": "ppi-kenya-2010", + "name": "PPI Survey for Kenya, version 2010", + "description": null, + "countryCode": "KE", + "validFrom": 1450047600000, + "validTo": 4607276399000 +} + +
+
+   +
+
+

Deactivate Survey

+
+
+ +DELETE https://DomainName/api/v1/surveys/1 + + +DELETE surveys/1 +Content-Type: application/json +No Request Body + + +200 OK + +
+
+   +
+
+

Create a Lookup Table entry

+

Add a new netry to a survey.

+ + + + + + + +
Mandatory Fields
key, score, validFrom, validTo
+
+
+ +POST https://DomainName/api/v1/surveys/1/lookuptables + + +POST surveys/1/lookuptables +Content-Type: application/json +Request Body: +{ + "key": "test-table", + "description": null, + "entries": [ + { + "valueFrom": 0, + "valueTo": 25, + "score": 100 + }, + { + "valueFrom": 26, + "valueTo": 50, + "score": 50 + }, + { + "valueFrom": 51, + "valueTo": 75, + "score": 25 + }, + { + "valueFrom": 76, + "valueTo": 100, + "score": 0 + } + ] +} + + +200 OK + +
+
+   +
+
+

List all Lookup Table entries

+

List all Lookup Table entries for a survey.

+
+
+ +GET https://DomainName/api/v1/surveys/1/lookuptables + + +GET surveys/1/lookuptables +Content-Type: application/json +No Request Body + + +[ + { + "key": "test-table", + "description": null, + "entries": [ + { + "valueFrom": 0, + "valueTo": 25, + "score": 100 + }, + { + "valueFrom": 26, + "valueTo": 50, + "score": 50 + }, + { + "valueFrom": 51, + "valueTo": 75, + "score": 25 + }, + { + "valueFrom": 76, + "valueTo": 100, + "score": 0 + } + ] + } +] + +
+
+   +
+
+

Retrieve a Lookup Table entry

+

Retrieve a Lookup Table entry for a survey.

+
+
+ +GET https://DomainName/api/v1/surveys/1/lookuptables/1 + + +GET surveys/1/lookuptables/test-table +Content-Type: application/json +No Request Body + + +{ + "key": "test-table", + "description": null, + "entries": [ + { + "valueFrom": 0, + "valueTo": 25, + "score": 100 + }, + { + "valueFrom": 26, + "valueTo": 50, + "score": 50 + }, + { + "valueFrom": 51, + "valueTo": 75, + "score": 25 + }, + { + "valueFrom": 76, + "valueTo": 100, + "score": 0 + } + ] +} + +
+
+ +   +
+
+

Create a Scorecard entry

+

Add a new netry to a survey.

+ + + + + + + +
Mandatory Fields
clientId, createdOn, questionId, responseId, staffId
+
+
+ +POST https://DomainName/api/v1/surveys/1/scorecards + + +POST surveys/1/scorecards +Content-Type: application/json +Request Body: +{ + "userId": 1, + "clientId": 1, + "createdOn": 1451905784553, + "scorecardValues": + [ + { + "questionId": 1, + "responseId": 1, + "value": 0 + }, + { + "questionId": 2, + "responseId": 8, + "value": 0 + }, + { + "questionId": 3, + "responseId": 12, + "value": 7 + }, + { + "questionId": 4, + "responseId": 16, + "value": 4 + }, + { + "questionId": 5, + "responseId": 21, + "value": 2 + }, + { + "questionId": 6, + "responseId": 25, + "value": 2 + }, + { + "questionId": 7, + "responseId": 28, + "value": 3 + }, + { + "questionId": 8, + "responseId": 30, + "value": 6 + }, + { + "questionId": 9, + "responseId": 33, + "value": 4 + }, + { + "questionId": 10, + "responseId": 37, + "value": 7 + } + ] +} + +200 OK + +
+
+   +
+
+

List all Scorecard entries

+

List all Scorecard entries for a survey.

+
+
+ +GET https://DomainName/api/v1/surveys/1/scorecards + + +GET surveys/1/scorecards +Content-Type: application/json +No Request Body + + +[ + { + "userId": 1, + "clientId": 1, + "createdOn": 1451905784553, + "scorecardValues": + [ + { + "questionId": 1, + "responseId": 1, + "value": 0 + }, + { + "questionId": 2, + "responseId": 8, + "value": 0 + }, + { + "questionId": 3, + "responseId": 12, + "value": 7 + }, + { + "questionId": 4, + "responseId": 16, + "value": 4 + }, + { + "questionId": 5, + "responseId": 21, + "value": 2 + }, + { + "questionId": 6, + "responseId": 25, + "value": 2 + }, + { + "questionId": 7, + "responseId": 28, + "value": 3 + }, + { + "questionId": 8, + "responseId": 30, + "value": 6 + }, + { + "questionId": 9, + "responseId": 33, + "value": 4 + }, + { + "questionId": 10, + "responseId": 37, + "value": 7 + } + ] + } +] + +
+
+ + + +
+
+

Self Service APIs

+
+
+   +
+
+

Verify authentication

+

Authenticates the credentials provided and returns the set roles and permissions allowed.

+
+
+ +POST https://DomainName/api/v1/self/authentication?username={username}&password={password} + + +POST self/authentication?username=mifos&password=password +Content-Type: application/json +No Request Body + +

Example response of autentication for user

+ +{ + "username": "mifos", + "userId": 1, + "base64EncodedAuthenticationKey": "bWlmb3M6cGFzc3dvcmQ=", + "authenticated": true, + "officeId": 1, + "officeName": "Head Office", + "staffId": 1, + "staffDisplayName": "Director, Program", + "organisationalRole": { + "id": 100, + "code": "staffOrganisationalRoleType.programDirector", + "value": "Program Director" + }, + "roles": [ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } + ], + "permissions": [ + "ALL_FUNCTIONS" + ], + "isSelfServiceUser": true, + "clients": [1,2,3] +} + + + +POST self/authentication?username=mifos&password=fail +Content-Type: application/json +No Request Body + + +{ + "developerMessage": "Invalid authentication details were passed in api request.", + "developerDocLink": "https://github.com/openMF/mifosx/wiki/HTTP-API-Error-codes", + "httpStatusCode": "401", + "defaultUserMessage": "Unauthenticated. Please login.", + "userMessageGlobalisationCode": "error.msg.not.authenticated", + "errors": [] +} + +
+
+ +   +
+
+

Fetch authenticated user details

+

checks the Authentication and returns the set roles and permissions allowed.

+
+
+ +POST https://DomainName/api/v1/userdetails?access_token={access_token} + + +POST userdetails?access_token=bWlmb3M6cGFzc3dvcmQ= +Content-Type: application/json +No Request Body + +

Example response of authenticated user.

+ +{ + "username": "mifos", + "userId": 1, + "base64EncodedAuthenticationKey": "bWlmb3M6cGFzc3dvcmQ=", + "authenticated": true, + "officeId": 1, + "officeName": "Head Office", + "staffId": 1, + "staffDisplayName": "Director, Program", + "organisationalRole": { + "id": 100, + "code": "staffOrganisationalRoleType.programDirector", + "value": "Program Director" + }, + "roles": [ + { + "id": 1, + "name": "Super user", + "description": "This role provides all application permissions." + } + ], + "permissions": [ + "ALL_FUNCTIONS" + ], + "isSelfServiceUser": true, + "clients": [1,2,3] +} + + + +POST api/oauth/token?username=mifos&password=password&client_id=community-app&grant_type=password&client_secret=123 +Content-Type: application/json +No Request Body + + +{ + "developerMessage": "Invalid authentication details were passed in api request.", + "developerDocLink": "https://github.com/openMF/mifosx/wiki/HTTP-API-Error-codes", + "httpStatusCode": "401", + "defaultUserMessage": "Unauthenticated. Please login.", + "userMessageGlobalisationCode": "error.msg.not.authenticated", + "errors": [] +} + +
+
+ +   +
+
+

List Clients associated to the user

+

The list capability of clients can support pagination and sorting.

+
Optional Arguments
+
+
offset
+
+ Integer optional, defaults to 0 +
+
Indicates the result from which pagination starts
+ +
limit
+
+ Integer optional, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
orderBy
+
+ String optional, one of displayName, accountNo, officeId, officeName +
+
Orders results by the indicated field.
+ +
sortBy
+
+ String optional, one of ASC, DESC +
+
Indicates what way to order results if orderBy is used.
+ +
displayName
+
+ String optional +
+
Use displayName of clients to restrict results.
+ +
firstName
+
+ String optional +
+
Use firstName of clients to restrict results.
+ +
lastName
+
+ String optional +
+
Use lastName of clients to restrict results.
+ +
+

Example Requests:

+
self/clients
+
+
self/clients?fields=displayName,officeName
+
+
self/clients?offset=10&limit=50
+
+
self/clients?orderBy=displayName&sortOrder=DESC
+
+
+ +GET https://DomainName/api/v1/self/clients + + +{ + "totalFilteredRecords": 2, + "pageItems": [ + { + "id": 1, + "accountNo": "000000001", + "status": { + "id": 300, + "code": "clientStatusType.active", + "value": "Active" + }, + "active": true, + "activationDate": [ + 2013, + 3, + 1 + ], + "fullname": "Small shop", + "displayName": "Small shop", + "officeId": 1, + "officeName": "Head Office" + }, + { + "id": 2, + "accountNo": "000000002", + "status": { + "id": 100, + "code": "clientStatusType.pending", + "value": "Pending" + }, + "active": false, + "fullname": "Home Farm Produce", + "displayName": "Home Farm Produce", + "officeId": 1, + "officeName": "Head Office" + } + ] +} + +
+
+ +   +
+
+

Retrieve a Client

+

Example Requests:

+
self/clients/1
+
+
self/clients/1?fields=id,displayName,officeName
+
+
+ +GET https://DomainName/api/v1/self/clients/{clientId} + + +{ + "id": 27, + "accountNo": "000000027", + "status": { + "id": 300, + "code": "clientStatusType.active", + "value": "Active" + }, + "active": true, + "activationDate": [ + 2013, + 1, + 1 + ], + "firstname": "savings", + "lastname": "test", + "displayName": "savings test", + "officeId": 1, + "officeName": "Head Office", + "timeline": { + "submittedOnDate": [ + 2013, + 1, + 1 + ], + "submittedByUsername": "mifos", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "activatedOnDate": [ + 2013, + 1, + 1 + ], + "activatedByUsername": "mifos", + "activatedByFirstname": "App", + "activatedByLastname": "Administrator" + }, + "savingsProductId": 4, + "savingsProductName": "account overdraft", + "groups": [] +} + +
+
+   +
+
+

Retrieve client accounts overview

+

+ An example of how a loan portfolio summary can be provided. This + is requested in a specific use case of the community application.
It is quite reasonable to add resources like this to simplify User Interface development. +

+

Example Requests:

+
self/clients/1/accounts
+
+
+
self/clients/1/accounts?fields=loanAccounts,savingsAccounts
+
+
+ +GET https://DomainName/api/v1/self/clients/{clientId}/accounts + + +{ + "loanAccounts": [ + { + "id": 1, + "accountNo": "000000001", + "externalId": "456", + "productId": 1, + "productName": "TestOne", + "status": { + "id": 300, + "code": "loanStatusType.active", + "value": "Active", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": true, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "loanType": { + "id": 1, + "code": "loanType.individual", + "value": "Individual" + }, + "loanCycle": 1 + } + ], + "savingsAccounts": [ + { + "id": 7, + "accountNo": "000000007", + "productId": 2, + "productName": "Other product", + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + }, + { + "id": 6, + "accountNo": "000000006", + "productId": 1, + "productName": "Passbook Savings", + "status": { + "id": 300, + "code": "savingsAccountStatusType.active", + "value": "Active", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": true, + "closed": false + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountBalance": 1828.03 + }, + { + "id": 5, + "accountNo": "000000005", + "productId": 1, + "productName": "Passbook Savings", + "status": { + "id": 400, + "code": "savingsAccountStatusType.withdrawn.by.applicant", + "value": "Withdrawn by applicant", + "submittedAndPendingApproval": false, + "approved": false, + "rejected": false, + "withdrawnByApplicant": true, + "active": false, + "closed": true + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + } + } + ] +} + +
+
+ +   +
+
+

Retrieve Client Image

+

Optional arguments are identical to those of Get Image associated with an Entity (Binary file)

+

Example Requests:

+
self/clients/1/images
+
+
+
+ +GET https://DomainName/api/v1/self/clients/{clientId}/images +Accept: text/plain + + + +data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ +bWFnZVJlYWR5ccllPAAAAJ1JREFUeNpi+P//PwMIA4E9EG8E4idQDGLbw+WhiiqA+D8OXAFVAzbp +DxBvB2JLIGaGYkuoGEjOhhFIHAbij0BdPgxYACMj42ogJQpifwBiXSDeC8JIbt4LxSC5DyxQjTeB ++BeaYb+Q5EBOAVutCzMJHUNNPADzzDokiYdAfAmJvwLkGeTgWQfyKZICS6hYBTwc0QL8ORSjBDhA +gAEAOg13B6R/SAgAAAAASUVORK5CYII= + +
+
+ +   +
+
+

List Client Charges

+ +

The list capability of client charges supports pagination.

+
Optional Arguments
+
+
offset
+
+ Integer Mandatory, defaults to 0 +
+
Indicates the result from which pagination starts
+ +
limit
+
+ Integer Mandatory, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+ +
pendingPayment
+
+ String optional +
+
Filters charges that are pending payment (neither paid or waived).
+ +
chargeStatus
+
+ String optional +
+
Filters charges according to the status.
+
+

Example Requests:

+
self/clients/1/charges
+
self/clients/1/charges?offset=0&limit=5
+
+
+ +GET https://DomainName/api/v1/self/clients/{clientId}/charges?limit=5&offset=0 + + +GET self/clients/1/charges?limit=5&offset=0 +Content-Type: application/json +No Request Body + + +{ + "totalFilteredRecords": 4, + "pageItems": [ + { + "id": 5, + "clientId": 1, + "chargeId": 6, + "name": "Client Fees 2", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2015, + 9, + 1 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 550.000000, + "amountPaid": 0.000000, + "amountWaived": 0.000000, + "amountWrittenOff": 0, + "amountOutstanding": 550.000000, + "penalty": false, + "isActive": true, + "isPaid": false, + "isWaived": false + }, + { + "id": 4, + "clientId": 1, + "chargeId": 5, + "name": "Client Fee 1", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2015, + 8, + 31 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 120.000000, + "amountPaid": 0.000000, + "amountWaived": 120.000000, + "amountWrittenOff": 0, + "amountOutstanding": 120.000000, + "penalty": true, + "isActive": true, + "isPaid": false, + "isWaived": true + }, + { + "id": 3, + "clientId": 1, + "chargeId": 5, + "name": "Client Fee 1", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2015, + 8, + 17 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100.000000, + "amountPaid": 0.000000, + "amountWaived": 100.000000, + "amountWrittenOff": 0, + "amountOutstanding": 0.000000, + "penalty": true, + "isActive": true, + "isPaid": false, + "isWaived": true + }, + { + "id": 2, + "clientId": 1, + "chargeId": 2, + "name": "Recurring savings Charge", + "chargeTimeType": { + "id": 7, + "code": "chargeTimeType.monthlyFee", + "value": "Monthly Fee" + }, + "dueDate": [ + 2015, + 8, + 17 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100.000000, + "amountPaid": 0, + "amountWaived": 100.000000, + "amountWrittenOff": 0, + "amountOutstanding": 0.000000, + "penalty": false, + "isActive": true, + "isPaid": false, + "isWaived": true + } + ] +} + + +
+
+   +
+
+

Retrieve a Client Charge

+
Arguments
+
+
associations
+
+ optional, a comma separated list of + 'associations' (itemised below). +
+
+
Associations are just extra pieces of data that you + might or might not want to retrieve.
+
+
+
+ 'transactions': Retrieves all transactions made on this client charge. +
+
+

Example Requests:

+
self/clients/1/charges/1
+
+
+
self/clients/1/charges/1?fields=name,id
+
+
+ +GET https://DomainName/api/v1/self/clients/{clientId}/charges/{clientChargeId} + + +{ + "id": 3, + "clientId": 1, + "chargeId": 5, + "name": "Client Fee 1", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2015, + 8, + 17 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100.000000, + "amountPaid": 0.000000, + "amountWaived": 100.000000, + "amountWrittenOff": 0, + "amountOutstanding": 0.000000, + "penalty": true, + "isActive": true, + "isPaid": false, + "isWaived": true +} + +
+
+ +   +
+
+

List Client Transactions

+

The list capability of client transaction can support pagination.

+
Mandatory Arguments
+
+
offset
+
+ Integer Mandatory, defaults to 0 +
+
Indicates the result from which pagination starts
+ +
limit
+
+ Integer Mandatory, defaults to 200 +
+
Restricts the size of results returned. To override the default and return all entries you must explicitly pass a non-positive integer value for limit e.g. limit=0, or limit=-1
+
+

Example Requests:

+
self/clients/189/transactions
+
self/clients/189/transactions?offset=10&limit=50
+
+
+ +GET https://DomainName/api/v1/self/clients/{clientId}/transactions?limit=5&offset=0 + + +GET self/clients/226/transactions?limit=5&offset=0 +Content-Type: application/json +No Request Body: + + + +{ + "totalFilteredRecords": 20, + "pageItems": [ + { + "id": 226, + "officeId": 1, + "officeName": "Head Office", + "type": { + "id": 1, + "code": "clientTransactionType.payCharge", + "value": "PAY_CHARGE" + }, + "date": [ + 2015, + 9, + 2 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 22, + "submittedOnDate": [ + 2015, + 9, + 2 + ], + "reversed": false + } + ] +} + +
+
+ +   +
+
+

Retrieve a Client Transaction

+

Example Requests:

+
self/clients/1/transactions/1
+
+
+
self/clients/1/transactions/1?fields=id,officeName
+
+
+ +GET https://DomainName/api/v1/self/clients/{clientId}/transaction/{transactionId} + + +{ + "id": 1, + "officeId": 1, + "officeName": "Head Office", + "type": { + "id": 1, + "code": "clientTransactionType.payCharge", + "value": "PAY_CHARGE" + }, + "date": [ + 2015, + 8, + 17 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 60.000000, + "submittedOnDate": [ + 2015, + 8, + 19 + ], + "reversed": true +} + +
+
+ +   +
+
+

Retrieve a Loan

+
Arguments
+
+
associations
+
+ optional, a comma separated list of + loan 'associations' (itemised below). +
+
+
Associations are just extra pieces of data that you + might or might not want to retrieve.
+
+
+
+ 'repaymentSchedule': Loan schedule data. +
+
+ 'originalSchedule': Loan schedule data without interest recalculations. +
+
+ 'futureSchedule': Loan schedule data from today date(will be displayed only for interest first repayment strategy processors) +
+
+ 'transactions': Loan transactions data. +
+
+ 'charges': Loan charges data. +
+
+ 'guarantors': Loan guarantors data. +
+
+ 'collateral': Loan collateral data. +
+
+ 'linkedAccount': Account linked to loan. +
+
+ 'multiDisburseDetails': Loan multi-disbursement details. +
+
+

Example Requests:

+
self/loans/1
+
+
+
self/loans/1?fields=id,principal,annualInterestRate
+
+
+
self/loans/1?fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions
+
+
+ +GET https://DomainName/api/v1/self/loans/{loanId} + + +{ + "id": 1, + "accountNo": "000000001", + "status": { + "id": 300, + "code": "loanStatusType.active", + "value": "Active", + "pendingApproval": false, + "waitingForDisbursal": false, + "active": true, + "closedObligationsMet": false, + "closedWrittenOff": false, + "closedRescheduled": false, + "closed": false, + "overpaid": false + }, + "clientId": 1, + "clientName": "Kampala first Client", + "clientOfficeId": 2, + "loanProductId": 1, + "loanProductName": "Kampala Product (with cash accounting)", + "loanProductDescription": "Typical Kampala loan product with cash accounting enabled for testing.", + "loanPurposeId": 22, + "loanPurposeName": "option.HousingImprovement", + "loanOfficerId": 2, + "loanOfficerName": "LoanOfficer, Kampala", + "loanType": { + "id": 1, + "code": "loanType.individual", + "value": "Individual" + }, + "currency": { + "code": "UGX", + "name": "Uganda Shilling", + "decimalPlaces": 2, + "displaySymbol": "USh", + "nameCode": "currency.UGX", + "displayLabel": "Uganda Shilling (USh)" + }, + "principal": 1000000, + "termFrequency": 12, + "termPeriodFrequencyType": { + "id": 2, + "code": "termFrequency.periodFrequencyType.months", + "value": "Months" + }, + "numberOfRepayments": 12, + "repaymentEvery": 1, + "repaymentFrequencyType": { + "id": 2, + "code": "repaymentFrequency.periodFrequencyType.months", + "value": "Months" + }, + "interestRatePerPeriod": 24, + "interestRateFrequencyType": { + "id": 3, + "code": "interestRateFrequency.periodFrequencyType.years", + "value": "Per year" + }, + "annualInterestRate": 24, + "amortizationType": { + "id": 1, + "code": "amortizationType.equal.installments", + "value": "Equal installments" + }, + "interestType": { + "id": 1, + "code": "interestType.flat", + "value": "Flat" + }, + "interestCalculationPeriodType": { + "id": 1, + "code": "interestCalculationPeriodType.same.as.repayment.period", + "value": "Same as repayment period" + }, + "transactionProcessingStrategyId": 2, + "timeline": { + "submittedOnDate": [ + 2012, + 4, + 3 + ], + "submittedByUsername": "admin", + "submittedByFirstname": "App", + "submittedByLastname": "Administrator", + "approvedOnDate": [ + 2012, + 4, + 3 + ], + "approvedByUsername": "admin", + "approvedByFirstname": "App", + "approvedByLastname": "Administrator", + "expectedDisbursementDate": [ + 2012, + 4, + 10 + ], + "actualDisbursementDate": [ + 2012, + 4, + 10 + ], + "disbursedByUsername": "admin", + "disbursedByFirstname": "App", + "disbursedByLastname": "Administrator", + "expectedMaturityDate": [ + 2013, + 4, + 10 + ] + }, + "summary": { + "currency": { + "code": "UGX", + "name": "Uganda Shilling", + "decimalPlaces": 2, + "displaySymbol": "USh", + "nameCode": "currency.UGX", + "displayLabel": "Uganda Shilling (USh)" + }, + "principalDisbursed": 1000000, + "principalPaid": 0, + "principalWrittenOff": 0, + "principalOutstanding": 1000000, + "principalOverdue": 833333.3, + "interestCharged": 240000, + "interestPaid": 0, + "interestWaived": 0, + "interestWrittenOff": 0, + "interestOutstanding": 240000, + "interestOverdue": 200000, + "feeChargesCharged": 18000, + "feeChargesDueAtDisbursementCharged": 0, + "feeChargesPaid": 0, + "feeChargesWaived": 0, + "feeChargesWrittenOff": 0, + "feeChargesOutstanding": 18000, + "feeChargesOverdue": 15000, + "penaltyChargesCharged": 0, + "penaltyChargesPaid": 0, + "penaltyChargesWaived": 0, + "penaltyChargesWrittenOff": 0, + "penaltyChargesOutstanding": 0, + "penaltyChargesOverdue": 0, + "totalExpectedRepayment": 1258000, + "totalRepayment": 0, + "totalExpectedCostOfLoan": 258000, + "totalCostOfLoan": 0, + "totalWaived": 0, + "totalWrittenOff": 0, + "totalOutstanding": 1258000, + "totalOverdue": 1048333.3, + "overdueSinceDate": [ + 2012, + 5, + 10 + ], + "linkedAccount":{ + "id":1, + "accountNo":"000000001" + }, + "disbursementDetails":[{"id":71,"expectedDisbursementDate":[2013,11,1],"principal":22000.000000,"approvedPrincipal":22000.000000}], + "fixedEmiAmount":1100.000000, + "maxOutstandingLoanBalance":35000, + "canDisburse":false, + "emiAmountVariations": [], + "inArrears": true, + "isNPA":false, + "overdueCharges": [ + { + "id": 20, + "name": "overdraft penality", + "active": true, + "penalty": true, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 3.000000, + "chargeTimeType": { + "id": 9, + "code": "chargeTimeType.overdueInstallment", + "value": "overdue fees" + }, + "chargeAppliesTo": { + "id": 1, + "code": "chargeAppliesTo.loan", + "value": "Loan" + }, + "chargeCalculationType": { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + }, + "chargePaymentMode": { + "id": 0, + "code": "chargepaymentmode.regular", + "value": "Regular" + }, + "feeInterval": 2, + "feeFrequency": { + "id": 1, + "code": "feeFrequencyperiodFrequencyType.weeks", + "value": "Weeks" + } + } + ] + } +} + +
+
+ +   +
+
+

Retrieve a Loan Transaction Details

+

Example Request:

+
self/loans/5/transactions/3
+
+
+ +GET https://DomainName/api/v1/self/loans/{loanId}/transactions/{transactionId} + + +{ + "id": 3, + "type": { + "id": 2, + "code": "loanTransactionType.repayment", + "value": "Repayment", + "disbursement": false, + "repaymentAtDisbursement": false, + "repayment": true, + "contra": false, + "waiveInterest": false, + "waiveCharges": false, + "writeOff": false, + "recoveryRepayment": false + }, + "date": [ + 2012, + 5, + 14 + ], + "manuallyReversed": false, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 559.88, + "interestPortion": 559.88 +} + +
+
+ +   +
+
+

List Loan Charges

+

Example Requests:

+
self/loans/1/charges
+
+
+
self/loans/1/charges?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/self/loans/{loanId}/charges + + +[ + { + "id": 1, + "chargeId": 1, + "name": "Loan Processing fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + }, + { + "id": 7, + "chargeId": 2, + "name": "Collection Fee", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2013, + 3, + 29 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + } +] + +
+
+ +   +
+
+

Retrieve a Loan Charge

+

Example Requests:

+
self/loans/1/charges/1
+
+
+
self/loans/1/charges/1?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/self/loans/{loanId}/charges/{chargeId} + + +{ + "id": 1, + "chargeId": 1, + "name": "Loan Processing fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.disbursement", + "value": "Disbursement" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false +} +
+
+ +   +
+
+

Retrieve a savings account:

+

Arguments

+
+
associations
+
optional, a comma separated list of savings 'associations' (itemized below).
+

Associations are just extra pieces of data that you might or might not want to retrieve.

+
'transactions': Gets data related to transactions on the account e.g. ?associations=transactions
+
'charges':Savings Account charges data.
+
+

Example Requests :

+
self/savingsaccounts/1
+

+
self/savingsaccounts/1?associations=transactions
+
+
+ GET https://DomainName/api/v1/self/savingsaccounts/{accountId} + +{ + "id": 1, + "accountNo": "000000001", + "clientId": 1, + "clientName": "small business", + "savingsProductId": 1, + "savingsProductName": "Passbook Savings", + "fieldOfficerId": 0, + "status": { + "id": 100, + "code": "savingsAccountStatusType.submitted.and.pending.approval", + "value": "Submitted and pending approval", + "submittedAndPendingApproval": true, + "approved": false, + "rejected": false, + "withdrawnByApplicant": false, + "active": false, + "closed": false + }, + "timeline": { + "submittedOnDate": [ + 2013, + 3, + 1 + ] + }, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "nominalAnnualInterestRate": 5, + "interestCompoundingPeriodType": { + "id": 1, + "code": "savings.interest.period.savingsCompoundingInterestPeriodType.daily", + "value": "Daily" + }, + "interestPostingPeriodType": { + "id": 4, + "code": "savings.interest.posting.period.savingsPostingInterestPeriodType.monthly", + "value": "Monthly" + }, + "interestCalculationType": { + "id": 1, + "code": "savingsInterestCalculationType.dailybalance", + "value": "Daily Balance" + }, + "interestCalculationDaysInYearType": { + "id": 365, + "code": "savingsInterestCalculationDaysInYearType.days365", + "value": "365 Days" + }, + "summary": { + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "accountBalance": 0 + } +} + +
+
+ +  +
+
+

Retrieve Savings Account Transaction:

+

Example Requests:

+
self/savingsaccounts/1/transactions/1
+
+
+
+ GET https://DomainName/api/v1/self/savingsaccounts/{accountId}/transactions/{transactionId} + + +{ + "id": 1, + "transactionType": { + "id": 2, + "code": "savingsAccountTransactionType.withdrawal", + "value": "Withdrawal", + "deposit": false, + "withdrawal": true, + "interestPosting": false, + "feeDeduction": false + }, + "accountId": 1, + "accountNo": "000000001", + "date": [ + 2013, + 8, + 7 + ], + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "inMultiplesOf": 0, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "paymentDetailData": { + "id": 62, + "paymentType": { + "id": 11, + "name": "cash" + }, + "accountNumber": "", + "checkNumber": "", + "routingCode": "", + "receiptNumber": "", + "bankNumber": "" + }, + "amount": 5000, + "runningBalance": 0, + "reversed": true +} + +
+
+ +   +
+
+

List Savings Charges

+

Example Requests:

+
self/savingsaccounts/1/charges
+
+
self/savingsaccounts/1/charges?chargeStatus=inactive
+
+
self/savingsaccounts/1/charges?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/self/savingsaccounts/{accountId}/charges + + +[ + { + "id": 1, + "chargeId": 3, + "accountId": 57, + "name": "Savings account maintenance fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + }, + { + "id": 2, + "chargeId": 4, + "accountId": 57, + "name": "Pass book Fee", + "chargeTimeType": { + "id": 2, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "dueDate": [ + 2013, + 3, + 29 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false + }, + { + "id": 9, + "chargeId": 4, + "accountId": 57, + "name": "Withdrawal fee percentage", + "chargeTimeType": { + "id": 5, + "code": "chargeTimeType.withdrawalFee", + "value": "Withdrawal Fee" + }, + "chargeCalculationType": { + "id": 2, + "code": "chargeCalculationType.percent.of.amount", + "value": "% Amount" + }, + "percentage": 0.25, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 0, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 0, + "amountOrPercentage": 0.25, + "penalty": false + }, + { + "id": 10, + "chargeId": 6, + "accountId": 57, + "name": "Annual fee - INR", + "chargeTimeType": { + "id": 6, + "code": "chargeTimeType.annualFee", + "value": "Annual Fee" + }, + "feeOnMonthDay": [ + 10, + 9 + ], + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 50, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 50, + "amountOrPercentage": 50, + "penalty": false + } +] + +
+
+ +   +
+
+

Retrieve a Savings account Charge

+

Example Requests:

+
self/savingsaccounts/1/charges/5
+
+
+
self/savingsaccounts/1/charges/5?fields=name,amountOrPercentage
+
+
+ +GET https://DomainName/api/v1/self/savingsaccounts/{accountId}/charges/{savingsAccountChargeId} + + +{ + "id": 1, + "chargeId": 1, + "name": "Passbook fee", + "chargeTimeType": { + "id": 1, + "code": "chargeTimeType.specifiedDueDate", + "value": "Specified due date" + }, + "chargeCalculationType": { + "id": 1, + "code": "chargeCalculationType.flat", + "value": "Flat" + }, + "percentage": 0, + "amountPercentageAppliedTo": 0, + "currency": { + "code": "USD", + "name": "US Dollar", + "decimalPlaces": 2, + "displaySymbol": "$", + "nameCode": "currency.USD", + "displayLabel": "US Dollar ($)" + }, + "amount": 100, + "amountPaid": 0, + "amountWaived": 0, + "amountWrittenOff": 0, + "amountOutstanding": 100, + "amountOrPercentage": 100, + "penalty": false +} +
+
+ +   +
+
+

Retrieve Account Transfer Template

+

Returns list of loan/savings accounts that can be used for account transfer

+

Example Requests:

+
self/accounttransfers/template
+
+
+ GET https://DomainName/api/v1/self/accounttransfers/template + + +{ + "accountOptions": [ + { + "accountId": 1, + "accountNo": "00000001", + "accountType": { + "id": 2, + "code": "accountType.savings", + "value": "Savings Account" + }, + "clientId": 1, + "clientName": "ABC", + "officeId": 1, + "officeName": "HEAD OFFICE" + }, + { + "accountId": 5, + "accountNo": "00000005", + "accountType": { + "id": 1, + "code": "accountType.loan", + "value": "Loan Account" + }, + "clientId": 2, + "clientName": "XYZ", + "officeId": 3, + "officeName": "REGIONAL OFFICE" + } + ] +} + +
+
+ +   +
+
+

Create new Transfer

+

Ability to create new transfer of monetary funds from one account to another.

+
+
+ POST https://DomainName/api/v1/self/accounttransfers + POST self/accounttransfers/ +Content-Type: application/json +No Request Body: +{ +"fromOfficeId": 1, +"fromClientId": 1, +"fromAccountType": 2, +"fromAccountId": 1, +"toOfficeId": 1, +"toClientId": 1, +"toAccountType": 2, +"toAccountId": 2, +"dateFormat": "dd MMMM yyyy", +"locale": "en", +"transferDate": "01 August 2011", +"transferAmount": "112.45", +"transferDescription": "A description of the transfer" +} + + +{ + "savingsId": 1, + "resourceId": 1 +} + +
+
+ + +
+ + +   +
+
+
+
+ + + + +

+ Full API Matrix +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
ClientsclientsCreate a ClientList Clients
clients/templateRetrieve Client Template
clients/{clientId}Retrieve a ClientUpdate a ClientDelete a Client
clients/{clientId}?command=activateActivate a Client
clients/{clientId}?command=closeClose a Client
clients/{clientId}?command=assignStaffAssign Staff
clients/{clientId}?command=unassignStaffUnassign Staff
clients/{clientId}/accountsRetrieve client accounts overview
clients/{clientId}?command=transferTransfer Client
clients/{clientId}?command=updateSavingsAccountUpdate Default Savings Account
Client Identifiersclients/{clientId}/identifiersCreate an Identifier for a ClientList all Identifiers for a Client
clients/{clientId}/identifiers/{identifierId}Retrieve a Client IdentifierUpdate a Client IdentifierDelete a Client Identifier
Client Imagesclients/{clientId}/imagesUpload an Image for a Client (as DATA URI)Get Client Image (DATA URI)Update Client Image (DATA URI)Delete Client Image
+ Upload an Image for a Client (Multi-part form data) + Get Client Image (Binary file) + Update Client Image (Multi-part form data) +
Standing InstructionsstandinginstructionsCreate Standing InstructionList Standing Instructions
standinginstructions/{standingInstructionId}Retrive a Standing InstructionUpdate Standing InstructionDelete Standing Instruction(status change)
standinginstructionrunhistoryStandinginstructions History
standinginstructions/templateRetrive Standing Instruction Template
Account Transfersaccounttransfers/Create new TransferList Transfers
accounttransfers/templateRetrieve Template
accounttransfers/{transferId}Retrieve Transfer
GroupgroupsCreate a GroupList Groups
groups/templateRetrieve Group Template
groups/{groupId}Retrieve a GroupUpdate a GroupDelete a Group
groups/{groupId}?command=activateActivate a Group
groups/{groupId}?command=associateClientsAssociate Clients
groups/{groupId}?command=disassociateClientsDisassociate Clients
groups/{groupId}/accountsRetrive Group accounts summary
groups/{groupId}?command=transferClientsBulk Transfer Clients across Groups
groups/{groupId}?command=generateCollectionSheetGenerate Collection Sheet
groups/{groupId}?command=saveCollectionSheetSave Collection Sheet
groups/{groupId}?command=unassignStaffUnassign Staff
groups/{groupId}?command=assignStaffAssign Staff
groups/{groupId}?command=closeClose Group
groups/{groupId}?command=assignRoleAssign Role
groups/{groupId}?command=unassignRoleUnassign Role
groups/{groupId}?command=updateRoleUpdate Role
CentercentersCreate a CenterList Centers
centers/templateRetrieve Center Template
centers/{centerId}Retrieve a CenterUpdate a CenterDelete a Center
centers/{centerId}?command=activateActivate a Center
centers/{centerId}?command=closeClose Center
centers/{centerId}?command=associateGroupsAssociate Groups
centers/{centerId}?command=disassociateGroupsDisassociate Groups
centers/{centerId}/accountsRetrive Center accounts summary
centers/{centerId}?command=generateCollectionSheetGenerate Collection Sheet
centers/{centerId}?command=saveCollectionSheetSave Collection Sheet
Loan ProductloanproductsCreate a Loan ProductList Loan Products
loanproducts/templateRetrieve Loan Product Template
loanproducts/{productId}Retrieve a Loan ProductUpdate a Loan Product
Loan Product Mixloanproducts/template?isProductMixTemplate=trueRetrieve Loan Product Mix Template
loanproducts?associations=productMixesList Loan Products Mix
loanproducts/{productId}/productmixCreate a Loan Product MixRetrieve Loan Products MixUpdate Loan Product MixDelete Loan Products Mix
Loansloans?calculateLoanScheduleCalculate Loan Repayment Schedule
loansSubmit a new Loan ApplicationList Loans/Loan Applications
loans/template?clientId={clientId}Retrieve Loan Template
loans/{loanId}Retrieve a LoanDelete a Loan Application
loans/{loanId}?command=approveApprove Loan Application
loans/{loanId}?command=undoApprovalUndo Loan Application Approval
loans/{loanId}?command=assignLoanOfficerAssign a Loan Officer
loans/{loanId}?command=unassignLoanOfficerUnassign a Loan Officer
loans/{loanId}?command=rejectReject Loan Application
loans/{loanId}?command=withdrawWithdraw Loan Application
loans/{loanId}?command=disburseDisburse Loan
loans/{loanId}?command=disburseToSavingsDisburse Loan To Savings Account
loans/{loanId}?command=undoDisbursalUndo Loan Application Disbursal
loans/{loanId}?command=recoverGuaranteesRecover From Guarantors
loans/{loanId}/transactions/templateRetrieve Loan Transaction Template
Loan Transactionsloans/{loanId}/transactions?command=repaymentEnter a repayment
loans/{loanId}/transactions?command=waiveInterestWaive Interest
loans/{loanId}/transactions?command=writeoffWrite-off Loan
loans/{loanId}/transactions?command=recoverypaymentMake Recovery Payment
loans/{loanId}/transactions?command=undowriteoffUndo Loan Write-off Transaction
loans/{loanId}/transactions/{transactionId}Retrieve a transactions details
loans/{loanId}/transactions/{transactionId}Adjust a Transaction
Loan Chargesloans/{loanId}/chargesAdd a Loan Charge
loans/{loanId}/charges/{loanChargeId}Pay Loan Charge from Linked SavingsRetrieve a Loan ChargeModify a Loan ChargeDelete a Loan Charge
Loan Guarantorsloans/{loanId}/guarantorsCreate a Guarantor + List Guarantors +
loans/{loanId}/guarantors/{guarantorId}Retrieve a GuarantorUpdate a GuarantorDelete a Guarantor
Loan Collateralloans/{loanId}/collateralsCreate a Collateral + List collaterals +
loans/{loanId}/collaterals/{collateralId}Retrieve a CollateralUpdate a CollateralDelete a Collateral
Loan ReschedulingrescheduleloansCreate a Loan Reschedule Request
rescheduleloans/{requestId}Retrieve a Loan Reschedule Request
rescheduleloans/{requestId}?command=previewLoanRescheduleRetrieve a Preview of The New Loan Repayment Schedule
rescheduleloans/{requestId}?command=rejectReject Loan Reschedule Request
rescheduleloans/{requestId}?command=approveApprove Loan Reschedule Request
Loan Term Variations/loans/{loanId}/schedule?command=calculateLoanScheduleCalculate Schedule with Loan Term Variations
/loans/{loanId}/schedule?command=addVariationsCreate Loan Term Variations
/loans/{loanId}/schedule?command=deleteVariationsRemove All Loan Term Variations
General Ledger AccountglaccountsCreate a New Ledger AccountList Ledger Accounts
glaccounts/{glaccountId}Retrieve a Ledger AccountUpdate a Ledger AccountDelete a Ledger Account
Accounting ClosureglclosuresCreate an Accounting ClosureList Accounting Closures
glclosures/{glclosureId}Retrieve an Accounting ClosureUpdate an Accounting ClosureDelete an Accounting Closure
Journal EntriesjournalentriesCreate Journal EntriesList Journal Entries
journalentries?command=updateRunningBalanceUpdate Running Balance for Journal Entries
journalentries/{entryId}Retrieve a single Entry
journalentries/{transactionId}/reversalReverse Journal Entries
Accounting RulesaccountingrulesCreate a Accounting RuleList Accounting Rules
accountingrules/{accountingrulesId}Retrieve a Accounting RuleUpdate a Accounting RuleDelete a Accounting Rule
ReportreportsCreate a ReportList Reports
reports/templateRetrieve Report Template
reports/{id}Retrieve a ReportUpdate a ReportDelete a Report
Run Reportrunreports/{reportName}Run a Report
SearchsearchSearch Resources
OfficeofficesCreate an OfficeList Offices
offices/templateRetrieve Office Template
offices/{officeId}Retrieve an OfficeUpdate an Office
CurrencycurrenciesRetrieve Currency + ConfigurationUpdate Currency + Configuration
FundsfundsCreate a FundList Funds
funds/{fundId}Retrieve a FundUpdate a Fund
StaffstaffCreate a StaffList Staff
staff/{staffId}Retrieve a Staff MemberUpdate a Staff Member
Staff Imagesstaff/{staffId}/imagesUpload an Image for a Staff Member (as DATA URI)Get Staff Image (DATA URI)Update Staff Image (DATA URI)Delete Staff Image
+ Upload an Image for a Staff Member (Multi-part form data) + Get Staff Image (Binary file) + Update Staff Image (Multi-part form data) +
ChargeschargesCreate a ChargeList Charges
charges/{chargeId}Retrieve a ChargeUpdate a ChargeDelete a Charge
Data TabledatatablesCreate Data TableList Data Tables
datatables/{datatable}Retrieve Data Table DetailsUpdate Data TableDelete Data Table
datatables/register/{datatable}/{apptable}Register Data Table
datatables/deregister/{datatable}Deregister Data Table
datatables/{datatable}/{apptableId}Create Entry in Data + TableRetrieve Entry(s) from + Data TableUpdate Entry in Data + Table (One to One)Delete Entry(s) in Data + Table
datatables/{datatable}/{apptableId}/{datatableId}Update Entry in Data + Table (One to Many)Delete Entry in Data + Table (One to Many)
Documents{entityType}/{entityId}/documentsCreate a DocumentList All Document Details
{entityType}/{entityId}/documents/{documentId}Retrieve a Documents DetailsUpdate a DocumentDelete a Document
{entityType}/{entityId}/documents/{documentId}/attachmentRetrieve + binary file associated with a + Document +
Notes{resource}/{resourceId}/notesAdd a Resource NoteRetrieve a Resource's Notes
{resource}/{resourceId}/notes/{noteId}List All + Notes for a ResourceUpdate a Resource NoteDelete a Resource Note
AuthenticationauthenticationVerify Authentication
UserusersCreate a UserList Users
users/templateRetrieve User Template
users/{userId}Retrieve a UserUpdate a UserDelete a User
RolerolesCreate a New RoleList Roles
roles/{roleId}Retrieve a RoleUpdate a Role
roles/{roleId}/permissionsRetrieve a Role's + PermissionsUpdate a Role's + Permissions
PermissionpermissionsList Application PermissionsEnable/Disable Permissions for Maker Checker
Global ConfigurationconfigurationsList Global Configuration
configurations/{configId}Retrieve a Global ConfigurationUpdate Global Configuration
Retrieve Surveys Global Configuration
CodescodesCreate a CodeList Codes
codes/{codeId}Retrieve a CodeUpdate a CodeDelete a Code
Code Valuescodes/{codeId}/codevaluesCreate a Code ValueList Code Values
codes/{codeId}/codevalues/{codevalueId}Retrieve a Code ValueUpdate a Code ValueDelete a Code Value
AuditsauditsList Audits
audits/searchtemplateRetrieve Audit Search Template
audits/{auditId}Retrieve an Audit Entry
MakercheckersmakercheckersList Maker Checker Entries
makercheckers/searchtemplateRetrieve Maker Checker Search Template
makercheckers/{auditId}Delete Maker Checker Entry
makercheckers/{auditId}?command=approveApprove Maker Checker Entry
makercheckers/{auditId}?command=rejectReject Maker Checker Entry
Scheduler jobsjobsList Scheduler jobs
jobs/{jobId}Retrieve a jobUpdate a job
jobs/{jobId}?command=executeJobRun a job
jobs/{jobid}/runhistory?offset=0&limit=200Retrieve job history
schedulerRetrieve scheduler status
scheduler?command=startActivate a scheduler service
scheduler?command=stopSuspend a scheduler service
Savings ProductsavingsproductsCreate a Savings productList Savings products
savingproducts/templateRetrieve Savings Product Template
savingsproducts/{productId}Retrieve a savings productUpdate a savings productDelete a savings product
Savings AccountssavingsaccountsSubmit new savings applicationList savings application/accounts
savingsaccounts/template?clientId={clientId}Retrieve savings template
savingsaccounts/{accountId}Retrieve a savings application/accountModify a savings applicationDelete a savings application
savingsaccounts/{accountId}?command=approveApprove a savings application
savingsaccounts/{accountId}?command=undoApprovalUndo savings application approval
savingsaccounts/{accountId}?command=assignSavingsOfficerAssign Savings Officer
savingsaccounts/{accountId}?command=unassignSavingsOfficerUnassign Savings Officer
savingsaccounts/{accountId}?command=rejectReject a savings application
savingsaccounts/{accountId}?command=withdrawWithdraw savings application
savingsaccounts/{accountId}?command=activateActivate a savings account
savingsaccounts/{accountId}?command=closeClose a savings account
savingsaccounts/{accountId}?command=calculateInterestCalculate interest on a savings account
savingsaccounts/{accountId}?command=postInterestPost interest on a savings account
Savings Transactionssavingsaccounts/{accountId}/transactions?command=depositMake a deposit
savingsaccounts/{accountId}/transactions?command=withdrawalMake a withdrawal
savingsaccounts/{accountId}/transactions/{transactionId}?command=undoUndo transaction
savingsaccounts/{accountId}/transactions/{transactionId}?command=modifyAdjust transaction
savingsaccounts/{accountId}/transactions/templateRetrieve savings account transaction template
savingsaccounts/{accountId}/transactions/{transactionId}Retrieve savings account transaction
Savings Account Chargessavingsaccounts/{accountId}/chargesAdd a Savings Account ChargeList Savings Account Charges
savingsaccounts/{accountId}/charges/{savingsAccountChargeId}Retrieve a Savings Account ChargeModify a Savings Account ChargeDelete a Savings Account Charge
savingsaccounts/{accountId}/charges/{savingsAccountChargeId}?command=paychargePay a Savings Account Charge
savingsaccounts/{accountId}/charges/{savingsAccountChargeId}?command=waiveWaive a Savings Account Charge
savingsaccounts/{accountId}/charges/{savingsAccountChargeId}?command=inactivateInactivate a Savings Account Charge
Fixed Deposit ProductfixeddepositproductsCreate a Fixed Deposit productList Fixed Deposit products
fixeddepositproducts/{productId}Retrieve a Fixed Deposit productUpdate a Fixed Deposit productDelete a Fixed Deposit product
Fixed Deposit AccountsfixeddepositaccountsSubmit new fixed deposit applicationList fixed deposit application/accounts
fixeddepositaccounts/{accountId}Retrieve a fixed deposit application/accountModify a fixed deposit applicationDelete a fixed deposit application
fixeddepositaccounts/{accountId}?command=approveApprove a fixed deposit application
fixeddepositaccounts/{accountId}?command=undoApprovalUndo fixed deposit application approval
fixeddepositaccounts/{accountId}?command=rejectReject a fixed deposit application
fixeddepositaccounts/{accountId}?command=withdrawWithdraw fixed deposit application
fixeddepositaccounts/{accountId}?command=activateActivate a fixed deposit account
fixeddepositaccounts/{accountId}?command=closeClose a fixed deposit account
fixeddepositaccounts/{accountId}?command=prematureClosePremature Close a fixed deposit account
fixeddepositaccounts/{accountId}?command=calculatePrematureAmountCalculate Premature amount on a fixed deposit account
fixeddepositaccounts/{accountId}?command=calculateInterestCalculate interest on a fixed deposit account
fixeddepositaccounts/{accountId}?command=postInterestPost interest on a fixed deposit account
Recurring Deposit ProductrecurringdepositproductsCreate a Recurring Deposit productList Recurring Deposit products
recurringdepositproducts/{productId}Retrieve a Recurring Deposit productUpdate a Recurring Deposit productDelete a Recurring Deposit product
Recurring Deposit AccountsrecurringdepositaccountsSubmit new recurring deposit applicationList recurring deposit application/accounts
recurringdepositaccounts/{accountId}Retrieve a recurring deposit application/accountModify a recurring deposit applicationDelete a recurring deposit application
recurringdepositaccounts/{accountId}?command=approveApprove a recurring deposit application
recurringdepositaccounts/{accountId}?command=undoApprovalUndo recurring deposit application approval
recurringdepositaccounts/{accountId}?command=rejectReject a recurring deposit application
recurringdepositaccounts/{accountId}?command=withdrawWithdraw recurring deposit application
recurringdepositaccounts/{accountId}?command=activateActivate a recurring deposit account
recurringdepositaccounts/{accountId}?command=closeClose a recurring deposit account
recurringdepositaccounts/{accountId}?command=prematureClosePremature Close a recurring deposit account
recurringdepositaccounts/{accountId}?command=calculatePrematureAmountCalculate Premature amount on a recurring deposit account
recurringdepositaccounts/{accountId}?command=calculateInterestCalculate interest on a recurring deposit account
recurringdepositaccounts/{accountId}?command=postInterestPost interest on a recurring deposit account
Recurring Deposit Transactionsrecurringdepositaccounts/{accountId}/transactions?command=depositMake a deposit
recurringdepositaccounts/{accountId}/transactions?command=withdrawalMake a withdrawal
recurringdepositaccounts/{accountId}/transactions/{transactionId}?command=undoUndo transaction
recurringdepositaccounts/{accountId}/transactions/{transactionId}?command=modifyAdjust transaction
recurringdepositaccounts/{accountId}/transactions/templateRetrieve Deposit account transaction template
recurringdepositaccounts/{accountId}/transactions/{transactionId}Retrieve Deposit account transaction
+
+ +   +
+ + + + +

Beta API Matrix

+ + + + + + + + + + + + + + + + +
+ + + + +
RESOURCES
+
+ + + + + + +
POST
create/complex update
+ + + + + + +
GET
read
+ + + + + + +
PUT
update
+ + + + + + +
DELETE
delete
+
CachecachesList Cache TypesSwitch Cache
+
+ +  +
+

Payment Application Logic / Transaction Processing Strategy

+ +

The way payments (transactions) are handled and the effect they have on the loan is an area that can differ widely from MFI to MFI. Mifos allows for transaction processing strategies to be developed that are associated with a loan product. Several approaches are provided out-of-the-box. If these approaches dont meet exactly your needs a custom approach can be developed and released with the platform.

+ +

In general the the following areas are handled by any given transaction processing strategy: +

+

+ +

Penalties, Fees, Interest, Principal order

+

+ Payment order: +

    +
  1. Overdue and due penalties
  2. +
  3. Overdue and due fees
  4. +
  5. Overdue and due interest
  6. +
  7. Overdue and due principal
  8. +
+

+

Early payment: Any payment that pays off an installment that occurs before the due date of the installment. There is no incentive/advantage to making an early payment as theres no decrease in cost of the loan.

+ +

On time payment: Any payment that pays off an installment that occurs exactly on the due date of the installment.

+ +

Late payment: Any payment that pays off an installment that occurs after the due date of the installment. There is no penalization for late payment. The total cost of the loan does not automatically increase, no penalties are automatically applied to the loan.

+ +

Principal Interest Penalties Fees Order

+

The key aspect of this strategy is the payment order.

+

+ Payment order: +

    +
  1. Overdue and due principal
  2. +
  3. Overdue and due interest
  4. +
  5. Overdue and due penalties
  6. +
  7. Overdue and due fees
  8. +
+

+

Early payment: Any payment that pays off an installment that occurs before the due date of the installment. There is no incentive/advantage to making an early payment as theres no decrease in cost of the loan.

+ +

On time payment: Any payment that pays off an installment that occurs exactly on the due date of the installment.

+ +

Late payment: Any payment that pays off an installment that occurs after the due date of the installment. There is no penalization for late payment. The total cost of the loan does not automatically increase, no penalties are automatically applied to the loan.

+ +

Interest Principal Penalties Fees Order

+

The key aspect of this strategy is the payment order.

+

+ Payment order: +

    +
  1. Overdue and due interest
  2. +
  3. Overdue and due principal
  4. +
  5. Overdue and due penalties
  6. +
  7. Overdue and due fees
  8. +
+

+

Early payment: Any payment that pays off an installment that occurs before the due date of the installment. There is no incentive/advantage to making an early payment as theres no decrease in cost of the loan.

+ +

On time payment: Any payment that pays off an installment that occurs exactly on the due date of the installment.

+ +

Late payment: Any payment that pays off an installment that occurs after the due date of the installment. There is no penalization for late payment. The total cost of the loan does not automatically increase, no penalties are automatically applied to the loan.

+ +

RBI (India)

+

Per RBI regulations, all interest must be paid (both current and overdue) before principal is paid.

+

For example taking a loan with two installments due (one current and one overdue) of 220 each (200 principal + 20 interest) - A partial payment of 40 results in payment been broken up as 20 interest on installment #1 (200 principal remaining) and 20 payment to interest on installment #2 (200 principal remaining)

+

+ Payment order: +

    +
  1. Overdue and due interest
  2. +
  3. Overdue and due principal
  4. +
  5. Overdue and due penalties
  6. +
  7. Overdue and due fees
  8. +
+

+

Early payment: Any payment that pays off an installment that occurs before the due date of the installment. There is no incentive/advantage to making an early payment as theres no decrease in cost of the loan.

+ +

On time payment: Any payment that pays off an installment that occurs exactly on the due date of the installment.

+ +

Late payment: Any payment that pays off an installment that occurs after the due date of the installment. There is no penalization for late payment. The total cost of the loan does not automatically increase, no penalties are automatically applied to the loan.

+ +

Early Payment Strategy

+

This strategy works similar to the Interest Principal Penalties Fees Order for on-time and late payments, i.e

+

+ Payment order: +

    +
  1. Overdue and due interest
  2. +
  3. Overdue and due principal
  4. +
  5. Overdue and due penalties
  6. +
  7. Overdue and due fees
  8. +
+

+

Early payment: Any payment that pays off an installment that occurs before the due date of the installment. There is no incentive/advantage to making an early payment as theres no decrease in cost of the loan. However, early payments are allocated only towards principal payments of future installments. Interest and fees/penalties of future installments are not paid and may be waived + manually if required

+ +

On time payment: Any payment that pays off an installment that occurs exactly on the due date of the installment.

+ +

Late payment: Any payment that pays off an installment that occurs after the due date of the installment. There is no penalization for late payment. The total cost of the loan does not automatically increase, no penalties are automatically applied to the loan.

+ + + + +
+ + +
+ + + + + diff --git a/api-docs/apidocs.css b/api-docs/apidocs.css new file mode 100644 index 000000000..38b8b9f96 --- /dev/null +++ b/api-docs/apidocs.css @@ -0,0 +1,748 @@ +.apiClick { + text-decoration: underline; + cursor: hand; + cursor: pointer; + color: blue; +} + +.apiClickNotPretty { + text-decoration: underline; + cursor: hand; + cursor: pointer; + color: blue; +} + +#jpw { + text-decoration: underline; + cursor: hand; + cursor: pointer; + color: blue; +} + + +.tocMatrix { + font-size: 85%; +} +.fullMatrixOuter { + margin-right: 20px; + margin-left: 20px; + margin-bottom: 20px; +} + +.matrixHeading { + font-family: Helvetica, Arial, sans-serif; + border-collapse:collapse; + border: 3px solid #6eb4db; + width:100%; +} + +.matrixHeading td +{ + //padding:3px 7px 2px 7px; + + padding-right:5px; + + vertical-align:text-top; +} + +.matrixHeading tr:not(:first-child):nth-child(even) { + color: #000; + background-color: rgb(240, 240, 255); +} + +.matrixHeading tr:not(:first-child):nth-child(odd) { + color: #000; + background-color: rgba(255, 248, 218, 0.13); +} + +.matrixHeading tr:first-child td table tr { + background-color: #6eb4db !important; +} + +.matrixHeadingBG { + background-color: #6eb4db; +} + +.matrixHeadingVerbs { + color: white; + font-weight: bold; + font-size: 125% +} + +.matrixHeadingCommands { + color: rgb(240, 240, 255) !important; + background-color: #6eb4db !important; +} + +.fineractHeading2 { + color: white; + font-weight: bold; + //font-size: 125% +} + +.fieldtype { + padding-right: 40px; + padding-left:40px; + padding-top:20px; + font-size: 85%; +} + +.fielddesc span, .fieldtype { + font-style: italic; + font-weight: normal; +} + +.fielddesc { + padding-bottom:10px; + padding-left:20px; +} + +.fielddesc span { + font-style: italic; + font-weight: normal; +} + +.normalli {list-style:disc outside none;} + + +html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,tdjpw{margin:0;padding:0;}tablejpw{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;} + +a img { outline: none; border: 0; } +h1 { font-size: 180%; font-weight: bold; } +h2 { font-size: 165%; font-weight: bold; } +h3 { font-size: 145%; font-weight: bold; } +h4 { font-size: 120%; font-weight: bold; } +h5 { font-size: 120%; font-weight: bold; } +h6 { font-size: 110%; font-weight: bold; } +h1, h2, h3, h4, h5, h6 { margin: 0 0 0.5em 0; line-height: 1.2em; } +p { margin: 1em 0; } +em {font-style: italic;} + +html { + background-color: rgb(240, 240, 255); +} + +body { + padding: 0; margin: 0; + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + font-size: 15px; + line-height: 22px; + min-width: 1000px; + background-color: gray; + border-top: 15px solid black; +} + +#flybar { + font-size: 14px; + line-height: 20px; +} + +.method-example h1, .method-example h2, .method-example h3, .method-example h4, .method-example h5, .method-example h6, #flybar, .footer { + font-family: Helvetica, Arial, sans-serif; +} + +.method-example code { + font-family: Monaco, Consolas, "Lucida Console", monospace; + font-size: 12px; + line-height: 18px; +} + +#flybar { + position: fixed; + z-index: 100; + height: 40px; + min-width: 745px; + left: 0; right: 0; top: 0; + padding-left: 150px; + background: #eee; + background: -webkit-gradient(linear, left top, left bottom, from(#6eb4db), to(#dadada)); + background: -moz-linear-gradient(top, #6eb4db, #dadada); + border-top: 3px solid black; + border-bottom: 1px solid #888; + -webkit-box-shadow: 0 3px 5px rgba(0,0,0,0.1); + -moz-box-shadow: 0 3px 5px rgba(0,0,0,0.1); + box-shadow: 0 3px 5px rgba(0,0,0,0.1); +} + +#nav-logo { + display: block; + height: 30px; + position: absolute; + top: 10px; + left: 10px; + font-weight: bold; + color: black; + font-size: 16px; + text-decoration: none; +} + +.flybar-button { + text-align: center; + text-transform: uppercase; + font-size: 12px; + padding: 0 0.5em; + line-height: 40px; + border-right: 1px solid transparent; + border-left: 1px solid transparent; + text-decoration: none; + font-weight: bold; + color: black; +} + +.flybar-nav { + display: block; + float: left; + min-width: 80px; + position: relative; +} + +.flybar-language { + display: block; + float: left; + position: relative; +} + +.flybar-language .flybar-button { + float: left; + clear: none; + border-right: 1px solid transparent; + border-left: 1px solid transparent; + min-width: 80px; + margin-left: -1px; +} + +.flybar-menu { + display: none; + position: absolute; + top: 41px; + max-height:550px; + overflow:auto; + width: 1000px; + background-color: rgba(249, 249, 249, 0.99); + border: 1px solid rgb(187, 187, 187); + border-top: 0; + padding: 1em; + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + -webkit-box-shadow: 0 3px 5px rgba(0,0,0,0.1); + -moz-box-shadow: 0 3px 5px rgba(0,0,0,0.1); + box-shadow: 0 3px 5px rgba(0,0,0,0.1); +} + +.flybar-menu-overview { + display: none; + position: absolute; + top: 41px; + + width: 300px; + background-color: rgba(249, 249, 249, 0.99); + border: 1px solid rgb(187, 187, 187); + border-top: 0; + padding: 1em; + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + -webkit-box-shadow: 0 3px 5px rgba(0,0,0,0.1); + -moz-box-shadow: 0 3px 5px rgba(0,0,0,0.1); + box-shadow: 0 3px 5px rgba(0,0,0,0.1); +} + + + +#toc-menu-client { + position:absolute; + left:-50px; +} +#toc-menu-group { + position:absolute; + left:-130px; +} +#toc-menu-loan { + position:absolute; + left:-210px; +} +#toc-menu-savings { + position:absolute; + left:-290px; +} +#toc-menu-accounting { + position:absolute; + left:-370px; +} +#toc-menu-org { + position:absolute; + left:-450px; +} +#toc-menu-user { + position:absolute; + left:-530px; +} +#toc-menu-system { + position:absolute; + left:-610px; +} +#toc-menu-noncore { + position:absolute; + left:-690px; +} +#toc-menu-report { + position:absolute; + left:-770px; +} +#toc-menu-template { + position:absolute; + left:-850px; +} + +#language-menu { + left: -25px; +} + +#language-menu li { + display: inline-block; + margin-right: 25px; +} + +.flybar-menu h3, .flybar-menu-overview h3, .flybar-menu-convenience h3 { + text-transform: uppercase; + font-size: 100%; +} + +.flybar-menu h4, .flybar-menu-overview h4, .flybar-menu-convenience h4 { + text-transform: uppercase; + font-size: 90%; + color: rgb(155, 155, 155); + margin: 0.5em 0 0.5em 0; +} + +.flybar-menu ul, .flybar-menu-overview ul, .flybar-menu-convenience ul { + margin: 0 0 1em 1em; +} + +.flybar-nav:hover .flybar-menu, .flybar-nav:hover .flybar-menu-overview, .flybar-nav:hover .flybar-menu-convenience, +.flybar-nav.active .flybar-menu, .flybar-nav.active .flybar-menu-overview, .flybar-nav.active .flybar-menu-convenience{ + display: block; +} + +.flybar-button:hover, +.flybar-button.active, +.flybar-nav:hover .flybar-button, +.flybar-nav.active .flybar-button { + background: #eee; + background: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#6eb4db)); + background: -moz-linear-gradient(top, #eee, #6eb4db); + border-left: 1px solid rgb(187, 187, 187); + border-right: 1px solid rgb(187, 187, 187); +} + +.flybar-nav:hover .flybar-menu, .flybar-nav:hover .flybar-menu-overview, .flybar-nav:hover .flybar-menu-convenience, +.flybar-button.active { + margin-right: -1px; +} + +.flybar-nav:hover .flybar-button, +.flybar-nav.active .flybar-button { + height: 51px; + color: #000; + background: -webkit-gradient(linear, left top, left bottom, from(#e5e5e5), to(#fff)); + background: -moz-linear-gradient(top, #e5e5e5, #fff); +} + +.toc-column1 { + width: 200px; +} + +.toc-column2 { + width: 235px; +} + +.toc-column3 { + width: 200px; +} + +.toc-column1, .toc-column2, .toc-column3, .toc-column4, .toc-column5, .toc-column6 { + float: left; +} + +.toc-section { + width: 235px; + font-size: 90%; +} + +code { + white-space: pre; + white-space: -o-pre-wrap; + white-space: -moz-pre-wrap; + white-space: pre-wrap; + display: block; + margin: 1em 0; + line-height: 1.5em; +} + +.method-section { + clear: left; + padding: 1em 0; + padding-top: 60px; + margin-left: -580px; +} + +.method-section:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; +} + +.method-description { + width: 540px; + float: left; + padding-right: 20px; + color: black; +} + +.method-description p { +} + +h1 { + text-transform: uppercase; +} + +.method-description h4 { + /*font-family: monospace;*/ +} + +.method-description h5 { + font-size: 110%; + color: rgb(155, 155, 155); + text-transform: uppercase; + clear: both; + padding: 0.5em 0; +} + +.method-example { + margin-left: 560px; + padding-left: 20px; + min-width: 380px; +} + +.method-example code { + white-space: pre; + white-space: -o-pre-wrap; + white-space: -moz-pre-wrap; + white-space: pre-wrap; +} + +.method-example { + color: rgb(105, 105, 125); +} + +.method-example p { + font-style: italic; + color: rgb(105, 105, 105); +} + +.method-error:before { + content: "EXAMPLE ERROR"; + color: rgb(155, 155, 185); + display: block; +} + +.method-declaration:before { + content: "DEFINITION"; + color: rgb(155, 155, 185); + display: block; +} + +.method-request:before { + content: "EXAMPLE REQUEST"; + color: rgb(155, 155, 185); + display: block; +} + +.method-response:before { + content: "EXAMPLE RESPONSE"; + color: rgb(155, 155, 185); + display: block; +} + +.expected-result:before { + content: "RESULT"; + color: rgb(155, 155, 185); + display: block; +} + +.method-response, .method-error { + font-size: 90%; +} + +.method-example li { + font-family: monospace; + color: black; +} + +.method-example ul { + margin: 1em 0; +} + +.method-example table { + font-family: monospace; + color: black; +} + +.method-example td { + padding-right: 20px; + padding-bottom: 5px; + vertical-align: top; +} +.method-example table th { + font-weight: bold; +} + +.method-example code { + color: black; +} + +.prompt:after { + content: '$ '; + color: gray; + display: block; +} + +.prompt.curl:after { content: '$ '; } +.prompt.ruby:after { content: '>> ' } +.prompt.python:after { content: '>>> ' } +.prompt.php:after { content: 'php > ' } +.prompt.java:after { content: '' } + +.method-name { + font-family: monospace; + font-weight: bold; +} + +.notification-request:before { + content: "EXAMPLE NOTIFICATION"; + color: rgb(155, 155, 185); + display: block; +} + +.notification-event:before { + content: "EVENT"; + color: rgb(155, 155, 185); + display: block; +} + + +#page-wrapper { + background-color: white; + color: black; +} + +#main-content-wrapper { + background-color: rgb(240, 240, 255); + + margin-left: 579px; + padding: 0 20px 40px 20px; + border-left: 1px solid rgb(229, 229, 238); +} + +#api-summary-example { + margin-top: 48px; +} + +.argument-list { + font-size: 90%; + line-height: 1.5em; +} + +.argument-list dl { + font-size: 95%; + padding: 1em 0; + line-height: 1.5em; +} + +.argument-list:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; +} + +.argument-list dl:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; +} + +.argument-list dt { + clear:both; + width:34%; + float:left; + text-align:right; + font-weight: bold; + margin-top: 8px; +} + +.event-types.argument-list dt { + width: 48%; +} + +.event-types.argument-list dd { + width: 48%; +} + +.argument-list dt:after { + content: ":"; +} + +.argument-list dd { + float:right; + width: 65%; +} + +.argument-list dl dd { + width: 65%; +} + +.argument-list dt + dd { + margin-top: 8px; + font-weight: bold; +} + +.argument-list dd dl dd dl { + width: 95%; +} + +.argument-list dd dl dd dl dd { + width: 65%; +} +.argument-list dd dl dd dl dt { + width:31%; +} + +.argument-list dd span { + font-style: italic; + font-weight: normal; +} + +.old-syle-anchor {display:block;height:0;width:0;} +strong { font-weight: bold; } + +.footer { + position: fixed; + bottom: 0; + height: 30px; + + border-top: 1px solid #ccc; + background: #eee; + background: -webkit-gradient(linear, left top, left bottom, from(#6eb4db), to(#dadada)); + background: -moz-linear-gradient(top, #6eb4db, #dadada); + + width: 100%; + opacity: 0.95; + font-size: 13px; +} + +.footer input[type="text"] { + height: 14px; + padding: 3px; + border: 1px solid #aaa; + border-radius: 4px; +} + +.suggestion-box { + float: right; + padding-top: 3px; + padding-right: 10px; +} + +.footer input[type="submit"]:hover { + background: -webkit-gradient( + linear, + center top, + center bottom, + from(#fefefe), + to(#dbdbdb), + color-stop(80%, #eeeeee), + color-stop(0%, #eeeeee) + ); + background: -moz-linear-gradient( + top, + #fff, + #fff + ); +} + +.footer input[type="submit"]:active { + background: -webkit-gradient( + linear, + center top, + center bottom, + from(#c0c0c0), + to(#fefefe), + color-stop(0%, #e1e1e1), + color-stop(30%, #eeeeee), + color-stop(80%, #fff) + ); + background: -moz-linear-gradient( + top, + #c0c0c0, + #fefefe + ); + + border: 1px solid #a3a3a3; +} + +.footer input[type="submit"] { + height: 22px; + padding: 3px; + font-size: 13px; + + font-family: "proxima-nova-1","proxima-nova-2", Helvetica, Arial, sans-serif; + color: #454545; + text-shadow: 0px 1px 0px #fff; + text-align: center; + + border: 1px solid #aaa; + background: -webkit-gradient( + linear, + center top, + center bottom, + from(#fefefe), + to(#dbdbdb), + color-stop(50%, #eeeeee) + ); + background: -moz-linear-gradient( + top, + #fefefe, + #dbdbdb + ); + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -webkit-background-clip: padding-box; + -webkit-backface-visibility: hidden; +} + +.stripe-version { + float: left; +} + +ul.field { + margin: 5px 10px; +} + +ul.field li { + list-style: square inside none; + font-style: italic; +} + +tt { + font-size: 9.5pt; +} \ No newline at end of file diff --git a/api-docs/jquery-1.7.min.js b/api-docs/jquery-1.7.min.js new file mode 100644 index 000000000..3ca5e0f5d --- /dev/null +++ b/api-docs/jquery-1.7.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7 jquery.com | jquery.org/license */ +(function(a,b){function cA(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cx(a){if(!cm[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cn||(cn=c.createElement("iframe"),cn.frameBorder=cn.width=cn.height=0),b.appendChild(cn);if(!co||!cn.createElement)co=(cn.contentWindow||cn.contentDocument).document,co.write((c.compatMode==="CSS1Compat"?"":"")+""),co.close();d=co.createElement(a),co.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cn)}cm[a]=e}return cm[a]}function cw(a,b){var c={};f.each(cs.concat.apply([],cs.slice(0,b)),function(){c[this]=a});return c}function cv(){ct=b}function cu(){setTimeout(cv,0);return ct=f.now()}function cl(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ck(){try{return new a.XMLHttpRequest}catch(b){}}function ce(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bB(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function br(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bi,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bq(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bp(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bp)}function bp(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bo(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bn(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bm(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(){return!0}function M(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.add(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return a!=null&&m.test(a)&&!isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,unknownElems:!!a.getElementsByTagName("nav").length,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",enctype:!!c.createElement("form").enctype,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.lastChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-999px",top:"-999px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;f(function(){var a,b,d,e,g,h,i=1,j="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",l="visibility:hidden;border:0;",n="style='"+j+"border:5px solid #000;padding:0;'",p="
"+""+"
";m=c.getElementsByTagName("body")[0];!m||(a=c.createElement("div"),a.style.cssText=l+"width:0;height:0;position:static;top:0;margin-top:"+i+"px",m.insertBefore(a,m.firstChild),o=c.createElement("div"),o.style.cssText=j+l,o.innerHTML=p,a.appendChild(o),b=o.firstChild,d=b.firstChild,g=b.nextSibling.firstChild.firstChild,h={doesNotAddBorder:d.offsetTop!==5,doesAddBorderForTableAndCells:g.offsetTop===5},d.style.position="fixed",d.style.top="20px",h.fixedPosition=d.offsetTop===20||d.offsetTop===15,d.style.position=d.style.top="",b.style.overflow="hidden",b.style.position="relative",h.subtractsBorderForOverflowNotVisible=d.offsetTop===-5,h.doesNotIncludeMarginInBodyOffset=m.offsetTop!==i,m.removeChild(a),o=a=null,f.extend(k,h))}),o.innerHTML="",n.removeChild(o),o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[f.expando]:a[f.expando]&&f.expando,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[f.expando]=n=++f.uuid:n=f.expando),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[f.expando]:f.expando;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)?b=b:b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" "));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];if(!arguments.length){if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}return b}e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!a||j===3||j===8||j===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g},removeAttr:function(a,b){var c,d,e,g,h=0;if(a.nodeType===1){d=(b||"").split(p),g=d.length;for(;h=0}})});var z=/\.(.*)$/,A=/^(?:textarea|input|select)$/i,B=/\./g,C=/ /g,D=/[^\w\s.|`]/g,E=/^([^\.]*)?(?:\.(.+))?$/,F=/\bhover(\.\S+)?/,G=/^key/,H=/^(?:mouse|contextmenu)|click/,I=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,J=function(a){var b=I.exec(a);b&& +(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},K=function(a,b){return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||a.id===b[2])&&(!b[3]||b[3].test(a.className))},L=function(a){return f.event.special.hover?a:a.replace(F,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=L(c).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"",(g||!e)&&c.preventDefault();if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,n=null;for(m=e.parentNode;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l=0:t===b&&(t=o[s]=r.quick?K(m,r.quick):f(m).is(s)),t&&q.push(r);q.length&&j.push({elem:m,matches:q})}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),G.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),H.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y="abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",Z=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,_=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,ba=/<([\w:]+)/,bb=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bk=X(c);bj.optgroup=bj.option,bj.tbody=bj.tfoot=bj.colgroup=bj.caption=bj.thead,bj.th=bj.td,f.support.htmlSerialize||(bj._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after" +,arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Z,""):null;if(typeof a=="string"&&!bd.test(a)&&(f.support.leadingWhitespace||!$.test(a))&&!bj[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(_,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bn(a,d),e=bo(a),g=bo(d);for(h=0;e[h];++h)g[h]&&bn(e[h],g[h])}if(b){bm(a,d);if(c){e=bo(a),g=bo(d);for(h=0;e[h];++h)bm(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bc.test(k))k=b.createTextNode(k);else{k=k.replace(_,"<$1>");var l=(ba.exec(k)||["",""])[1].toLowerCase(),m=bj[l]||bj._default,n=m[0],o=b.createElement("div");b===c?bk.appendChild(o):X(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=bb.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&$.test(k)&&o.insertBefore(b.createTextNode($.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bt.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bs,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bs.test(g)?g.replace(bs,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bB(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bC=function(a,c){var d,e,g;c=c.replace(bu,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bD=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bv.test(f)&&bw.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bB=bC||bD,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bF=/%20/g,bG=/\[\]$/,bH=/\r?\n/g,bI=/#.*$/,bJ=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bK=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bL=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bM=/^(?:GET|HEAD)$/,bN=/^\/\//,bO=/\?/,bP=/)<[^<]*)*<\/script>/gi,bQ=/^(?:select|textarea)/i,bR=/\s+/,bS=/([?&])_=[^&]*/,bT=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bU=f.fn.load,bV={},bW={},bX,bY,bZ=["*/"]+["*"];try{bX=e.href}catch(b$){bX=c.createElement("a"),bX.href="",bX=bX.href}bY=bT.exec(bX.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bU)return bU.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bP,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bQ.test(this.nodeName)||bK.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bH,"\r\n")}}):{name:b.name,value:c.replace(bH,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?cb(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),cb(a,b);return a},ajaxSettings:{url:bX,isLocal:bL.test(bY[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bZ},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:b_(bV),ajaxTransport:b_(bW),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cd(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=ce(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bJ.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bI,"").replace(bN,bY[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bR),d.crossDomain==null&&(r=bT.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bY[1]&&r[2]==bY[2]&&(r[3]||(r[1]==="http:"?80:443))==(bY[3]||(bY[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),ca(bV,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bM.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bO.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bS,"$1_="+x);d.url=y+(y===d.url?(bO.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bZ+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=ca(bW,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)cc(g,a[g],c,e);return d.join("&").replace(bF,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cf=f.now(),cg=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cf++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cg.test(b.url)||e&&cg.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cg,l),b.url===j&&(e&&(k=k.replace(cg,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ch=a.ActiveXObject?function(){for(var a in cj)cj[a](0,1)}:!1,ci=0,cj;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ck()||cl()}:ck,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ch&&delete cj[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++ci,ch&&(cj||(cj={},f(a).unload(ch)),cj[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cm={},cn,co,cp=/^(?:toggle|show|hide)$/,cq=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cr,cs=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],ct;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cw("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cz.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cz.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cA(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cA(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/build-cloudbees.sh b/build-cloudbees.sh new file mode 100755 index 000000000..c608ea16d --- /dev/null +++ b/build-cloudbees.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e + +# https://developer.cloudbees.com/bin/view/DEV/Node+Builds +curl -s -o use-node https://repository-cloudbees.forge.cloudbees.com/distributions/ci-addons/node/use-node +NODE_VERSION=0.11.12 . ./use-node + +./build.sh diff --git a/build.sh b/build.sh new file mode 100755 index 000000000..3b06f127e --- /dev/null +++ b/build.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Exit the script if any command returns a non-true return value (http://www.davidpashley.com/articles/writing-robust-shell-scripts/) +set -e + +git --version +# TODO UNCOMMENT THIS once https://github.com/openMF/mifosx/pull/1291 is merged! +# git pull +# This does NOT get the most recent revision from the submodule repository. +# Instead, it only gets the revision of the submodule that is recorded in the revision of the main repository. +## NOT git submodule update --remote +# The following is very important, because even if the main (API) repo is latest, +# the sub-module initially will be a fixed old rev. and only this grabs real latest: +git submodule foreach 'git checkout develop && git pull --ff-only origin develop' + +cd apps/community-app +./build.sh +cd ../../fineract-provider/ +./gradlew -Penv=dev clean dist diff --git a/config/fineractdev-eclipse-preferences.epf b/config/fineractdev-eclipse-preferences.epf new file mode 100644 index 000000000..373d3ef59 --- /dev/null +++ b/config/fineractdev-eclipse-preferences.epf @@ -0,0 +1,110 @@ +#Fri Nov 23 23:01:54 GMT 2012 +/instance/org.eclipse.jdt.ui/cleanup.always_use_parentheses_in_expressions=false +/instance/org.eclipse.jdt.ui/cleanup.make_parameters_final=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning +/instance/org.eclipse.jdt.ui/cleanup.add_serial_version_id=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.argumentSuffixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=disabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.argumentPrefixes= +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.ondemandthreshold=99 +/instance/org.eclipse.jdt.ui/cleanup.always_use_blocks=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +/instance/org.eclipse.jdt.ui/cleanup.remove_trailing_whitespaces=true +/instance/org.eclipse.jdt.ui/cleanup.make_private_fields_final=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning +/instance/org.eclipse.jdt.ui/cleanup.add_missing_override_annotations_interface_methods=true +@org.eclipse.jdt.ui=3.7.1.r371_v20110824-0800 +/instance/org.eclipse.jdt.ui/cleanup.add_missing_nls_tags=false +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.ignorelowercasenames=true +/instance/org.eclipse.jdt.ui/cleanup.remove_private_constructors=true +/instance/org.eclipse.jdt.ui/cleanup.add_default_serial_version_id=true +/instance/org.eclipse.jdt.ui/cleanup.use_blocks=true +/instance/org.eclipse.jdt.ui/cleanup.convert_to_enhanced_for_loop=false +file_export_version=3.0 +/instance/org.eclipse.jdt.ui/formatter_settings_version=12 +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.exception.name=e +/instance/org.eclipse.jdt.ui/cleanup.qualify_static_field_accesses_with_declaring_class=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.cleanupprofiles=\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.importorder=java;javax;org;com; +/instance/org.eclipse.jdt.ui/cleanup_profile=_fineractdevprofile +/instance/org.eclipse.jdt.ui/cleanup.qualify_static_member_accesses_with_declaring_class=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +/instance/org.eclipse.jdt.ui/cleanup.use_parentheses_in_expressions=false +\!/= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.compliance=1.6 +/instance/org.eclipse.jdt.ui/cleanup.sort_members=false +/instance/org.eclipse.jdt.ui/cleanup.use_this_for_non_static_field_access_only_if_necessary=false +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.staticondemandthreshold=99 +/instance/org.eclipse.jdt.ui/cleanup.never_use_parentheses_in_expressions=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.localSuffixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.fieldSuffixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.localPrefixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.fieldPrefixes= +/instance/org.eclipse.jdt.ui/cleanup.make_variable_declarations_final=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.formatterprofiles=\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.keywordthis=true +/instance/org.eclipse.jdt.ui/cleanup.add_missing_override_annotations=true +/instance/org.eclipse.jdt.ui/cleanup.remove_unnecessary_nls_tags=true +/instance/org.eclipse.jdt.ui/formatter_profile=_fineractdevprojectformatter +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +/instance/org.eclipse.jdt.ui/cleanup.organize_imports=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.formatterprofiles.version=12 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +@org.eclipse.jdt.core=3.7.1.v_B76_R37x +/instance/org.eclipse.jdt.ui/cleanup.remove_unused_private_types=true +/instance/org.eclipse.jdt.ui/cleanup.add_missing_methods=true +/instance/org.eclipse.jdt.ui/cleanup.remove_unused_imports=true +/instance/org.eclipse.jdt.ui/cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +/instance/org.eclipse.jdt.ui/cleanup.always_use_this_for_non_static_method_access=false +/instance/org.eclipse.jdt.ui/cleanup.always_use_this_for_non_static_field_access=true +/instance/org.eclipse.jdt.ui/cleanup.add_missing_annotations=true +/instance/org.eclipse.jdt.ui/cleanup.use_this_for_non_static_field_access=true +/instance/org.eclipse.jdt.ui/cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +/instance/org.eclipse.jdt.ui/cleanup.remove_trailing_whitespaces_all=true +/instance/org.eclipse.jdt.ui/cleanup.never_use_blocks=false +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.gettersetter.use.is=true +/instance/org.eclipse.jdt.ui/cleanup.format_source_code_changes_only=false +/instance/org.eclipse.jdt.ui/cleanup.remove_unused_private_methods=true +/instance/org.eclipse.jdt.ui/cleanup.add_generated_serial_version_id=false +/instance/org.eclipse.jdt.ui/cleanup.remove_trailing_whitespaces_ignore_empty=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.source=1.6 +/instance/org.eclipse.jdt.ui/cleanup.use_this_for_non_static_method_access=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +/instance/org.eclipse.jdt.ui/cleanup.sort_members_all=false +/instance/org.eclipse.jdt.ui/cleanup.use_this_for_non_static_method_access_only_if_necessary=true +/instance/org.eclipse.jdt.ui/cleanup.remove_unused_private_fields=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.overrideannotation=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +/instance/org.eclipse.jdt.ui/cleanup.qualify_static_method_accesses_with_declaring_class=false +/instance/org.eclipse.jdt.ui/cleanup_settings_version=2 +/instance/org.eclipse.jdt.ui/cleanup.make_type_abstract_if_missing_method=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +/instance/org.eclipse.jdt.ui/cleanup.remove_unused_local_variables=false +/instance/org.eclipse.jdt.ui/cleanup.make_local_variable_final=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= +/instance/org.eclipse.jdt.ui/cleanup.format_source_code=true +/instance/org.eclipse.jdt.ui/cleanup.correct_indentation=true +/instance/org.eclipse.jdt.ui/cleanup.remove_unnecessary_casts=true +/instance/org.eclipse.jdt.ui/cleanup.remove_unused_private_members=false +/instance/org.eclipse.jdt.ui/cleanup.add_missing_deprecated_annotations=true +/instance/org.eclipse.jdt.ui/cleanup.use_blocks_only_for_return_and_throw=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.text.custom_code_templates= diff --git a/docs/system-architecture/.gitattributes b/docs/system-architecture/.gitattributes new file mode 100644 index 000000000..212566614 --- /dev/null +++ b/docs/system-architecture/.gitattributes @@ -0,0 +1 @@ +* text=auto \ No newline at end of file diff --git a/docs/system-architecture/.gitignore b/docs/system-architecture/.gitignore new file mode 100644 index 000000000..16b2d7d0a --- /dev/null +++ b/docs/system-architecture/.gitignore @@ -0,0 +1,2 @@ +# Include your project-specific ignores in this file +# Read about how to use .gitignore: https://help.github.com/articles/ignoring-files diff --git a/docs/system-architecture/.htaccess b/docs/system-architecture/.htaccess new file mode 100644 index 000000000..64b43ad14 --- /dev/null +++ b/docs/system-architecture/.htaccess @@ -0,0 +1,544 @@ +# Apache Configuration File + +# (!) Using `.htaccess` files slows down Apache, therefore, if you have access +# to the main server config file (usually called `httpd.conf`), you should add +# this logic there: http://httpd.apache.org/docs/current/howto/htaccess.html. + +# ############################################################################## +# # CROSS-ORIGIN RESOURCE SHARING (CORS) # +# ############################################################################## + +# ------------------------------------------------------------------------------ +# | Cross-domain AJAX requests | +# ------------------------------------------------------------------------------ + +# Enable cross-origin AJAX requests. +# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity +# http://enable-cors.org/ + +# +# Header set Access-Control-Allow-Origin "*" +# + +# ------------------------------------------------------------------------------ +# | CORS-enabled images | +# ------------------------------------------------------------------------------ + +# Send the CORS header for images when browsers request it. +# https://developer.mozilla.org/en/CORS_Enabled_Image +# http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html +# http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/ + + + + + SetEnvIf Origin ":" IS_CORS + Header set Access-Control-Allow-Origin "*" env=IS_CORS + + + + +# ------------------------------------------------------------------------------ +# | Web fonts access | +# ------------------------------------------------------------------------------ + +# Allow access from all domains for web fonts + + + + Header set Access-Control-Allow-Origin "*" + + + + +# ############################################################################## +# # ERRORS # +# ############################################################################## + +# ------------------------------------------------------------------------------ +# | 404 error prevention for non-existing redirected folders | +# ------------------------------------------------------------------------------ + +# Prevent Apache from returning a 404 error for a rewrite if a directory +# with the same name does not exist. +# http://httpd.apache.org/docs/current/content-negotiation.html#multiviews +# http://www.webmasterworld.com/apache/3808792.htm + +Options -MultiViews + +# ------------------------------------------------------------------------------ +# | Custom error messages / pages | +# ------------------------------------------------------------------------------ + +# You can customize what Apache returns to the client in case of an error (see +# http://httpd.apache.org/docs/current/mod/core.html#errordocument), e.g.: + +ErrorDocument 404 /404.html + + +# ############################################################################## +# # INTERNET EXPLORER # +# ############################################################################## + +# ------------------------------------------------------------------------------ +# | Better website experience | +# ------------------------------------------------------------------------------ + +# Force IE to render pages in the highest available mode in the various +# cases when it may not: http://hsivonen.iki.fi/doctype/ie-mode.pdf. +# Use, if installed, Google Chrome Frame. + + + Header set X-UA-Compatible "IE=edge,chrome=1" + # `mod_headers` can't match based on the content-type, however, we only + # want to send this header for HTML pages and not for the other resources + + Header unset X-UA-Compatible + + + +# ------------------------------------------------------------------------------ +# | Cookie setting from iframes | +# ------------------------------------------------------------------------------ + +# Allow cookies to be set from iframes in IE. + +# +# Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"" +# + +# ------------------------------------------------------------------------------ +# | Screen flicker | +# ------------------------------------------------------------------------------ + +# Stop screen flicker in IE on CSS rollovers (this only works in +# combination with the `ExpiresByType` directives for images from below). + +# BrowserMatch "MSIE" brokenvary=1 +# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1 +# BrowserMatch "Opera" !brokenvary +# SetEnvIf brokenvary 1 force-no-vary + + +# ############################################################################## +# # MIME TYPES AND ENCODING # +# ############################################################################## + +# ------------------------------------------------------------------------------ +# | Proper MIME types for all files | +# ------------------------------------------------------------------------------ + + + + # Audio + AddType audio/mp4 m4a f4a f4b + AddType audio/ogg oga ogg + + # JavaScript + # Normalize to standard type (it's sniffed in IE anyways): + # http://tools.ietf.org/html/rfc4329#section-7.2 + AddType application/javascript js jsonp + AddType application/json json + + # Video + AddType video/mp4 mp4 m4v f4v f4p + AddType video/ogg ogv + AddType video/webm webm + AddType video/x-flv flv + + # Web fonts + AddType application/font-woff woff + AddType application/vnd.ms-fontobject eot + + # Browsers usually ignore the font MIME types and sniff the content, + # however, Chrome shows a warning if other MIME types are used for the + # following fonts. + AddType application/x-font-ttf ttc ttf + AddType font/opentype otf + + # Make SVGZ fonts work on iPad: + # https://twitter.com/FontSquirrel/status/14855840545 + AddType image/svg+xml svg svgz + AddEncoding gzip svgz + + # Other + AddType application/octet-stream safariextz + AddType application/x-chrome-extension crx + AddType application/x-opera-extension oex + AddType application/x-shockwave-flash swf + AddType application/x-web-app-manifest+json webapp + AddType application/x-xpinstall xpi + AddType application/xml atom rdf rss xml + AddType image/webp webp + AddType image/x-icon ico + AddType text/cache-manifest appcache manifest + AddType text/vtt vtt + AddType text/x-component htc + AddType text/x-vcard vcf + + + +# ------------------------------------------------------------------------------ +# | UTF-8 encoding | +# ------------------------------------------------------------------------------ + +# Use UTF-8 encoding for anything served as `text/html` or `text/plain`. +AddDefaultCharset utf-8 + +# Force UTF-8 for certain file formats. + + AddCharset utf-8 .atom .css .js .json .rss .vtt .webapp .xml + + + +# ############################################################################## +# # URL REWRITES # +# ############################################################################## + +# ------------------------------------------------------------------------------ +# | Rewrite engine | +# ------------------------------------------------------------------------------ + +# Turning on the rewrite engine and enabling the `FollowSymLinks` option is +# necessary for the following directives to work. + +# If your web host doesn't allow the `FollowSymlinks` option, you may need to +# comment it out and use `Options +SymLinksIfOwnerMatch` but, be aware of the +# performance impact: http://httpd.apache.org/docs/current/misc/perf-tuning.html#symlinks + +# Also, some cloud hosting services require `RewriteBase` to be set: +# http://www.rackspace.com/knowledge_center/frequently-asked-question/why-is-mod-rewrite-not-working-on-my-site + + + Options +FollowSymlinks + # Options +SymLinksIfOwnerMatch + RewriteEngine On + # RewriteBase / + + +# ------------------------------------------------------------------------------ +# | Suppressing / Forcing the "www." at the beginning of URLs | +# ------------------------------------------------------------------------------ + +# The same content should never be available under two different URLs especially +# not with and without "www." at the beginning. This can cause SEO problems +# (duplicate content), therefore, you should choose one of the alternatives and +# redirect the other one. + +# By default option 1 (no "www.") is activated: +# http://no-www.org/faq.php?q=class_b + +# If you'd prefer to use option 2, just comment out all the lines from option 1 +# and uncomment the ones from option 2. + +# IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME! + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +# Option 1: rewrite www.example.com → example.com + + + RewriteCond %{HTTPS} !=on + RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] + RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +# Option 2: rewrite example.com → www.example.com + +# Be aware that the following might not be a good idea if you use "real" +# subdomains for certain parts of your website. + +# +# RewriteCond %{HTTPS} !=on +# RewriteCond %{HTTP_HOST} !^www\..+$ [NC] +# RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] +# + + +# ############################################################################## +# # SECURITY # +# ############################################################################## + +# ------------------------------------------------------------------------------ +# | Content Security Policy (CSP) | +# ------------------------------------------------------------------------------ + +# You can mitigate the risk of cross-site scripting and other content-injection +# attacks by setting a Content Security Policy which whitelists trusted sources +# of content for your site. + +# The example header below allows ONLY scripts that are loaded from the current +# site's origin (no inline scripts, no CDN, etc). This almost certainly won't +# work as-is for your site! + +# To get all the details you'll need to craft a reasonable policy for your site, +# read: http://html5rocks.com/en/tutorials/security/content-security-policy (or +# see the specification: http://w3.org/TR/CSP). + +# +# Header set Content-Security-Policy "script-src 'self'; object-src 'self'" +# +# Header unset Content-Security-Policy +# +# + +# ------------------------------------------------------------------------------ +# | File access | +# ------------------------------------------------------------------------------ + +# Block access to directories without a default document. +# Usually you should leave this uncommented because you shouldn't allow anyone +# to surf through every directory on your server (which may includes rather +# private places like the CMS's directories). + + + Options -Indexes + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +# Block access to hidden files and directories. +# This includes directories used by version control systems such as Git and SVN. + + + RewriteCond %{SCRIPT_FILENAME} -d [OR] + RewriteCond %{SCRIPT_FILENAME} -f + RewriteRule "(^|/)\." - [F] + + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +# Block access to backup and source files. +# These files may be left by some text editors and can pose a great security +# danger when anyone has access to them. + + + Order allow,deny + Deny from all + Satisfy All + + +# ------------------------------------------------------------------------------ +# | Secure Sockets Layer (SSL) | +# ------------------------------------------------------------------------------ + +# Rewrite secure requests properly to prevent SSL certificate warnings, e.g.: +# prevent `https://www.example.com` when your certificate only allows +# `https://secure.example.com`. + +# +# RewriteCond %{SERVER_PORT} !^443 +# RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L] +# + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +# Force client-side SSL redirection. + +# If a user types "example.com" in his browser, the above rule will redirect him +# to the secure version of the site. That still leaves a window of opportunity +# (the initial HTTP connection) for an attacker to downgrade or redirect the +# request. The following header ensures that browser will ONLY connect to your +# server via HTTPS, regardless of what the users type in the address bar. +# http://www.html5rocks.com/en/tutorials/security/transport-layer-security/ + +# +# Header set Strict-Transport-Security max-age=16070400; +# + +# ------------------------------------------------------------------------------ +# | Server software information | +# ------------------------------------------------------------------------------ + +# Avoid displaying the exact Apache version number, the description of the +# generic OS-type and the information about Apache's compiled-in modules. + +# ADD THIS DIRECTIVE IN THE `httpd.conf` AS IT WILL NOT WORK IN THE `.htaccess`! + +# ServerTokens Prod + + +# ############################################################################## +# # WEB PERFORMANCE # +# ############################################################################## + +# ------------------------------------------------------------------------------ +# | Compression | +# ------------------------------------------------------------------------------ + + + + # Force compression for mangled headers. + # http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping + + + SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding + RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding + + + + # Compress all output labeled with one of the following MIME-types + # (for Apache versions below 2.3.7, you don't need to enable `mod_filter` + # and can remove the `` and `` lines + # as `AddOutputFilterByType` is still in the core directives). + + AddOutputFilterByType DEFLATE application/atom+xml \ + application/javascript \ + application/json \ + application/rss+xml \ + application/vnd.ms-fontobject \ + application/x-font-ttf \ + application/x-web-app-manifest+json \ + application/xhtml+xml \ + application/xml \ + font/opentype \ + image/svg+xml \ + image/x-icon \ + text/css \ + text/html \ + text/plain \ + text/x-component \ + text/xml + + + + +# ------------------------------------------------------------------------------ +# | Content transformations | +# ------------------------------------------------------------------------------ + +# Prevent some of the mobile network providers from modifying the content of +# your site: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5. + +# +# Header set Cache-Control "no-transform" +# + +# ------------------------------------------------------------------------------ +# | ETag removal | +# ------------------------------------------------------------------------------ + +# Since we're sending far-future expires headers (see below), ETags can +# be removed: http://developer.yahoo.com/performance/rules.html#etags. + +# `FileETag None` is not enough for every server. + + Header unset ETag + + +FileETag None + +# ------------------------------------------------------------------------------ +# | Expires headers (for better cache control) | +# ------------------------------------------------------------------------------ + +# The following expires headers are set pretty far in the future. If you don't +# control versioning with filename-based cache busting, consider lowering the +# cache time for resources like CSS and JS to something like 1 week. + + + + ExpiresActive on + ExpiresDefault "access plus 1 month" + + # CSS + ExpiresByType text/css "access plus 1 year" + + # Data interchange + ExpiresByType application/json "access plus 0 seconds" + ExpiresByType application/xml "access plus 0 seconds" + ExpiresByType text/xml "access plus 0 seconds" + + # Favicon (cannot be renamed!) + ExpiresByType image/x-icon "access plus 1 week" + + # HTML components (HTCs) + ExpiresByType text/x-component "access plus 1 month" + + # HTML + ExpiresByType text/html "access plus 0 seconds" + + # JavaScript + ExpiresByType application/javascript "access plus 1 year" + + # Manifest files + ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds" + ExpiresByType text/cache-manifest "access plus 0 seconds" + + # Media + ExpiresByType audio/ogg "access plus 1 month" + ExpiresByType image/gif "access plus 1 month" + ExpiresByType image/jpeg "access plus 1 month" + ExpiresByType image/png "access plus 1 month" + ExpiresByType video/mp4 "access plus 1 month" + ExpiresByType video/ogg "access plus 1 month" + ExpiresByType video/webm "access plus 1 month" + + # Web feeds + ExpiresByType application/atom+xml "access plus 1 hour" + ExpiresByType application/rss+xml "access plus 1 hour" + + # Web fonts + ExpiresByType application/font-woff "access plus 1 month" + ExpiresByType application/vnd.ms-fontobject "access plus 1 month" + ExpiresByType application/x-font-ttf "access plus 1 month" + ExpiresByType font/opentype "access plus 1 month" + ExpiresByType image/svg+xml "access plus 1 month" + + + +# ------------------------------------------------------------------------------ +# | Filename-based cache busting | +# ------------------------------------------------------------------------------ + +# If you're not using a build process to manage your filename version revving, +# you might want to consider enabling the following directives to route all +# requests such as `/css/style.12345.css` to `/css/style.css`. + +# To understand why this is important and a better idea than `*.css?v231`, read: +# http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring + +# +# RewriteCond %{REQUEST_FILENAME} !-f +# RewriteCond %{REQUEST_FILENAME} !-d +# RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L] +# + +# ------------------------------------------------------------------------------ +# | File concatenation | +# ------------------------------------------------------------------------------ + +# Allow concatenation from within specific CSS and JS files, e.g.: +# Inside of `script.combined.js` you could have +# +# +# and they would be included into this single file. + +# +# +# Options +Includes +# AddOutputFilterByType INCLUDES application/javascript application/json +# SetOutputFilter INCLUDES +# +# +# Options +Includes +# AddOutputFilterByType INCLUDES text/css +# SetOutputFilter INCLUDES +# +# + +# ------------------------------------------------------------------------------ +# | Persistent connections | +# ------------------------------------------------------------------------------ + +# Allow multiple requests to be sent over the same TCP connection: +# http://httpd.apache.org/docs/current/en/mod/core.html#keepalive. + +# Enable if you serve a lot of static content but, be aware of the +# possible disadvantages! + +# +# Header set Connection Keep-Alive +# diff --git a/docs/system-architecture/404.html b/docs/system-architecture/404.html new file mode 100644 index 000000000..fdace4ab1 --- /dev/null +++ b/docs/system-architecture/404.html @@ -0,0 +1,157 @@ + + + + + Page Not Found :( + + + +
+

Not found :(

+

Sorry, but the page you were trying to view does not exist.

+

It looks like this was the result of either:

+
    +
  • a mistyped address
  • +
  • an out-of-date link
  • +
+ + +
+ + diff --git a/docs/system-architecture/CHANGELOG.md b/docs/system-architecture/CHANGELOG.md new file mode 100644 index 000000000..c6ea12538 --- /dev/null +++ b/docs/system-architecture/CHANGELOG.md @@ -0,0 +1,122 @@ +### HEAD + +### 4.2.0 (April 8, 2013) + +* Remove Google Analytics protocol check ([#1319](https://github.com/h5bp/html5-boilerplate/pull/1319)). +* Update to Normalize.css 1.1.1. +* Update Apache configurations to include the latest changes in the canonical + [`.htaccess`](https://github.com/h5bp/server-configs/blob/master/apache/.htaccess) + file. +* Use a protocol relative URL for the 404 template script. +* Update to jQuery 1.9.1. + +### 4.1.0 (January 21, 2013) + +* Update to Normalize.css 1.1.0. +* Update to jQuery 1.9.0. + +### 4.0.3 (January 12, 2013) + +* Use 32x32 favicon.ico ([#1286](https://github.com/h5bp/html5-boilerplate/pull/1286)). +* Remove named function expression in plugins.js ([#1280](https://github.com/h5bp/html5-boilerplate/pull/1280)). +* Adjust CSS image-replacement code ([#1239](https://github.com/h5bp/html5-boilerplate/issues/1239)). +* Update HiDPI example media query ([#1127](https://github.com/h5bp/html5-boilerplate/issues/1127)). + +### 4.0.2 (December 9, 2012) + +* Update placeholder icons. +* Update to Normalize.css 1.0.2. +* Update to jQuery 1.8.3. + +### 4.0.1 (October 20, 2012) + +* Further improvements to `console` method stubbing ([#1206](https://github.com/h5bp/html5-boilerplate/issues/1206), [#1229](https://github.com/h5bp/html5-boilerplate/pull/1229)). +* Update to jQuery 1.8.2. +* Update to Modernizr 2.6.2. +* Minor additions to the documentation. + +### 4.0.0 (August 28, 2012) + +* Improve the Apache compression configuration ([#1012](https://github.com/h5bp/html5-boilerplate/issues/1012), [#1173](https://github.com/h5bp/html5-boilerplate/issues/1173)). +* Add a HiDPI example media query ([#1127](https://github.com/h5bp/html5-boilerplate/issues/1127)). +* Add bundled docs ([#1154](https://github.com/h5bp/html5-boilerplate/issues/1154)). +* Add MIT license ([#1139](https://github.com/h5bp/html5-boilerplate/issues/1139)). +* Update to Normalize.css 1.0.1. +* Separate Normalize.css from the rest of the CSS ([#1160](https://github.com/h5bp/html5-boilerplate/issues/1160)). +* Improve `console.log` protection ([#1107](https://github.com/h5bp/html5-boilerplate/issues/1107)). +* Replace hot pink text selection color with a neutral color. +* Change image replacement technique ([#1149](https://github.com/h5bp/html5-boilerplate/issues/1149)). +* Code format and consistency changes ([#1112](https://github.com/h5bp/html5-boilerplate/issues/1112)). +* Rename CSS file and rename JS files and subdirectories. +* Update to jQuery 1.8 ([#1161](https://github.com/h5bp/html5-boilerplate/issues/1161)). +* Update to Modernizr 2.6.1 ([#1086](https://github.com/h5bp/html5-boilerplate/issues/1086)). +* Remove uncompressed jQuery ([#1153](https://github.com/h5bp/html5-boilerplate/issues/1153)). +* Remove superfluous inline comments ([#1150](https://github.com/h5bp/html5-boilerplate/issues/1150)). + +### 3.0.2 (February 19, 2012) + +* Update to Modernizr 2.5.3. + +### 3.0.1 (February 08, 2012). + +* Update to Modernizr 2.5.2 (includes html5shiv 3.3). + +### 3.0.0 (February 06, 2012) + +* Improvements to `.htaccess`. +* Improve 404 design. +* Simplify JS folder structure. +* Change `html` IE class names changed to target ranges rather than specific versions of IE. +* Update CSS to include latest normalize.css changes and better typographic defaults ([#825](https://github.com/h5bp/html5-boilerplate/issues/825)). +* Update to Modernizr 2.5 (includes yepnope 1.5 and html5shiv 3.2). +* Update to jQuery 1.7.1. +* Revert to async snippet for the Google Analytics script. +* Remove the ant build script ([#826](https://github.com/h5bp/html5-boilerplate/issues/826)). +* Remove Respond.js ([#816](https://github.com/h5bp/html5-boilerplate/issues/816)). +* Remove the `demo/` directory ([#808](https://github.com/h5bp/html5-boilerplate/issues/808)). +* Remove the `test/` directory ([#808](https://github.com/h5bp/html5-boilerplate/issues/808)). +* Remove Google Chrome Frame script for IE6 users; replace with links to Chrome Frame and options for alternative browsers. +* Remove `initial-scale=1` from the viewport `meta` ([#824](https://github.com/h5bp/html5-boilerplate/issues/824)). +* Remove `defer` from all scripts to avoid legacy IE bugs. +* Remove explicit Site Speed tracking for Google Analytics. It's now enabled by default. + +### 2.0.0 (August 10, 2011) + +* Change starting CSS to be based on normalize.css instead of reset.css ([#500](https://github.com/h5bp/html5-boilerplate/issues/500)). +* Add Respond.js media query polyfill. +* Add Google Chrome Frame script prompt for IE6 users. +* Simplify the `html` conditional comments for modern browsers and add an `oldie` class. +* Update clearfix to use "micro clearfix". +* Add placeholder CSS MQs for mobile-first approach. +* Add `textarea { resize: vertical; }` to only allow vertical resizing. +* Add `img { max-width: 100%; }` to the print styles; prevents images being truncated. +* Add Site Speed tracking for Google Analytics. +* Update to jQuery 1.6.2 (and use minified by default). +* Update to Modernizr 2.0 Complete, Production minified (includes yepnope, html5shiv, and Respond.js). +* Use `Modernizr.load()` to load the Google Analytics script. +* Much faster build process. +* Add build script options for CSSLint, JSLint, JSHint tools. +* Build script now compresses all images in subfolders. +* Build script now versions files by SHA hash. +* Many `.htaccess` improvements including: disable directory browsing, improved support for all versions of Apache, more robust and extensive HTTP compression rules. +* Remove `handheld.css` as it has very poor device support. +* Remove touch-icon `link` elements from the HTML and include improved touch-icon support. +* Remove the cache-busting query paramaters from files references in the HTML. +* Remove IE6 PNGFix. + +### 1.0.0 (March 21, 2011) + +* Rewrite build script to make it more customizable and flexible. +* Add a humans.txt. +* Numerous `.htaccess` improvements (including inline documentation). +* Move the alternative server configurations to the H5BP server configs repo. +* Use a protocol-relative url to reference jQuery and prevent mixed content warnings. +* Optimize the Google Analytics snippet. +* Use Eric Meyer's recent CSS reset update and the HTML5 Doctor reset. +* More robust `sub`/`sup` CSS styles. +* Add keyboard `.focusable` helper class that extends `.visuallyhidden`. +* Print styles no longer print hash or JavaScript links. +* Add a print reset for IE's proprietary filters. +* Remove IE9-specific conditional class on the `html` element. +* Remove margins from lists within `nav` elements. +* Remove YUI profiling. diff --git a/docs/system-architecture/CONTRIBUTING.md b/docs/system-architecture/CONTRIBUTING.md new file mode 100644 index 000000000..6facbb646 --- /dev/null +++ b/docs/system-architecture/CONTRIBUTING.md @@ -0,0 +1,118 @@ +# Contributing to HTML5 Boilerplate + +♥ [HTML5 Boilerplate](http://html5boilerplate.com) and want to get involved? +Thanks! There are plenty of ways you can help! + + +## Bugs + +A bug is a _demonstrable problem_ that is caused by the code in the +repository. Good bug reports are extremely helpful - thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been + reported. + +2. **Check if the issue has been fixed** — try to reproduce it using the + latest `master` branch in the repository. + +3. **Isolate the problem** — ideally create a [reduced test + case](http://css-tricks.com/6263-reduced-test-cases/) and a live example. + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. What is +your environment? What steps will reproduce the issue? What browser(s) and OS +experience the problem? What would you expect to be the outcome? All these +details will help people to fix any potential bugs. + +Example: + +> Short and descriptive example bug report title +> +> A summary of the issue and the browser/OS environment in which it occurs. If +> suitable, include the steps required to reproduce the bug. +> +> 1. This is the first step +> 2. This is the second step +> 3. Further steps, etc. +> +> `` (a link to the reduced test case) +> +> Any other information you want to share that is relevant to the issue being +> reported. This might include the lines of code that you have identified as +> causing the bug, and potential solutions (and your opinions on their +> merits). + +**[File a bug report](https://github.com/h5bp/html5-boilerplate/issues/)** + + +## Pull requests + +Good pull requests - patches, improvements, new features - are a fantastic +help. They should remain focused in scope and avoid containing unrelated +commits. If your contribution involves a significant amount of work or substantial +changes to any part of the project, please open an issue to discuss it first. + +Make sure to adhere to the coding conventions used throughout a project +(indentation, accurate comments, etc.). Please update any documentation that is +relevant to the change you're making. + +Please follow this process; it's the best way to get your work included in the +project: + +1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, + and configure the remotes: + + ```bash + # Clones your fork of the repo into the current directory in terminal + git clone https://github.com//html5-boilerplate.git + # Navigate to the newly cloned directory + cd html5-boilerplate + # Assigns the original repo to a remote called "upstream" + git remote add upstream https://github.com/h5bp/html5-boilerplate.git + ``` + +2. If you cloned a while ago, get the latest changes from upstream: + + ```bash + git checkout master + git pull upstream master + ``` + +3. Create a new topic branch to contain your feature, change, or fix: + + ```bash + git checkout -b + ``` + +4. Commit your changes in logical chunks. Please adhere to these [git commit + message + guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) + or your pull request is unlikely be merged into the main project. Use git's + [interactive rebase](https://help.github.com/articles/interactive-rebase) + feature to tidy up your commits before making them public. + +5. Locally merge (or rebase) the upstream development branch into your topic branch: + + ```bash + git pull [--rebase] upstream master + ``` + +6. Push your topic branch up to your fork: + + ```bash + git push origin + ``` + +10. [Open a Pull Request](https://help.github.com/articles/using-pull-requests) with a + clear title and description. + + +## Do not… + +Please **do not** use the issue tracker for personal support requests (use +[StackOverflow](http://stackoverflow.com/questions/tagged/html5boilerplate) or IRC). + +Please **do not** derail or troll issues. Keep the +discussion on topic and respect the opinions of others. diff --git a/docs/system-architecture/apple-touch-icon-114x114-precomposed.png b/docs/system-architecture/apple-touch-icon-114x114-precomposed.png new file mode 100644 index 000000000..0fdf60e8f Binary files /dev/null and b/docs/system-architecture/apple-touch-icon-114x114-precomposed.png differ diff --git a/docs/system-architecture/apple-touch-icon-144x144-precomposed.png b/docs/system-architecture/apple-touch-icon-144x144-precomposed.png new file mode 100644 index 000000000..257c77acf Binary files /dev/null and b/docs/system-architecture/apple-touch-icon-144x144-precomposed.png differ diff --git a/docs/system-architecture/apple-touch-icon-57x57-precomposed.png b/docs/system-architecture/apple-touch-icon-57x57-precomposed.png new file mode 100644 index 000000000..99b60545a Binary files /dev/null and b/docs/system-architecture/apple-touch-icon-57x57-precomposed.png differ diff --git a/docs/system-architecture/apple-touch-icon-72x72-precomposed.png b/docs/system-architecture/apple-touch-icon-72x72-precomposed.png new file mode 100644 index 000000000..8345cc3f1 Binary files /dev/null and b/docs/system-architecture/apple-touch-icon-72x72-precomposed.png differ diff --git a/docs/system-architecture/apple-touch-icon-precomposed.png b/docs/system-architecture/apple-touch-icon-precomposed.png new file mode 100644 index 000000000..99b60545a Binary files /dev/null and b/docs/system-architecture/apple-touch-icon-precomposed.png differ diff --git a/docs/system-architecture/apple-touch-icon.png b/docs/system-architecture/apple-touch-icon.png new file mode 100644 index 000000000..99b60545a Binary files /dev/null and b/docs/system-architecture/apple-touch-icon.png differ diff --git a/docs/system-architecture/crossdomain.xml b/docs/system-architecture/crossdomain.xml new file mode 100644 index 000000000..29a035d7f --- /dev/null +++ b/docs/system-architecture/crossdomain.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/docs/system-architecture/css/bootstrap-3.0.0/bootstrap-theme.css b/docs/system-architecture/css/bootstrap-3.0.0/bootstrap-theme.css new file mode 100644 index 000000000..ad1173569 --- /dev/null +++ b/docs/system-architecture/css/bootstrap-3.0.0/bootstrap-theme.css @@ -0,0 +1,384 @@ +.btn-default, +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger { + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.btn-default:active, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active, +.btn-default.active, +.btn-primary.active, +.btn-success.active, +.btn-info.active, +.btn-warning.active, +.btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} + +.btn:active, +.btn.active { + background-image: none; +} + +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, 0%, #e6e6e6, 100%); + background-image: -moz-linear-gradient(top, #ffffff 0%, #e6e6e6 100%); + background-image: linear-gradient(to bottom, #ffffff 0%, #e6e6e6 100%); + background-repeat: repeat-x; + border-color: #e0e0e0; + border-color: #ccc; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); +} + +.btn-default:active, +.btn-default.active { + background-color: #e6e6e6; + border-color: #e0e0e0; +} + +.btn-primary { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9)); + background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%); + background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); + background-repeat: repeat-x; + border-color: #2d6ca2; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); +} + +.btn-primary:active, +.btn-primary.active { + background-color: #3071a9; + border-color: #2d6ca2; +} + +.btn-success { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5cb85c), to(#449d44)); + background-image: -webkit-linear-gradient(top, #5cb85c, 0%, #449d44, 100%); + background-image: -moz-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + background-repeat: repeat-x; + border-color: #419641; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); +} + +.btn-success:active, +.btn-success.active { + background-color: #449d44; + border-color: #419641; +} + +.btn-warning { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f0ad4e), to(#ec971f)); + background-image: -webkit-linear-gradient(top, #f0ad4e, 0%, #ec971f, 100%); + background-image: -moz-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + background-repeat: repeat-x; + border-color: #eb9316; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); +} + +.btn-warning:active, +.btn-warning.active { + background-color: #ec971f; + border-color: #eb9316; +} + +.btn-danger { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9534f), to(#c9302c)); + background-image: -webkit-linear-gradient(top, #d9534f, 0%, #c9302c, 100%); + background-image: -moz-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + background-repeat: repeat-x; + border-color: #c12e2a; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); +} + +.btn-danger:active, +.btn-danger.active { + background-color: #c9302c; + border-color: #c12e2a; +} + +.btn-info { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5bc0de), to(#31b0d5)); + background-image: -webkit-linear-gradient(top, #5bc0de, 0%, #31b0d5, 100%); + background-image: -moz-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + background-repeat: repeat-x; + border-color: #2aabd2; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); +} + +.btn-info:active, +.btn-info.active { + background-color: #31b0d5; + border-color: #2aabd2; +} + +.thumbnail, +.img-thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + background-color: #357ebd; + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#357ebd)); + background-image: -webkit-linear-gradient(top, #428bca, 0%, #357ebd, 100%); + background-image: -moz-linear-gradient(top, #428bca 0%, #357ebd 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); +} + +.navbar { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ffffff), to(#f8f8f8)); + background-image: -webkit-linear-gradient(top, #ffffff, 0%, #f8f8f8, 100%); + background-image: -moz-linear-gradient(top, #ffffff 0%, #f8f8f8 100%); + background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%); + background-repeat: repeat-x; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); +} + +.navbar .navbar-nav > .active > a { + background-color: #f8f8f8; +} + +.navbar-brand, +.navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); +} + +.navbar-inverse { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#3c3c3c), to(#222222)); + background-image: -webkit-linear-gradient(top, #3c3c3c, 0%, #222222, 100%); + background-image: -moz-linear-gradient(top, #3c3c3c 0%, #222222 100%); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); +} + +.navbar-inverse .navbar-nav > .active > a { + background-color: #222222; +} + +.navbar-inverse .navbar-brand, +.navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.navbar-static-top, +.navbar-fixed-top, +.navbar-fixed-bottom { + border-radius: 0; +} + +.alert { + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.alert-success { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#dff0d8), to(#c8e5bc)); + background-image: -webkit-linear-gradient(top, #dff0d8, 0%, #c8e5bc, 100%); + background-image: -moz-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + background-repeat: repeat-x; + border-color: #b2dba1; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); +} + +.alert-info { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9edf7), to(#b9def0)); + background-image: -webkit-linear-gradient(top, #d9edf7, 0%, #b9def0, 100%); + background-image: -moz-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + background-repeat: repeat-x; + border-color: #9acfea; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); +} + +.alert-warning { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#fcf8e3), to(#f8efc0)); + background-image: -webkit-linear-gradient(top, #fcf8e3, 0%, #f8efc0, 100%); + background-image: -moz-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + background-repeat: repeat-x; + border-color: #f5e79e; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); +} + +.alert-danger { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f2dede), to(#e7c3c3)); + background-image: -webkit-linear-gradient(top, #f2dede, 0%, #e7c3c3, 100%); + background-image: -moz-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + background-repeat: repeat-x; + border-color: #dca7a7; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); +} + +.progress { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#ebebeb), to(#f5f5f5)); + background-image: -webkit-linear-gradient(top, #ebebeb, 0%, #f5f5f5, 100%); + background-image: -moz-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); +} + +.progress-bar { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3071a9)); + background-image: -webkit-linear-gradient(top, #428bca, 0%, #3071a9, 100%); + background-image: -moz-linear-gradient(top, #428bca 0%, #3071a9 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); +} + +.progress-bar-success { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5cb85c), to(#449d44)); + background-image: -webkit-linear-gradient(top, #5cb85c, 0%, #449d44, 100%); + background-image: -moz-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); +} + +.progress-bar-info { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#5bc0de), to(#31b0d5)); + background-image: -webkit-linear-gradient(top, #5bc0de, 0%, #31b0d5, 100%); + background-image: -moz-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); +} + +.progress-bar-warning { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f0ad4e), to(#ec971f)); + background-image: -webkit-linear-gradient(top, #f0ad4e, 0%, #ec971f, 100%); + background-image: -moz-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); +} + +.progress-bar-danger { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9534f), to(#c9302c)); + background-image: -webkit-linear-gradient(top, #d9534f, 0%, #c9302c, 100%); + background-image: -moz-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); +} + +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); +} + +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + text-shadow: 0 -1px 0 #3071a9; + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#3278b3)); + background-image: -webkit-linear-gradient(top, #428bca, 0%, #3278b3, 100%); + background-image: -moz-linear-gradient(top, #428bca 0%, #3278b3 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%); + background-repeat: repeat-x; + border-color: #3278b3; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0); +} + +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.panel-default > .panel-heading { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f5f5f5), to(#e8e8e8)); + background-image: -webkit-linear-gradient(top, #f5f5f5, 0%, #e8e8e8, 100%); + background-image: -moz-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); +} + +.panel-primary > .panel-heading { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#428bca), to(#357ebd)); + background-image: -webkit-linear-gradient(top, #428bca, 0%, #357ebd, 100%); + background-image: -moz-linear-gradient(top, #428bca 0%, #357ebd 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); +} + +.panel-success > .panel-heading { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#dff0d8), to(#d0e9c6)); + background-image: -webkit-linear-gradient(top, #dff0d8, 0%, #d0e9c6, 100%); + background-image: -moz-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); +} + +.panel-info > .panel-heading { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#d9edf7), to(#c4e3f3)); + background-image: -webkit-linear-gradient(top, #d9edf7, 0%, #c4e3f3, 100%); + background-image: -moz-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); +} + +.panel-warning > .panel-heading { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#fcf8e3), to(#faf2cc)); + background-image: -webkit-linear-gradient(top, #fcf8e3, 0%, #faf2cc, 100%); + background-image: -moz-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); +} + +.panel-danger > .panel-heading { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#f2dede), to(#ebcccc)); + background-image: -webkit-linear-gradient(top, #f2dede, 0%, #ebcccc, 100%); + background-image: -moz-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); +} + +.well { + background-image: -webkit-gradient(linear, left 0%, left 100%, from(#e8e8e8), to(#f5f5f5)); + background-image: -webkit-linear-gradient(top, #e8e8e8, 0%, #f5f5f5, 100%); + background-image: -moz-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + background-repeat: repeat-x; + border-color: #dcdcdc; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); +} \ No newline at end of file diff --git a/docs/system-architecture/css/bootstrap-3.0.0/bootstrap-theme.min.css b/docs/system-architecture/css/bootstrap-3.0.0/bootstrap-theme.min.css new file mode 100644 index 000000000..cad36b4e6 --- /dev/null +++ b/docs/system-architecture/css/bootstrap-3.0.0/bootstrap-theme.min.css @@ -0,0 +1 @@ +.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,0%,#e6e6e6,100%);background-image:-moz-linear-gradient(top,#fff 0,#e6e6e6 100%);background-image:linear-gradient(to bottom,#fff 0,#e6e6e6 100%);background-repeat:repeat-x;border-color:#e0e0e0;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0)}.btn-default:active,.btn-default.active{background-color:#e6e6e6;border-color:#e0e0e0}.btn-primary{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3071a9));background-image:-webkit-linear-gradient(top,#428bca,0%,#3071a9,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;border-color:#2d6ca2;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.btn-primary:active,.btn-primary.active{background-color:#3071a9;border-color:#2d6ca2}.btn-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5cb85c),to(#449d44));background-image:-webkit-linear-gradient(top,#5cb85c,0%,#449d44,100%);background-image:-moz-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;border-color:#419641;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.btn-success:active,.btn-success.active{background-color:#449d44;border-color:#419641}.btn-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f0ad4e),to(#ec971f));background-image:-webkit-linear-gradient(top,#f0ad4e,0%,#ec971f,100%);background-image:-moz-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;border-color:#eb9316;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.btn-warning:active,.btn-warning.active{background-color:#ec971f;border-color:#eb9316}.btn-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9534f),to(#c9302c));background-image:-webkit-linear-gradient(top,#d9534f,0%,#c9302c,100%);background-image:-moz-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;border-color:#c12e2a;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.btn-danger:active,.btn-danger.active{background-color:#c9302c;border-color:#c12e2a}.btn-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5bc0de),to(#31b0d5));background-image:-webkit-linear-gradient(top,#5bc0de,0%,#31b0d5,100%);background-image:-moz-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;border-color:#2aabd2;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.btn-info:active,.btn-info.active{background-color:#31b0d5;border-color:#2aabd2}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#357ebd;background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#357ebd));background-image:-webkit-linear-gradient(top,#428bca,0%,#357ebd,100%);background-image:-moz-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.navbar{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#f8f8f8));background-image:-webkit-linear-gradient(top,#fff,0%,#f8f8f8,100%);background-image:-moz-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff8f8f8',GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar .navbar-nav>.active>a{background-color:#f8f8f8}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-gradient(linear,left 0,left 100%,from(#3c3c3c),to(#222));background-image:-webkit-linear-gradient(top,#3c3c3c,0%,#222,100%);background-image:-moz-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c',endColorstr='#ff222222',GradientType=0)}.navbar-inverse .navbar-nav>.active>a{background-color:#222}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#dff0d8),to(#c8e5bc));background-image:-webkit-linear-gradient(top,#dff0d8,0%,#c8e5bc,100%);background-image:-moz-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;border-color:#b2dba1;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffc8e5bc',GradientType=0)}.alert-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9edf7),to(#b9def0));background-image:-webkit-linear-gradient(top,#d9edf7,0%,#b9def0,100%);background-image:-moz-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;border-color:#9acfea;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffb9def0',GradientType=0)}.alert-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fcf8e3),to(#f8efc0));background-image:-webkit-linear-gradient(top,#fcf8e3,0%,#f8efc0,100%);background-image:-moz-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;border-color:#f5e79e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fff8efc0',GradientType=0)}.alert-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f2dede),to(#e7c3c3));background-image:-webkit-linear-gradient(top,#f2dede,0%,#e7c3c3,100%);background-image:-moz-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;border-color:#dca7a7;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffe7c3c3',GradientType=0)}.progress{background-image:-webkit-gradient(linear,left 0,left 100%,from(#ebebeb),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#ebebeb,0%,#f5f5f5,100%);background-image:-moz-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb',endColorstr='#fff5f5f5',GradientType=0)}.progress-bar{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3071a9));background-image:-webkit-linear-gradient(top,#428bca,0%,#3071a9,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.progress-bar-success{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5cb85c),to(#449d44));background-image:-webkit-linear-gradient(top,#5cb85c,0%,#449d44,100%);background-image:-moz-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.progress-bar-info{background-image:-webkit-gradient(linear,left 0,left 100%,from(#5bc0de),to(#31b0d5));background-image:-webkit-linear-gradient(top,#5bc0de,0%,#31b0d5,100%);background-image:-moz-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.progress-bar-warning{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f0ad4e),to(#ec971f));background-image:-webkit-linear-gradient(top,#f0ad4e,0%,#ec971f,100%);background-image:-moz-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.progress-bar-danger{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9534f),to(#c9302c));background-image:-webkit-linear-gradient(top,#d9534f,0%,#c9302c,100%);background-image:-moz-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#3278b3));background-image:-webkit-linear-gradient(top,#428bca,0%,#3278b3,100%);background-image:-moz-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;border-color:#3278b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3278b3',GradientType=0)}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f5f5f5),to(#e8e8e8));background-image:-webkit-linear-gradient(top,#f5f5f5,0%,#e8e8e8,100%);background-image:-moz-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#ffe8e8e8',GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#428bca),to(#357ebd));background-image:-webkit-linear-gradient(top,#428bca,0%,#357ebd,100%);background-image:-moz-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#dff0d8),to(#d0e9c6));background-image:-webkit-linear-gradient(top,#dff0d8,0%,#d0e9c6,100%);background-image:-moz-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffd0e9c6',GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#d9edf7),to(#c4e3f3));background-image:-webkit-linear-gradient(top,#d9edf7,0%,#c4e3f3,100%);background-image:-moz-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffc4e3f3',GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#fcf8e3),to(#faf2cc));background-image:-webkit-linear-gradient(top,#fcf8e3,0%,#faf2cc,100%);background-image:-moz-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fffaf2cc',GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-gradient(linear,left 0,left 100%,from(#f2dede),to(#ebcccc));background-image:-webkit-linear-gradient(top,#f2dede,0%,#ebcccc,100%);background-image:-moz-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffebcccc',GradientType=0)}.well{background-image:-webkit-gradient(linear,left 0,left 100%,from(#e8e8e8),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#e8e8e8,0%,#f5f5f5,100%);background-image:-moz-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;border-color:#dcdcdc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)} \ No newline at end of file diff --git a/docs/system-architecture/css/bootstrap-3.0.0/bootstrap.css b/docs/system-architecture/css/bootstrap-3.0.0/bootstrap.css new file mode 100644 index 000000000..bbda4eed4 --- /dev/null +++ b/docs/system-architecture/css/bootstrap-3.0.0/bootstrap.css @@ -0,0 +1,6805 @@ +/*! + * Bootstrap v3.0.0 + * + * Copyright 2013 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world by @mdo and @fat. + */ + +/*! normalize.css v2.1.0 | MIT License | git.io/normalize */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} + +audio, +canvas, +video { + display: inline-block; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +[hidden] { + display: none; +} + +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + margin: 0; +} + +a:focus { + outline: thin dotted; +} + +a:active, +a:hover { + outline: 0; +} + +h1 { + margin: 0.67em 0; + font-size: 2em; +} + +abbr[title] { + border-bottom: 1px dotted; +} + +b, +strong { + font-weight: bold; +} + +dfn { + font-style: italic; +} + +hr { + height: 0; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +mark { + color: #000; + background: #ff0; +} + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +pre { + white-space: pre-wrap; +} + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +small { + font-size: 80%; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + border: 0; +} + +svg:not(:root) { + overflow: hidden; +} + +figure { + margin: 0; +} + +fieldset { + padding: 0.35em 0.625em 0.75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} + +legend { + padding: 0; + border: 0; +} + +button, +input, +select, +textarea { + margin: 0; + font-family: inherit; + font-size: 100%; +} + +button, +input { + line-height: normal; +} + +button, +select { + text-transform: none; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +button[disabled], +html input[disabled] { + cursor: default; +} + +input[type="checkbox"], +input[type="radio"] { + padding: 0; + box-sizing: border-box; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 2cm .5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .table td, + .table th { + background-color: #fff !important; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} + +*, +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +html { + font-size: 62.5%; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.428571429; + color: #333333; + background-color: #ffffff; +} + +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input, +select[multiple], +textarea { + background-image: none; +} + +a { + color: #428bca; + text-decoration: none; +} + +a:hover, +a:focus { + color: #2a6496; + text-decoration: underline; +} + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +img { + vertical-align: middle; +} + +.img-responsive { + display: block; + height: auto; + max-width: 100%; +} + +.img-rounded { + border-radius: 6px; +} + +.img-thumbnail { + display: inline-block; + height: auto; + max-width: 100%; + padding: 4px; + line-height: 1.428571429; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +.img-circle { + border-radius: 50%; +} + +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eeeeee; +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0 0 0 0); + border: 0; +} + +p { + margin: 0 0 10px; +} + +.lead { + margin-bottom: 20px; + font-size: 16.099999999999998px; + font-weight: 200; + line-height: 1.4; +} + +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} + +small { + font-size: 85%; +} + +cite { + font-style: normal; +} + +.text-muted { + color: #999999; +} + +.text-primary { + color: #428bca; +} + +.text-warning { + color: #c09853; +} + +.text-danger { + color: #b94a48; +} + +.text-success { + color: #468847; +} + +.text-info { + color: #3a87ad; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 500; + line-height: 1.1; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} + +h1, +h2, +h3 { + margin-top: 20px; + margin-bottom: 10px; +} + +h4, +h5, +h6 { + margin-top: 10px; + margin-bottom: 10px; +} + +h1, +.h1 { + font-size: 36px; +} + +h2, +.h2 { + font-size: 30px; +} + +h3, +.h3 { + font-size: 24px; +} + +h4, +.h4 { + font-size: 18px; +} + +h5, +.h5 { + font-size: 14px; +} + +h6, +.h6 { + font-size: 12px; +} + +h1 small, +.h1 small { + font-size: 24px; +} + +h2 small, +.h2 small { + font-size: 18px; +} + +h3 small, +.h3 small, +h4 small, +.h4 small { + font-size: 14px; +} + +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eeeeee; +} + +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} + +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 1.428571429; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 0; +} + +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } + .dl-horizontal dd:before, + .dl-horizontal dd:after { + display: table; + content: " "; + } + .dl-horizontal dd:after { + clear: both; + } + .dl-horizontal dd:before, + .dl-horizontal dd:after { + display: table; + content: " "; + } + .dl-horizontal dd:after { + clear: both; + } +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote p:last-child { + margin-bottom: 0; +} + +blockquote small { + display: block; + line-height: 1.428571429; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 1.428571429; +} + +code, +pre { + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; +} + +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + white-space: nowrap; + background-color: #f9f2f4; + border-radius: 4px; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.428571429; + color: #333333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #cccccc; + border-radius: 4px; +} + +pre.prettyprint { + margin-bottom: 20px; +} + +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.container:before, +.container:after { + display: table; + content: " "; +} + +.container:after { + clear: both; +} + +.container:before, +.container:after { + display: table; + content: " "; +} + +.container:after { + clear: both; +} + +.row { + margin-right: -15px; + margin-left: -15px; +} + +.row:before, +.row:after { + display: table; + content: " "; +} + +.row:after { + clear: both; +} + +.row:before, +.row:after { + display: table; + content: " "; +} + +.row:after { + clear: both; +} + +.col-xs-1, +.col-xs-2, +.col-xs-3, +.col-xs-4, +.col-xs-5, +.col-xs-6, +.col-xs-7, +.col-xs-8, +.col-xs-9, +.col-xs-10, +.col-xs-11, +.col-xs-12, +.col-sm-1, +.col-sm-2, +.col-sm-3, +.col-sm-4, +.col-sm-5, +.col-sm-6, +.col-sm-7, +.col-sm-8, +.col-sm-9, +.col-sm-10, +.col-sm-11, +.col-sm-12, +.col-md-1, +.col-md-2, +.col-md-3, +.col-md-4, +.col-md-5, +.col-md-6, +.col-md-7, +.col-md-8, +.col-md-9, +.col-md-10, +.col-md-11, +.col-md-12, +.col-lg-1, +.col-lg-2, +.col-lg-3, +.col-lg-4, +.col-lg-5, +.col-lg-6, +.col-lg-7, +.col-lg-8, +.col-lg-9, +.col-lg-10, +.col-lg-11, +.col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} + +.col-xs-1, +.col-xs-2, +.col-xs-3, +.col-xs-4, +.col-xs-5, +.col-xs-6, +.col-xs-7, +.col-xs-8, +.col-xs-9, +.col-xs-10, +.col-xs-11 { + float: left; +} + +.col-xs-1 { + width: 8.333333333333332%; +} + +.col-xs-2 { + width: 16.666666666666664%; +} + +.col-xs-3 { + width: 25%; +} + +.col-xs-4 { + width: 33.33333333333333%; +} + +.col-xs-5 { + width: 41.66666666666667%; +} + +.col-xs-6 { + width: 50%; +} + +.col-xs-7 { + width: 58.333333333333336%; +} + +.col-xs-8 { + width: 66.66666666666666%; +} + +.col-xs-9 { + width: 75%; +} + +.col-xs-10 { + width: 83.33333333333334%; +} + +.col-xs-11 { + width: 91.66666666666666%; +} + +.col-xs-12 { + width: 100%; +} + +@media (min-width: 768px) { + .container { + max-width: 750px; + } + .col-sm-1, + .col-sm-2, + .col-sm-3, + .col-sm-4, + .col-sm-5, + .col-sm-6, + .col-sm-7, + .col-sm-8, + .col-sm-9, + .col-sm-10, + .col-sm-11 { + float: left; + } + .col-sm-1 { + width: 8.333333333333332%; + } + .col-sm-2 { + width: 16.666666666666664%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-4 { + width: 33.33333333333333%; + } + .col-sm-5 { + width: 41.66666666666667%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-7 { + width: 58.333333333333336%; + } + .col-sm-8 { + width: 66.66666666666666%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-10 { + width: 83.33333333333334%; + } + .col-sm-11 { + width: 91.66666666666666%; + } + .col-sm-12 { + width: 100%; + } + .col-sm-push-1 { + left: 8.333333333333332%; + } + .col-sm-push-2 { + left: 16.666666666666664%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-4 { + left: 33.33333333333333%; + } + .col-sm-push-5 { + left: 41.66666666666667%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-7 { + left: 58.333333333333336%; + } + .col-sm-push-8 { + left: 66.66666666666666%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-10 { + left: 83.33333333333334%; + } + .col-sm-push-11 { + left: 91.66666666666666%; + } + .col-sm-pull-1 { + right: 8.333333333333332%; + } + .col-sm-pull-2 { + right: 16.666666666666664%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-4 { + right: 33.33333333333333%; + } + .col-sm-pull-5 { + right: 41.66666666666667%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-7 { + right: 58.333333333333336%; + } + .col-sm-pull-8 { + right: 66.66666666666666%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-10 { + right: 83.33333333333334%; + } + .col-sm-pull-11 { + right: 91.66666666666666%; + } + .col-sm-offset-1 { + margin-left: 8.333333333333332%; + } + .col-sm-offset-2 { + margin-left: 16.666666666666664%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-4 { + margin-left: 33.33333333333333%; + } + .col-sm-offset-5 { + margin-left: 41.66666666666667%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-7 { + margin-left: 58.333333333333336%; + } + .col-sm-offset-8 { + margin-left: 66.66666666666666%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-10 { + margin-left: 83.33333333333334%; + } + .col-sm-offset-11 { + margin-left: 91.66666666666666%; + } +} + +@media (min-width: 992px) { + .container { + max-width: 970px; + } + .col-md-1, + .col-md-2, + .col-md-3, + .col-md-4, + .col-md-5, + .col-md-6, + .col-md-7, + .col-md-8, + .col-md-9, + .col-md-10, + .col-md-11 { + float: left; + } + .col-md-1 { + width: 8.333333333333332%; + } + .col-md-2 { + width: 16.666666666666664%; + } + .col-md-3 { + width: 25%; + } + .col-md-4 { + width: 33.33333333333333%; + } + .col-md-5 { + width: 41.66666666666667%; + } + .col-md-6 { + width: 50%; + } + .col-md-7 { + width: 58.333333333333336%; + } + .col-md-8 { + width: 66.66666666666666%; + } + .col-md-9 { + width: 75%; + } + .col-md-10 { + width: 83.33333333333334%; + } + .col-md-11 { + width: 91.66666666666666%; + } + .col-md-12 { + width: 100%; + } + .col-md-push-0 { + left: auto; + } + .col-md-push-1 { + left: 8.333333333333332%; + } + .col-md-push-2 { + left: 16.666666666666664%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-4 { + left: 33.33333333333333%; + } + .col-md-push-5 { + left: 41.66666666666667%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-7 { + left: 58.333333333333336%; + } + .col-md-push-8 { + left: 66.66666666666666%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-10 { + left: 83.33333333333334%; + } + .col-md-push-11 { + left: 91.66666666666666%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-pull-1 { + right: 8.333333333333332%; + } + .col-md-pull-2 { + right: 16.666666666666664%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-4 { + right: 33.33333333333333%; + } + .col-md-pull-5 { + right: 41.66666666666667%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-7 { + right: 58.333333333333336%; + } + .col-md-pull-8 { + right: 66.66666666666666%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-10 { + right: 83.33333333333334%; + } + .col-md-pull-11 { + right: 91.66666666666666%; + } + .col-md-offset-0 { + margin-left: 0; + } + .col-md-offset-1 { + margin-left: 8.333333333333332%; + } + .col-md-offset-2 { + margin-left: 16.666666666666664%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-4 { + margin-left: 33.33333333333333%; + } + .col-md-offset-5 { + margin-left: 41.66666666666667%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-7 { + margin-left: 58.333333333333336%; + } + .col-md-offset-8 { + margin-left: 66.66666666666666%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-10 { + margin-left: 83.33333333333334%; + } + .col-md-offset-11 { + margin-left: 91.66666666666666%; + } +} + +@media (min-width: 1200px) { + .container { + max-width: 1170px; + } + .col-lg-1, + .col-lg-2, + .col-lg-3, + .col-lg-4, + .col-lg-5, + .col-lg-6, + .col-lg-7, + .col-lg-8, + .col-lg-9, + .col-lg-10, + .col-lg-11 { + float: left; + } + .col-lg-1 { + width: 8.333333333333332%; + } + .col-lg-2 { + width: 16.666666666666664%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-4 { + width: 33.33333333333333%; + } + .col-lg-5 { + width: 41.66666666666667%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-7 { + width: 58.333333333333336%; + } + .col-lg-8 { + width: 66.66666666666666%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-10 { + width: 83.33333333333334%; + } + .col-lg-11 { + width: 91.66666666666666%; + } + .col-lg-12 { + width: 100%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-push-1 { + left: 8.333333333333332%; + } + .col-lg-push-2 { + left: 16.666666666666664%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-4 { + left: 33.33333333333333%; + } + .col-lg-push-5 { + left: 41.66666666666667%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-7 { + left: 58.333333333333336%; + } + .col-lg-push-8 { + left: 66.66666666666666%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-10 { + left: 83.33333333333334%; + } + .col-lg-push-11 { + left: 91.66666666666666%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-pull-1 { + right: 8.333333333333332%; + } + .col-lg-pull-2 { + right: 16.666666666666664%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-4 { + right: 33.33333333333333%; + } + .col-lg-pull-5 { + right: 41.66666666666667%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-7 { + right: 58.333333333333336%; + } + .col-lg-pull-8 { + right: 66.66666666666666%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-10 { + right: 83.33333333333334%; + } + .col-lg-pull-11 { + right: 91.66666666666666%; + } + .col-lg-offset-0 { + margin-left: 0; + } + .col-lg-offset-1 { + margin-left: 8.333333333333332%; + } + .col-lg-offset-2 { + margin-left: 16.666666666666664%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-4 { + margin-left: 33.33333333333333%; + } + .col-lg-offset-5 { + margin-left: 41.66666666666667%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-7 { + margin-left: 58.333333333333336%; + } + .col-lg-offset-8 { + margin-left: 66.66666666666666%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-10 { + margin-left: 83.33333333333334%; + } + .col-lg-offset-11 { + margin-left: 91.66666666666666%; + } +} + +table { + max-width: 100%; + background-color: transparent; +} + +th { + text-align: left; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table thead > tr > th, +.table tbody > tr > th, +.table tfoot > tr > th, +.table thead > tr > td, +.table tbody > tr > td, +.table tfoot > tr > td { + padding: 8px; + line-height: 1.428571429; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #dddddd; +} + +.table caption + thead tr:first-child th, +.table colgroup + thead tr:first-child th, +.table thead:first-child tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child td { + border-top: 0; +} + +.table tbody + tbody { + border-top: 2px solid #dddddd; +} + +.table .table { + background-color: #ffffff; +} + +.table-condensed thead > tr > th, +.table-condensed tbody > tr > th, +.table-condensed tfoot > tr > th, +.table-condensed thead > tr > td, +.table-condensed tbody > tr > td, +.table-condensed tfoot > tr > td { + padding: 5px; +} + +.table-bordered { + border: 1px solid #dddddd; +} + +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #dddddd; +} + +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} + +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover > tbody > tr:hover > td, +.table-hover > tbody > tr:hover > th { + background-color: #f5f5f5; +} + +table col[class*="col-"] { + display: table-column; + float: none; +} + +table td[class*="col-"], +table th[class*="col-"] { + display: table-cell; + float: none; +} + +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} + +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td { + background-color: #d0e9c6; + border-color: #c9e2b3; +} + +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; + border-color: #eed3d7; +} + +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td { + background-color: #ebcccc; + border-color: #e6c1c7; +} + +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; + border-color: #fbeed5; +} + +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td { + background-color: #faf2cc; + border-color: #f8e5be; +} + +@media (max-width: 768px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: scroll; + overflow-y: hidden; + border: 1px solid #dddddd; + } + .table-responsive > .table { + margin-bottom: 0; + background-color: #fff; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > thead > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > thead > tr:last-child > td, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +label { + display: inline-block; + margin-bottom: 5px; + font-weight: bold; +} + +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + /* IE8-9 */ + + line-height: normal; +} + +input[type="file"] { + display: block; +} + +select[multiple], +select[size] { + height: auto; +} + +select optgroup { + font-family: inherit; + font-size: inherit; + font-style: inherit; +} + +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +input[type="number"]::-webkit-outer-spin-button, +input[type="number"]::-webkit-inner-spin-button { + height: auto; +} + +.form-control:-moz-placeholder { + color: #999999; +} + +.form-control::-moz-placeholder { + color: #999999; +} + +.form-control:-ms-input-placeholder { + color: #999999; +} + +.form-control::-webkit-input-placeholder { + color: #999999; +} + +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.428571429; + color: #555555; + vertical-align: middle; + background-color: #ffffff; + border: 1px solid #cccccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} + +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eeeeee; +} + +textarea.form-control { + height: auto; +} + +.form-group { + margin-bottom: 15px; +} + +.radio, +.checkbox { + display: block; + min-height: 20px; + padding-left: 20px; + margin-top: 10px; + margin-bottom: 10px; + vertical-align: middle; +} + +.radio label, +.checkbox label { + display: inline; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} + +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + float: left; + margin-left: -20px; +} + +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} + +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} + +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled], +.radio[disabled], +.radio-inline[disabled], +.checkbox[disabled], +.checkbox-inline[disabled], +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"], +fieldset[disabled] .radio, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} + +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +select.input-sm { + height: 30px; + line-height: 30px; +} + +textarea.input-sm { + height: auto; +} + +.input-lg { + height: 45px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +select.input-lg { + height: 45px; + line-height: 45px; +} + +textarea.input-lg { + height: auto; +} + +.has-warning .help-block, +.has-warning .control-label { + color: #c09853; +} + +.has-warning .form-control { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.has-warning .form-control:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.has-warning .input-group-addon { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.has-error .help-block, +.has-error .control-label { + color: #b94a48; +} + +.has-error .form-control { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.has-error .form-control:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.has-error .input-group-addon { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.has-success .help-block, +.has-success .control-label { + color: #468847; +} + +.has-success .form-control { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.has-success .form-control:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.has-success .input-group-addon { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.form-control-static { + padding-top: 7px; + margin-bottom: 0; +} + +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} + +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } +} + +.form-horizontal .control-label, +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} + +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} + +.form-horizontal .form-group:before, +.form-horizontal .form-group:after { + display: table; + content: " "; +} + +.form-horizontal .form-group:after { + clear: both; +} + +.form-horizontal .form-group:before, +.form-horizontal .form-group:after { + display: table; + content: " "; +} + +.form-horizontal .form-group:after { + clear: both; +} + +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + } +} + +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.428571429; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + border: 1px solid transparent; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; +} + +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} + +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + pointer-events: none; + cursor: not-allowed; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} + +.btn-default { + color: #333333; + background-color: #ffffff; + border-color: #cccccc; +} + +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + color: #333333; + background-color: #ebebeb; + border-color: #adadad; +} + +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + background-image: none; +} + +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #ffffff; + border-color: #cccccc; +} + +.btn-primary { + color: #ffffff; + background-color: #428bca; + border-color: #357ebd; +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + color: #ffffff; + background-color: #3276b1; + border-color: #285e8e; +} + +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + background-image: none; +} + +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #428bca; + border-color: #357ebd; +} + +.btn-warning { + color: #ffffff; + background-color: #f0ad4e; + border-color: #eea236; +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + color: #ffffff; + background-color: #ed9c28; + border-color: #d58512; +} + +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + background-image: none; +} + +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} + +.btn-danger { + color: #ffffff; + background-color: #d9534f; + border-color: #d43f3a; +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + color: #ffffff; + background-color: #d2322d; + border-color: #ac2925; +} + +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + background-image: none; +} + +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} + +.btn-success { + color: #ffffff; + background-color: #5cb85c; + border-color: #4cae4c; +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + color: #ffffff; + background-color: #47a447; + border-color: #398439; +} + +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + background-image: none; +} + +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} + +.btn-info { + color: #ffffff; + background-color: #5bc0de; + border-color: #46b8da; +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + color: #ffffff; + background-color: #39b3d7; + border-color: #269abc; +} + +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + background-image: none; +} + +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} + +.btn-link { + font-weight: normal; + color: #428bca; + cursor: pointer; + border-radius: 0; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} + +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} + +.btn-link:hover, +.btn-link:focus { + color: #2a6496; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #999999; + text-decoration: none; +} + +.btn-lg { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +.btn-sm, +.btn-xs { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-xs { + padding: 1px 5px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + display: none; +} + +.collapse.in { + display: block; +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); +} + +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + -webkit-font-smoothing: antialiased; + font-style: normal; + font-weight: normal; + line-height: 1; +} + +.glyphicon-asterisk:before { + content: "\2a"; +} + +.glyphicon-plus:before { + content: "\2b"; +} + +.glyphicon-euro:before { + content: "\20ac"; +} + +.glyphicon-minus:before { + content: "\2212"; +} + +.glyphicon-cloud:before { + content: "\2601"; +} + +.glyphicon-envelope:before { + content: "\2709"; +} + +.glyphicon-pencil:before { + content: "\270f"; +} + +.glyphicon-glass:before { + content: "\e001"; +} + +.glyphicon-music:before { + content: "\e002"; +} + +.glyphicon-search:before { + content: "\e003"; +} + +.glyphicon-heart:before { + content: "\e005"; +} + +.glyphicon-star:before { + content: "\e006"; +} + +.glyphicon-star-empty:before { + content: "\e007"; +} + +.glyphicon-user:before { + content: "\e008"; +} + +.glyphicon-film:before { + content: "\e009"; +} + +.glyphicon-th-large:before { + content: "\e010"; +} + +.glyphicon-th:before { + content: "\e011"; +} + +.glyphicon-th-list:before { + content: "\e012"; +} + +.glyphicon-ok:before { + content: "\e013"; +} + +.glyphicon-remove:before { + content: "\e014"; +} + +.glyphicon-zoom-in:before { + content: "\e015"; +} + +.glyphicon-zoom-out:before { + content: "\e016"; +} + +.glyphicon-off:before { + content: "\e017"; +} + +.glyphicon-signal:before { + content: "\e018"; +} + +.glyphicon-cog:before { + content: "\e019"; +} + +.glyphicon-trash:before { + content: "\e020"; +} + +.glyphicon-home:before { + content: "\e021"; +} + +.glyphicon-file:before { + content: "\e022"; +} + +.glyphicon-time:before { + content: "\e023"; +} + +.glyphicon-road:before { + content: "\e024"; +} + +.glyphicon-download-alt:before { + content: "\e025"; +} + +.glyphicon-download:before { + content: "\e026"; +} + +.glyphicon-upload:before { + content: "\e027"; +} + +.glyphicon-inbox:before { + content: "\e028"; +} + +.glyphicon-play-circle:before { + content: "\e029"; +} + +.glyphicon-repeat:before { + content: "\e030"; +} + +.glyphicon-refresh:before { + content: "\e031"; +} + +.glyphicon-list-alt:before { + content: "\e032"; +} + +.glyphicon-flag:before { + content: "\e034"; +} + +.glyphicon-headphones:before { + content: "\e035"; +} + +.glyphicon-volume-off:before { + content: "\e036"; +} + +.glyphicon-volume-down:before { + content: "\e037"; +} + +.glyphicon-volume-up:before { + content: "\e038"; +} + +.glyphicon-qrcode:before { + content: "\e039"; +} + +.glyphicon-barcode:before { + content: "\e040"; +} + +.glyphicon-tag:before { + content: "\e041"; +} + +.glyphicon-tags:before { + content: "\e042"; +} + +.glyphicon-book:before { + content: "\e043"; +} + +.glyphicon-print:before { + content: "\e045"; +} + +.glyphicon-font:before { + content: "\e047"; +} + +.glyphicon-bold:before { + content: "\e048"; +} + +.glyphicon-italic:before { + content: "\e049"; +} + +.glyphicon-text-height:before { + content: "\e050"; +} + +.glyphicon-text-width:before { + content: "\e051"; +} + +.glyphicon-align-left:before { + content: "\e052"; +} + +.glyphicon-align-center:before { + content: "\e053"; +} + +.glyphicon-align-right:before { + content: "\e054"; +} + +.glyphicon-align-justify:before { + content: "\e055"; +} + +.glyphicon-list:before { + content: "\e056"; +} + +.glyphicon-indent-left:before { + content: "\e057"; +} + +.glyphicon-indent-right:before { + content: "\e058"; +} + +.glyphicon-facetime-video:before { + content: "\e059"; +} + +.glyphicon-picture:before { + content: "\e060"; +} + +.glyphicon-map-marker:before { + content: "\e062"; +} + +.glyphicon-adjust:before { + content: "\e063"; +} + +.glyphicon-tint:before { + content: "\e064"; +} + +.glyphicon-edit:before { + content: "\e065"; +} + +.glyphicon-share:before { + content: "\e066"; +} + +.glyphicon-check:before { + content: "\e067"; +} + +.glyphicon-move:before { + content: "\e068"; +} + +.glyphicon-step-backward:before { + content: "\e069"; +} + +.glyphicon-fast-backward:before { + content: "\e070"; +} + +.glyphicon-backward:before { + content: "\e071"; +} + +.glyphicon-play:before { + content: "\e072"; +} + +.glyphicon-pause:before { + content: "\e073"; +} + +.glyphicon-stop:before { + content: "\e074"; +} + +.glyphicon-forward:before { + content: "\e075"; +} + +.glyphicon-fast-forward:before { + content: "\e076"; +} + +.glyphicon-step-forward:before { + content: "\e077"; +} + +.glyphicon-eject:before { + content: "\e078"; +} + +.glyphicon-chevron-left:before { + content: "\e079"; +} + +.glyphicon-chevron-right:before { + content: "\e080"; +} + +.glyphicon-plus-sign:before { + content: "\e081"; +} + +.glyphicon-minus-sign:before { + content: "\e082"; +} + +.glyphicon-remove-sign:before { + content: "\e083"; +} + +.glyphicon-ok-sign:before { + content: "\e084"; +} + +.glyphicon-question-sign:before { + content: "\e085"; +} + +.glyphicon-info-sign:before { + content: "\e086"; +} + +.glyphicon-screenshot:before { + content: "\e087"; +} + +.glyphicon-remove-circle:before { + content: "\e088"; +} + +.glyphicon-ok-circle:before { + content: "\e089"; +} + +.glyphicon-ban-circle:before { + content: "\e090"; +} + +.glyphicon-arrow-left:before { + content: "\e091"; +} + +.glyphicon-arrow-right:before { + content: "\e092"; +} + +.glyphicon-arrow-up:before { + content: "\e093"; +} + +.glyphicon-arrow-down:before { + content: "\e094"; +} + +.glyphicon-share-alt:before { + content: "\e095"; +} + +.glyphicon-resize-full:before { + content: "\e096"; +} + +.glyphicon-resize-small:before { + content: "\e097"; +} + +.glyphicon-exclamation-sign:before { + content: "\e101"; +} + +.glyphicon-gift:before { + content: "\e102"; +} + +.glyphicon-leaf:before { + content: "\e103"; +} + +.glyphicon-eye-open:before { + content: "\e105"; +} + +.glyphicon-eye-close:before { + content: "\e106"; +} + +.glyphicon-warning-sign:before { + content: "\e107"; +} + +.glyphicon-plane:before { + content: "\e108"; +} + +.glyphicon-random:before { + content: "\e110"; +} + +.glyphicon-comment:before { + content: "\e111"; +} + +.glyphicon-magnet:before { + content: "\e112"; +} + +.glyphicon-chevron-up:before { + content: "\e113"; +} + +.glyphicon-chevron-down:before { + content: "\e114"; +} + +.glyphicon-retweet:before { + content: "\e115"; +} + +.glyphicon-shopping-cart:before { + content: "\e116"; +} + +.glyphicon-folder-close:before { + content: "\e117"; +} + +.glyphicon-folder-open:before { + content: "\e118"; +} + +.glyphicon-resize-vertical:before { + content: "\e119"; +} + +.glyphicon-resize-horizontal:before { + content: "\e120"; +} + +.glyphicon-hdd:before { + content: "\e121"; +} + +.glyphicon-bullhorn:before { + content: "\e122"; +} + +.glyphicon-certificate:before { + content: "\e124"; +} + +.glyphicon-thumbs-up:before { + content: "\e125"; +} + +.glyphicon-thumbs-down:before { + content: "\e126"; +} + +.glyphicon-hand-right:before { + content: "\e127"; +} + +.glyphicon-hand-left:before { + content: "\e128"; +} + +.glyphicon-hand-up:before { + content: "\e129"; +} + +.glyphicon-hand-down:before { + content: "\e130"; +} + +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} + +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} + +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} + +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} + +.glyphicon-globe:before { + content: "\e135"; +} + +.glyphicon-tasks:before { + content: "\e137"; +} + +.glyphicon-filter:before { + content: "\e138"; +} + +.glyphicon-fullscreen:before { + content: "\e140"; +} + +.glyphicon-dashboard:before { + content: "\e141"; +} + +.glyphicon-heart-empty:before { + content: "\e143"; +} + +.glyphicon-link:before { + content: "\e144"; +} + +.glyphicon-phone:before { + content: "\e145"; +} + +.glyphicon-usd:before { + content: "\e148"; +} + +.glyphicon-gbp:before { + content: "\e149"; +} + +.glyphicon-sort:before { + content: "\e150"; +} + +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} + +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} + +.glyphicon-sort-by-order:before { + content: "\e153"; +} + +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} + +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} + +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} + +.glyphicon-unchecked:before { + content: "\e157"; +} + +.glyphicon-expand:before { + content: "\e158"; +} + +.glyphicon-collapse-down:before { + content: "\e159"; +} + +.glyphicon-collapse-up:before { + content: "\e160"; +} + +.glyphicon-log-in:before { + content: "\e161"; +} + +.glyphicon-flash:before { + content: "\e162"; +} + +.glyphicon-log-out:before { + content: "\e163"; +} + +.glyphicon-new-window:before { + content: "\e164"; +} + +.glyphicon-record:before { + content: "\e165"; +} + +.glyphicon-save:before { + content: "\e166"; +} + +.glyphicon-open:before { + content: "\e167"; +} + +.glyphicon-saved:before { + content: "\e168"; +} + +.glyphicon-import:before { + content: "\e169"; +} + +.glyphicon-export:before { + content: "\e170"; +} + +.glyphicon-send:before { + content: "\e171"; +} + +.glyphicon-floppy-disk:before { + content: "\e172"; +} + +.glyphicon-floppy-saved:before { + content: "\e173"; +} + +.glyphicon-floppy-remove:before { + content: "\e174"; +} + +.glyphicon-floppy-save:before { + content: "\e175"; +} + +.glyphicon-floppy-open:before { + content: "\e176"; +} + +.glyphicon-credit-card:before { + content: "\e177"; +} + +.glyphicon-transfer:before { + content: "\e178"; +} + +.glyphicon-cutlery:before { + content: "\e179"; +} + +.glyphicon-header:before { + content: "\e180"; +} + +.glyphicon-compressed:before { + content: "\e181"; +} + +.glyphicon-earphone:before { + content: "\e182"; +} + +.glyphicon-phone-alt:before { + content: "\e183"; +} + +.glyphicon-tower:before { + content: "\e184"; +} + +.glyphicon-stats:before { + content: "\e185"; +} + +.glyphicon-sd-video:before { + content: "\e186"; +} + +.glyphicon-hd-video:before { + content: "\e187"; +} + +.glyphicon-subtitles:before { + content: "\e188"; +} + +.glyphicon-sound-stereo:before { + content: "\e189"; +} + +.glyphicon-sound-dolby:before { + content: "\e190"; +} + +.glyphicon-sound-5-1:before { + content: "\e191"; +} + +.glyphicon-sound-6-1:before { + content: "\e192"; +} + +.glyphicon-sound-7-1:before { + content: "\e193"; +} + +.glyphicon-copyright-mark:before { + content: "\e194"; +} + +.glyphicon-registration-mark:before { + content: "\e195"; +} + +.glyphicon-cloud-download:before { + content: "\e197"; +} + +.glyphicon-cloud-upload:before { + content: "\e198"; +} + +.glyphicon-tree-conifer:before { + content: "\e199"; +} + +.glyphicon-tree-deciduous:before { + content: "\e200"; +} + +.glyphicon-briefcase:before { + content: "\1f4bc"; +} + +.glyphicon-calendar:before { + content: "\1f4c5"; +} + +.glyphicon-pushpin:before { + content: "\1f4cc"; +} + +.glyphicon-paperclip:before { + content: "\1f4ce"; +} + +.glyphicon-camera:before { + content: "\1f4f7"; +} + +.glyphicon-lock:before { + content: "\1f512"; +} + +.glyphicon-bell:before { + content: "\1f514"; +} + +.glyphicon-bookmark:before { + content: "\1f516"; +} + +.glyphicon-fire:before { + content: "\1f525"; +} + +.glyphicon-wrench:before { + content: "\1f527"; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-bottom: 0 dotted; + border-left: 4px solid transparent; + content: ""; +} + +.dropdown { + position: relative; +} + +.dropdown-toggle:focus { + outline: 0; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + list-style: none; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} + +.dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} + +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.428571429; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #428bca; +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #428bca; + outline: 0; +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open > .dropdown-menu { + display: block; +} + +.open > a { + outline: 0; +} + +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.428571429; + color: #999999; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0 dotted; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } +} + +.btn-default .caret { + border-top-color: #333333; +} + +.btn-primary .caret, +.btn-success .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret { + border-top-color: #fff; +} + +.dropup .btn-default .caret { + border-bottom-color: #333333; +} + +.dropup .btn-primary .caret, +.dropup .btn-success .caret, +.dropup .btn-warning .caret, +.dropup .btn-danger .caret, +.dropup .btn-info .caret { + border-bottom-color: #fff; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} + +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} + +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} + +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus { + outline: none; +} + +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} + +.btn-toolbar:before, +.btn-toolbar:after { + display: table; + content: " "; +} + +.btn-toolbar:after { + clear: both; +} + +.btn-toolbar:before, +.btn-toolbar:after { + display: table; + content: " "; +} + +.btn-toolbar:after { + clear: both; +} + +.btn-toolbar .btn-group { + float: left; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group, +.btn-toolbar > .btn-group + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} + +.btn-group > .btn:first-child { + margin-left: 0; +} + +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.btn-group > .btn-group { + float: left; +} + +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} + +.btn-group > .btn-group:first-child > .btn:last-child, +.btn-group > .btn-group:first-child > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.btn-group > .btn-group:last-child > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group-xs > .btn { + padding: 5px 10px; + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} + +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} + +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} + +.btn .caret { + margin-left: 0; +} + +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} + +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} + +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group { + display: block; + float: none; + width: 100%; + max-width: 100%; +} + +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after { + display: table; + content: " "; +} + +.btn-group-vertical > .btn-group:after { + clear: both; +} + +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after { + display: table; + content: " "; +} + +.btn-group-vertical > .btn-group:after { + clear: both; +} + +.btn-group-vertical > .btn-group > .btn { + float: none; +} + +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} + +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-right-radius: 0; + border-bottom-left-radius: 4px; + border-top-left-radius: 0; +} + +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} + +.btn-group-vertical > .btn-group:first-child > .btn:last-child, +.btn-group-vertical > .btn-group:first-child > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.btn-group-vertical > .btn-group:last-child > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.btn-group-justified { + display: table; + width: 100%; + border-collapse: separate; + table-layout: fixed; +} + +.btn-group-justified .btn { + display: table-cell; + float: none; + width: 1%; +} + +[data-toggle="buttons"] > .btn > input[type="radio"], +[data-toggle="buttons"] > .btn > input[type="checkbox"] { + display: none; +} + +.input-group { + position: relative; + display: table; + border-collapse: separate; +} + +.input-group.col { + float: none; + padding-right: 0; + padding-left: 0; +} + +.input-group .form-control { + width: 100%; + margin-bottom: 0; +} + +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 45px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 45px; + line-height: 45px; +} + +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn { + height: auto; +} + +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} + +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn { + height: auto; +} + +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} + +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} + +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} + +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + text-align: center; + background-color: #eeeeee; + border: 1px solid #cccccc; + border-radius: 4px; +} + +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} + +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} + +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} + +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group-addon:first-child { + border-right: 0; +} + +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.input-group-addon:last-child { + border-left: 0; +} + +.input-group-btn { + position: relative; + white-space: nowrap; +} + +.input-group-btn > .btn { + position: relative; +} + +.input-group-btn > .btn + .btn { + margin-left: -4px; +} + +.input-group-btn > .btn:hover, +.input-group-btn > .btn:active { + z-index: 2; +} + +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav:before, +.nav:after { + display: table; + content: " "; +} + +.nav:after { + clear: both; +} + +.nav:before, +.nav:after { + display: table; + content: " "; +} + +.nav:after { + clear: both; +} + +.nav > li { + position: relative; + display: block; +} + +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.nav > li.disabled > a { + color: #999999; +} + +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #999999; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} + +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eeeeee; + border-color: #428bca; +} + +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} + +.nav > li > a > img { + max-width: none; +} + +.nav-tabs { + border-bottom: 1px solid #dddddd; +} + +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} + +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.428571429; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #dddddd; + border-bottom-color: transparent; +} + +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} + +.nav-tabs.nav-justified > li { + float: none; +} + +.nav-tabs.nav-justified > li > a { + text-align: center; +} + +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } +} + +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-bottom: 1px solid #dddddd; +} + +.nav-tabs.nav-justified > .active > a { + border-bottom-color: #ffffff; +} + +.nav-pills > li { + float: left; +} + +.nav-pills > li > a { + border-radius: 5px; +} + +.nav-pills > li + li { + margin-left: 2px; +} + +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #ffffff; + background-color: #428bca; +} + +.nav-stacked > li { + float: none; +} + +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} + +.nav-justified { + width: 100%; +} + +.nav-justified > li { + float: none; +} + +.nav-justified > li > a { + text-align: center; +} + +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } +} + +.nav-tabs-justified { + border-bottom: 0; +} + +.nav-tabs-justified > li > a { + margin-right: 0; + border-bottom: 1px solid #dddddd; +} + +.nav-tabs-justified > .active > a { + border-bottom-color: #ffffff; +} + +.tabbable:before, +.tabbable:after { + display: table; + content: " "; +} + +.tabbable:after { + clear: both; +} + +.tabbable:before, +.tabbable:after { + display: table; + content: " "; +} + +.tabbable:after { + clear: both; +} + +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} + +.tab-content > .active, +.pill-content > .active { + display: block; +} + +.nav .caret { + border-top-color: #428bca; + border-bottom-color: #428bca; +} + +.nav a:hover .caret { + border-top-color: #2a6496; + border-bottom-color: #2a6496; +} + +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.navbar { + position: relative; + z-index: 1000; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} + +.navbar:before, +.navbar:after { + display: table; + content: " "; +} + +.navbar:after { + clear: both; +} + +.navbar:before, +.navbar:after { + display: table; + content: " "; +} + +.navbar:after { + clear: both; +} + +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} + +.navbar-header:before, +.navbar-header:after { + display: table; + content: " "; +} + +.navbar-header:after { + clear: both; +} + +.navbar-header:before, +.navbar-header:after { + display: table; + content: " "; +} + +.navbar-header:after { + clear: both; +} + +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} + +.navbar-collapse { + max-height: 340px; + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} + +.navbar-collapse:before, +.navbar-collapse:after { + display: table; + content: " "; +} + +.navbar-collapse:after { + clear: both; +} + +.navbar-collapse:before, +.navbar-collapse:after { + display: table; + content: " "; +} + +.navbar-collapse:after { + clear: both; +} + +.navbar-collapse.in { + overflow-y: auto; +} + +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-collapse .navbar-nav.navbar-left:first-child { + margin-left: -15px; + } + .navbar-collapse .navbar-nav.navbar-right:last-child { + margin-right: -15px; + } + .navbar-collapse .navbar-text:last-child { + margin-right: 0; + } +} + +.container > .navbar-header, +.container > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} + +@media (min-width: 768px) { + .container > .navbar-header, + .container > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} + +.navbar-static-top { + border-width: 0 0 1px; +} + +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + border-width: 0 0 1px; +} + +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} + +.navbar-fixed-top { + top: 0; + z-index: 1030; +} + +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; +} + +.navbar-brand { + float: left; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} + +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} + +@media (min-width: 768px) { + .navbar > .container .navbar-brand { + margin-left: -15px; + } +} + +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + border: 1px solid transparent; + border-radius: 4px; +} + +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} + +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} + +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} + +.navbar-nav { + margin: 7.5px -15px; +} + +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} + +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} + +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} + +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + } +} + +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); +} + +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } +} + +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } +} + +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} + +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.navbar-nav.pull-right > li > .dropdown-menu, +.navbar-nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} + +.navbar-text { + float: left; + margin-top: 15px; + margin-bottom: 15px; +} + +@media (min-width: 768px) { + .navbar-text { + margin-right: 15px; + margin-left: 15px; + } +} + +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} + +.navbar-default .navbar-brand { + color: #777777; +} + +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} + +.navbar-default .navbar-text { + color: #777777; +} + +.navbar-default .navbar-nav > li > a { + color: #777777; +} + +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333333; + background-color: transparent; +} + +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555555; + background-color: #e7e7e7; +} + +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #cccccc; + background-color: transparent; +} + +.navbar-default .navbar-toggle { + border-color: #dddddd; +} + +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #dddddd; +} + +.navbar-default .navbar-toggle .icon-bar { + background-color: #cccccc; +} + +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e6e6e6; +} + +.navbar-default .navbar-nav > .dropdown > a:hover .caret, +.navbar-default .navbar-nav > .dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555555; + background-color: #e7e7e7; +} + +.navbar-default .navbar-nav > .open > a .caret, +.navbar-default .navbar-nav > .open > a:hover .caret, +.navbar-default .navbar-nav > .open > a:focus .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar-default .navbar-nav > .dropdown > a .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #cccccc; + background-color: transparent; + } +} + +.navbar-default .navbar-link { + color: #777777; +} + +.navbar-default .navbar-link:hover { + color: #333333; +} + +.navbar-inverse { + background-color: #222222; + border-color: #080808; +} + +.navbar-inverse .navbar-brand { + color: #999999; +} + +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .navbar-nav > li > a { + color: #999999; +} + +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #ffffff; + background-color: #080808; +} + +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444444; + background-color: transparent; +} + +.navbar-inverse .navbar-toggle { + border-color: #333333; +} + +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333333; +} + +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #ffffff; +} + +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} + +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #ffffff; + background-color: #080808; +} + +.navbar-inverse .navbar-nav > .dropdown > a:hover .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-nav > .dropdown > a .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .navbar-nav > .open > a .caret, +.navbar-inverse .navbar-nav > .open > a:hover .caret, +.navbar-inverse .navbar-nav > .open > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #999999; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #ffffff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #ffffff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444444; + background-color: transparent; + } +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover { + color: #ffffff; +} + +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} + +.breadcrumb > li { + display: inline-block; +} + +.breadcrumb > li + li:before { + padding: 0 5px; + color: #cccccc; + content: "/\00a0"; +} + +.breadcrumb > .active { + color: #999999; +} + +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} + +.pagination > li { + display: inline; +} + +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.428571429; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; +} + +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} + +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + background-color: #eeeeee; +} + +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #ffffff; + cursor: default; + background-color: #428bca; + border-color: #428bca; +} + +.pagination > .disabled > span, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #999999; + cursor: not-allowed; + background-color: #ffffff; + border-color: #dddddd; +} + +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; +} + +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-bottom-left-radius: 6px; + border-top-left-radius: 6px; +} + +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; +} + +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} + +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} + +.pager:before, +.pager:after { + display: table; + content: " "; +} + +.pager:after { + clear: both; +} + +.pager:before, +.pager:after { + display: table; + content: " "; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 15px; +} + +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.pager .next > a, +.pager .next > span { + float: right; +} + +.pager .previous > a, +.pager .previous > span { + float: left; +} + +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + cursor: not-allowed; + background-color: #ffffff; +} + +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} + +.label[href]:hover, +.label[href]:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label:empty { + display: none; +} + +.label-default { + background-color: #999999; +} + +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #808080; +} + +.label-primary { + background-color: #428bca; +} + +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #3071a9; +} + +.label-success { + background-color: #5cb85c; +} + +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} + +.label-info { + background-color: #5bc0de; +} + +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} + +.label-warning { + background-color: #f0ad4e; +} + +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} + +.label-danger { + background-color: #d9534f; +} + +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} + +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; + border-radius: 10px; +} + +.badge:empty { + display: none; +} + +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.btn .badge { + position: relative; + top: -1px; +} + +a.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #428bca; + background-color: #ffffff; +} + +.nav-pills > li > a > .badge { + margin-left: 3px; +} + +.jumbotron { + padding: 30px; + margin-bottom: 30px; + font-size: 21px; + font-weight: 200; + line-height: 2.1428571435; + color: inherit; + background-color: #eeeeee; +} + +.jumbotron h1 { + line-height: 1; + color: inherit; +} + +.jumbotron p { + line-height: 1.4; +} + +.container .jumbotron { + border-radius: 6px; +} + +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1 { + font-size: 63px; + } +} + +.thumbnail { + display: inline-block; + display: block; + height: auto; + max-width: 100%; + padding: 4px; + line-height: 1.428571429; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +.thumbnail > img { + display: block; + height: auto; + max-width: 100%; +} + +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #428bca; +} + +.thumbnail > img { + margin-right: auto; + margin-left: auto; +} + +.thumbnail .caption { + padding: 9px; + color: #333333; +} + +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} + +.alert h4 { + margin-top: 0; + color: inherit; +} + +.alert .alert-link { + font-weight: bold; +} + +.alert > p, +.alert > ul { + margin-bottom: 0; +} + +.alert > p + p { + margin-top: 5px; +} + +.alert-dismissable { + padding-right: 35px; +} + +.alert-dismissable .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success hr { + border-top-color: #c9e2b3; +} + +.alert-success .alert-link { + color: #356635; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info hr { + border-top-color: #a6e1ec; +} + +.alert-info .alert-link { + color: #2d6987; +} + +.alert-warning { + color: #c09853; + background-color: #fcf8e3; + border-color: #fbeed5; +} + +.alert-warning hr { + border-top-color: #f8e5be; +} + +.alert-warning .alert-link { + color: #a47e3c; +} + +.alert-danger { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-danger hr { + border-top-color: #e6c1c7; +} + +.alert-danger .alert-link { + color: #953b39; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + color: #ffffff; + text-align: center; + background-color: #428bca; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress-striped .progress-bar { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} + +.progress.active .progress-bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + +.progress-bar-success { + background-color: #5cb85c; +} + +.progress-striped .progress-bar-success { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-bar-info { + background-color: #5bc0de; +} + +.progress-striped .progress-bar-info { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-bar-warning { + background-color: #f0ad4e; +} + +.progress-striped .progress-bar-warning { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-bar-danger { + background-color: #d9534f; +} + +.progress-striped .progress-bar-danger { + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.media, +.media-body { + overflow: hidden; + zoom: 1; +} + +.media, +.media .media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media-object { + display: block; +} + +.media-heading { + margin: 0 0 5px; +} + +.media > .pull-left { + margin-right: 10px; +} + +.media > .pull-right { + margin-left: 10px; +} + +.media-list { + padding-left: 0; + list-style: none; +} + +.list-group { + padding-left: 0; + margin-bottom: 20px; +} + +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #ffffff; + border: 1px solid #dddddd; +} + +.list-group-item:first-child { + border-top-right-radius: 4px; + border-top-left-radius: 4px; +} + +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} + +.list-group-item > .badge { + float: right; +} + +.list-group-item > .badge + .badge { + margin-right: 5px; +} + +a.list-group-item { + color: #555555; +} + +a.list-group-item .list-group-item-heading { + color: #333333; +} + +a.list-group-item:hover, +a.list-group-item:focus { + text-decoration: none; + background-color: #f5f5f5; +} + +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #ffffff; + background-color: #428bca; + border-color: #428bca; +} + +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading { + color: inherit; +} + +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #e1edf7; +} + +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} + +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} + +.panel { + margin-bottom: 20px; + background-color: #ffffff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.panel-body { + padding: 15px; +} + +.panel-body:before, +.panel-body:after { + display: table; + content: " "; +} + +.panel-body:after { + clear: both; +} + +.panel-body:before, +.panel-body:after { + display: table; + content: " "; +} + +.panel-body:after { + clear: both; +} + +.panel > .list-group { + margin-bottom: 0; +} + +.panel > .list-group .list-group-item { + border-width: 1px 0; +} + +.panel > .list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} + +.panel > .list-group .list-group-item:last-child { + border-bottom: 0; +} + +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} + +.panel > .table { + margin-bottom: 0; +} + +.panel > .panel-body + .table { + border-top: 1px solid #dddddd; +} + +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} + +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; +} + +.panel-title > a { + color: inherit; +} + +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #dddddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} + +.panel-group .panel { + margin-bottom: 0; + overflow: hidden; + border-radius: 4px; +} + +.panel-group .panel + .panel { + margin-top: 5px; +} + +.panel-group .panel-heading { + border-bottom: 0; +} + +.panel-group .panel-heading + .panel-collapse .panel-body { + border-top: 1px solid #dddddd; +} + +.panel-group .panel-footer { + border-top: 0; +} + +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #dddddd; +} + +.panel-default { + border-color: #dddddd; +} + +.panel-default > .panel-heading { + color: #333333; + background-color: #f5f5f5; + border-color: #dddddd; +} + +.panel-default > .panel-heading + .panel-collapse .panel-body { + border-top-color: #dddddd; +} + +.panel-default > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #dddddd; +} + +.panel-primary { + border-color: #428bca; +} + +.panel-primary > .panel-heading { + color: #ffffff; + background-color: #428bca; + border-color: #428bca; +} + +.panel-primary > .panel-heading + .panel-collapse .panel-body { + border-top-color: #428bca; +} + +.panel-primary > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #428bca; +} + +.panel-success { + border-color: #d6e9c6; +} + +.panel-success > .panel-heading { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.panel-success > .panel-heading + .panel-collapse .panel-body { + border-top-color: #d6e9c6; +} + +.panel-success > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #d6e9c6; +} + +.panel-warning { + border-color: #fbeed5; +} + +.panel-warning > .panel-heading { + color: #c09853; + background-color: #fcf8e3; + border-color: #fbeed5; +} + +.panel-warning > .panel-heading + .panel-collapse .panel-body { + border-top-color: #fbeed5; +} + +.panel-warning > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #fbeed5; +} + +.panel-danger { + border-color: #eed3d7; +} + +.panel-danger > .panel-heading { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.panel-danger > .panel-heading + .panel-collapse .panel-body { + border-top-color: #eed3d7; +} + +.panel-danger > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #eed3d7; +} + +.panel-info { + border-color: #bce8f1; +} + +.panel-info > .panel-heading { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.panel-info > .panel-heading + .panel-collapse .panel-body { + border-top-color: #bce8f1; +} + +.panel-info > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #bce8f1; +} + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.well-lg { + padding: 24px; + border-radius: 6px; +} + +.well-sm { + padding: 9px; + border-radius: 3px; +} + +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.modal-open { + overflow: hidden; +} + +body.modal-open, +.modal-open .navbar-fixed-top, +.modal-open .navbar-fixed-bottom { + margin-right: 15px; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + display: none; + overflow: auto; + overflow-y: scroll; +} + +.modal.fade .modal-dialog { + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + transform: translate(0, -25%); + -webkit-transition: -webkit-transform 0.3s ease-out; + -moz-transition: -moz-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + transition: transform 0.3s ease-out; +} + +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} + +.modal-dialog { + z-index: 1050; + width: auto; + padding: 10px; + margin-right: auto; + margin-left: auto; +} + +.modal-content { + position: relative; + background-color: #ffffff; + border: 1px solid #999999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; + background-color: #000000; +} + +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} + +.modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); +} + +.modal-header { + min-height: 16.428571429px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} + +.modal-header .close { + margin-top: -2px; +} + +.modal-title { + margin: 0; + line-height: 1.428571429; +} + +.modal-body { + position: relative; + padding: 20px; +} + +.modal-footer { + padding: 19px 20px 20px; + margin-top: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +@media screen and (min-width: 768px) { + .modal-dialog { + right: auto; + left: 50%; + width: 600px; + padding-top: 30px; + padding-bottom: 30px; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + } +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 12px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + border-radius: 4px; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.top-right .tooltip-arrow { + right: 5px; + bottom: 0; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} + +.popover-content { + padding: 9px 14px; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow { + border-width: 11px; +} + +.popover .arrow:after { + border-width: 10px; + content: ""; +} + +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; + content: " "; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; + content: " "; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; + content: " "; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; + content: " "; +} + +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + height: auto; + max-width: 100%; + line-height: 1; +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.left { + background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%)); + background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} + +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%)); + background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} + +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + left: 50%; + z-index: 5; + display: inline-block; +} + +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + font-family: serif; +} + +.carousel-control .icon-prev:before { + content: '\2039'; +} + +.carousel-control .icon-next:before { + content: '\203a'; +} + +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} + +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + border: 1px solid #ffffff; + border-radius: 10px; +} + +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #ffffff; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} + +.carousel-caption .btn { + text-shadow: none; +} + +@media screen and (min-width: 768px) { + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + margin-left: -15px; + font-size: 30px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} + +.clearfix:before, +.clearfix:after { + display: table; + content: " "; +} + +.clearfix:after { + clear: both; +} + +.pull-right { + float: right !important; +} + +.pull-left { + float: left !important; +} + +.hide { + display: none !important; +} + +.show { + display: block !important; +} + +.invisible { + visibility: hidden; +} + +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.affix { + position: fixed; +} + +@-ms-viewport { + width: device-width; +} + +@media screen and (max-width: 400px) { + @-ms-viewport { + width: 320px; + } +} + +.hidden { + display: none !important; + visibility: hidden !important; +} + +.visible-xs { + display: none !important; +} + +tr.visible-xs { + display: none !important; +} + +th.visible-xs, +td.visible-xs { + display: none !important; +} + +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-xs.visible-sm { + display: block !important; + } + tr.visible-xs.visible-sm { + display: table-row !important; + } + th.visible-xs.visible-sm, + td.visible-xs.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-xs.visible-md { + display: block !important; + } + tr.visible-xs.visible-md { + display: table-row !important; + } + th.visible-xs.visible-md, + td.visible-xs.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-xs.visible-lg { + display: block !important; + } + tr.visible-xs.visible-lg { + display: table-row !important; + } + th.visible-xs.visible-lg, + td.visible-xs.visible-lg { + display: table-cell !important; + } +} + +.visible-sm { + display: none !important; +} + +tr.visible-sm { + display: none !important; +} + +th.visible-sm, +td.visible-sm { + display: none !important; +} + +@media (max-width: 767px) { + .visible-sm.visible-xs { + display: block !important; + } + tr.visible-sm.visible-xs { + display: table-row !important; + } + th.visible-sm.visible-xs, + td.visible-sm.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-sm.visible-md { + display: block !important; + } + tr.visible-sm.visible-md { + display: table-row !important; + } + th.visible-sm.visible-md, + td.visible-sm.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-sm.visible-lg { + display: block !important; + } + tr.visible-sm.visible-lg { + display: table-row !important; + } + th.visible-sm.visible-lg, + td.visible-sm.visible-lg { + display: table-cell !important; + } +} + +.visible-md { + display: none !important; +} + +tr.visible-md { + display: none !important; +} + +th.visible-md, +td.visible-md { + display: none !important; +} + +@media (max-width: 767px) { + .visible-md.visible-xs { + display: block !important; + } + tr.visible-md.visible-xs { + display: table-row !important; + } + th.visible-md.visible-xs, + td.visible-md.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-md.visible-sm { + display: block !important; + } + tr.visible-md.visible-sm { + display: table-row !important; + } + th.visible-md.visible-sm, + td.visible-md.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-md.visible-lg { + display: block !important; + } + tr.visible-md.visible-lg { + display: table-row !important; + } + th.visible-md.visible-lg, + td.visible-md.visible-lg { + display: table-cell !important; + } +} + +.visible-lg { + display: none !important; +} + +tr.visible-lg { + display: none !important; +} + +th.visible-lg, +td.visible-lg { + display: none !important; +} + +@media (max-width: 767px) { + .visible-lg.visible-xs { + display: block !important; + } + tr.visible-lg.visible-xs { + display: table-row !important; + } + th.visible-lg.visible-xs, + td.visible-lg.visible-xs { + display: table-cell !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .visible-lg.visible-sm { + display: block !important; + } + tr.visible-lg.visible-sm { + display: table-row !important; + } + th.visible-lg.visible-sm, + td.visible-lg.visible-sm { + display: table-cell !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .visible-lg.visible-md { + display: block !important; + } + tr.visible-lg.visible-md { + display: table-row !important; + } + th.visible-lg.visible-md, + td.visible-lg.visible-md { + display: table-cell !important; + } +} + +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} + +.hidden-xs { + display: block !important; +} + +tr.hidden-xs { + display: table-row !important; +} + +th.hidden-xs, +td.hidden-xs { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } + tr.hidden-xs { + display: none !important; + } + th.hidden-xs, + td.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-xs.hidden-sm { + display: none !important; + } + tr.hidden-xs.hidden-sm { + display: none !important; + } + th.hidden-xs.hidden-sm, + td.hidden-xs.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-xs.hidden-md { + display: none !important; + } + tr.hidden-xs.hidden-md { + display: none !important; + } + th.hidden-xs.hidden-md, + td.hidden-xs.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-xs.hidden-lg { + display: none !important; + } + tr.hidden-xs.hidden-lg { + display: none !important; + } + th.hidden-xs.hidden-lg, + td.hidden-xs.hidden-lg { + display: none !important; + } +} + +.hidden-sm { + display: block !important; +} + +tr.hidden-sm { + display: table-row !important; +} + +th.hidden-sm, +td.hidden-sm { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-sm.hidden-xs { + display: none !important; + } + tr.hidden-sm.hidden-xs { + display: none !important; + } + th.hidden-sm.hidden-xs, + td.hidden-sm.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } + tr.hidden-sm { + display: none !important; + } + th.hidden-sm, + td.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-sm.hidden-md { + display: none !important; + } + tr.hidden-sm.hidden-md { + display: none !important; + } + th.hidden-sm.hidden-md, + td.hidden-sm.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-sm.hidden-lg { + display: none !important; + } + tr.hidden-sm.hidden-lg { + display: none !important; + } + th.hidden-sm.hidden-lg, + td.hidden-sm.hidden-lg { + display: none !important; + } +} + +.hidden-md { + display: block !important; +} + +tr.hidden-md { + display: table-row !important; +} + +th.hidden-md, +td.hidden-md { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-md.hidden-xs { + display: none !important; + } + tr.hidden-md.hidden-xs { + display: none !important; + } + th.hidden-md.hidden-xs, + td.hidden-md.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-md.hidden-sm { + display: none !important; + } + tr.hidden-md.hidden-sm { + display: none !important; + } + th.hidden-md.hidden-sm, + td.hidden-md.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } + tr.hidden-md { + display: none !important; + } + th.hidden-md, + td.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-md.hidden-lg { + display: none !important; + } + tr.hidden-md.hidden-lg { + display: none !important; + } + th.hidden-md.hidden-lg, + td.hidden-md.hidden-lg { + display: none !important; + } +} + +.hidden-lg { + display: block !important; +} + +tr.hidden-lg { + display: table-row !important; +} + +th.hidden-lg, +td.hidden-lg { + display: table-cell !important; +} + +@media (max-width: 767px) { + .hidden-lg.hidden-xs { + display: none !important; + } + tr.hidden-lg.hidden-xs { + display: none !important; + } + th.hidden-lg.hidden-xs, + td.hidden-lg.hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-lg.hidden-sm { + display: none !important; + } + tr.hidden-lg.hidden-sm { + display: none !important; + } + th.hidden-lg.hidden-sm, + td.hidden-lg.hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-lg.hidden-md { + display: none !important; + } + tr.hidden-lg.hidden-md { + display: none !important; + } + th.hidden-lg.hidden-md, + td.hidden-lg.hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } + tr.hidden-lg { + display: none !important; + } + th.hidden-lg, + td.hidden-lg { + display: none !important; + } +} + +.visible-print { + display: none !important; +} + +tr.visible-print { + display: none !important; +} + +th.visible-print, +td.visible-print { + display: none !important; +} + +@media print { + .visible-print { + display: block !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } + .hidden-print { + display: none !important; + } + tr.hidden-print { + display: none !important; + } + th.hidden-print, + td.hidden-print { + display: none !important; + } +} \ No newline at end of file diff --git a/docs/system-architecture/css/bootstrap-3.0.0/bootstrap.min.css b/docs/system-architecture/css/bootstrap-3.0.0/bootstrap.min.css new file mode 100644 index 000000000..a553c4f5e --- /dev/null +++ b/docs/system-architecture/css/bootstrap-3.0.0/bootstrap.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap v3.0.0 + * + * Copyright 2013 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world by @mdo and @fat. + *//*! normalize.css v2.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid #c0c0c0}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:2cm .5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}button,input,select[multiple],textarea{background-image:none}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-responsive{display:block;height:auto;max-width:100%}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16.099999999999998px;font-weight:200;line-height:1.4}@media(min-width:768px){.lead{font-size:21px}}small{font-size:85%}cite{font-style:normal}.text-muted{color:#999}.text-primary{color:#428bca}.text-warning{color:#c09853}.text-danger{color:#b94a48}.text-success{color:#468847}.text-info{color:#3a87ad}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{margin-top:20px;margin-bottom:10px}h4,h5,h6{margin-top:10px;margin-bottom:10px}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}h1 small,.h1 small{font-size:24px}h2 small,.h2 small{font-size:18px}h3 small,.h3 small,h4 small,.h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt,dd{line-height:1.428571429}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{font-size:17.5px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small{display:block;line-height:1.428571429;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:1.428571429}code,pre{font-family:Monaco,Menlo,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:4px}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.row{margin-right:-15px;margin-left:-15px}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11{float:left}.col-xs-1{width:8.333333333333332%}.col-xs-2{width:16.666666666666664%}.col-xs-3{width:25%}.col-xs-4{width:33.33333333333333%}.col-xs-5{width:41.66666666666667%}.col-xs-6{width:50%}.col-xs-7{width:58.333333333333336%}.col-xs-8{width:66.66666666666666%}.col-xs-9{width:75%}.col-xs-10{width:83.33333333333334%}.col-xs-11{width:91.66666666666666%}.col-xs-12{width:100%}@media(min-width:768px){.container{max-width:750px}.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11{float:left}.col-sm-1{width:8.333333333333332%}.col-sm-2{width:16.666666666666664%}.col-sm-3{width:25%}.col-sm-4{width:33.33333333333333%}.col-sm-5{width:41.66666666666667%}.col-sm-6{width:50%}.col-sm-7{width:58.333333333333336%}.col-sm-8{width:66.66666666666666%}.col-sm-9{width:75%}.col-sm-10{width:83.33333333333334%}.col-sm-11{width:91.66666666666666%}.col-sm-12{width:100%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-3{left:25%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-6{left:50%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-9{left:75%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-11{left:91.66666666666666%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-3{right:25%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-6{right:50%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-9{right:75%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-11{margin-left:91.66666666666666%}}@media(min-width:992px){.container{max-width:970px}.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11{float:left}.col-md-1{width:8.333333333333332%}.col-md-2{width:16.666666666666664%}.col-md-3{width:25%}.col-md-4{width:33.33333333333333%}.col-md-5{width:41.66666666666667%}.col-md-6{width:50%}.col-md-7{width:58.333333333333336%}.col-md-8{width:66.66666666666666%}.col-md-9{width:75%}.col-md-10{width:83.33333333333334%}.col-md-11{width:91.66666666666666%}.col-md-12{width:100%}.col-md-push-0{left:auto}.col-md-push-1{left:8.333333333333332%}.col-md-push-2{left:16.666666666666664%}.col-md-push-3{left:25%}.col-md-push-4{left:33.33333333333333%}.col-md-push-5{left:41.66666666666667%}.col-md-push-6{left:50%}.col-md-push-7{left:58.333333333333336%}.col-md-push-8{left:66.66666666666666%}.col-md-push-9{left:75%}.col-md-push-10{left:83.33333333333334%}.col-md-push-11{left:91.66666666666666%}.col-md-pull-0{right:auto}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-3{right:25%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-6{right:50%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-9{right:75%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-11{right:91.66666666666666%}.col-md-offset-0{margin-left:0}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-11{margin-left:91.66666666666666%}}@media(min-width:1200px){.container{max-width:1170px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11{float:left}.col-lg-1{width:8.333333333333332%}.col-lg-2{width:16.666666666666664%}.col-lg-3{width:25%}.col-lg-4{width:33.33333333333333%}.col-lg-5{width:41.66666666666667%}.col-lg-6{width:50%}.col-lg-7{width:58.333333333333336%}.col-lg-8{width:66.66666666666666%}.col-lg-9{width:75%}.col-lg-10{width:83.33333333333334%}.col-lg-11{width:91.66666666666666%}.col-lg-12{width:100%}.col-lg-push-0{left:auto}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-3{left:25%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-6{left:50%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-9{left:75%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-11{left:91.66666666666666%}.col-lg-pull-0{right:auto}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-3{right:25%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-6{right:50%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-9{right:75%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-offset-0{margin-left:0}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-11{margin-left:91.66666666666666%}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table thead>tr>th,.table tbody>tr>th,.table tfoot>tr>th,.table thead>tr>td,.table tbody>tr>td,.table tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.table thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table caption+thead tr:first-child th,.table colgroup+thead tr:first-child th,.table thead:first-child tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed thead>tr>th,.table-condensed tbody>tr>th,.table-condensed tfoot>tr>th,.table-condensed thead>tr>td,.table-condensed tbody>tr>td,.table-condensed tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8;border-color:#d6e9c6}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td{background-color:#d0e9c6;border-color:#c9e2b3}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede;border-color:#eed3d7}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td{background-color:#ebcccc;border-color:#e6c1c7}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3;border-color:#fbeed5}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td{background-color:#faf2cc;border-color:#f8e5be}@media(max-width:768px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0;background-color:#fff}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>thead>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>thead>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.radio label,.checkbox label{display:inline;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:normal;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm{height:auto}.input-lg{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:45px;line-height:45px}textarea.input-lg{height:auto}.has-warning .help-block,.has-warning .control-label{color:#c09853}.has-warning .form-control{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.has-warning .input-group-addon{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.has-error .help-block,.has-error .control-label{color:#b94a48}.has-error .form-control{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.has-error .input-group-addon{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.has-success .help-block,.has-success .control-label{color:#468847}.has-success .form-control{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.has-success .input-group-addon{color:#468847;background-color:#dff0d8;border-color:#468847}.form-control-static{padding-top:7px;margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline .radio,.form-inline .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}@media(min-width:768px){.form-horizontal .control-label{text-align:right}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:normal;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-link{font-weight:normal;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-print:before{content:"\e045"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-briefcase:before{content:"\1f4bc"}.glyphicon-calendar:before{content:"\1f4c5"}.glyphicon-pushpin:before{content:"\1f4cc"}.glyphicon-paperclip:before{content:"\1f4ce"}.glyphicon-camera:before{content:"\1f4f7"}.glyphicon-lock:before{content:"\1f512"}.glyphicon-bell:before{content:"\1f514"}.glyphicon-bookmark:before{content:"\1f516"}.glyphicon-fire:before{content:"\1f525"}.glyphicon-wrench:before{content:"\1f527"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0 dotted;border-left:4px solid transparent;content:""}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#fff;text-decoration:none;background-color:#428bca}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0 dotted;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.btn-default .caret{border-top-color:#333}.btn-primary .caret,.btn-success .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret{border-top-color:#fff}.dropup .btn-default .caret{border-bottom-color:#333}.dropup .btn-primary .caret,.dropup .btn-success .caret,.dropup .btn-warning .caret,.dropup .btn-danger .caret,.dropup .btn-info .caret{border-bottom-color:#fff}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar .btn-group{float:left}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group-xs>.btn{padding:5px 10px;padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:4px;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.btn-group-justified .btn{display:table-cell;float:none;width:1%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group.col{float:none;padding-right:0;padding-left:0}.input-group .form-control{width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:45px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:45px;line-height:45px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}}.nav-tabs.nav-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs.nav-justified>.active>a{border-bottom-color:#fff}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:5px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center}@media(min-width:768px){.nav-justified>li{display:table-cell;width:1%}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-bottom:1px solid #ddd}.nav-tabs-justified>.active>a{border-bottom-color:#fff}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tabbable:before,.tabbable:after{display:table;content:" "}.tabbable:after{clear:both}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.nav .caret{border-top-color:#428bca;border-bottom-color:#428bca}.nav a:hover .caret{border-top-color:#2a6496;border-bottom-color:#2a6496}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;z-index:1000;min-height:50px;margin-bottom:20px;border:1px solid transparent}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}@media(min-width:768px){.navbar{border-radius:4px}}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse.in{overflow-y:auto}@media(min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-collapse .navbar-nav.navbar-left:first-child{margin-left:-15px}.navbar-collapse .navbar-nav.navbar-right:last-child{margin-right:-15px}.navbar-collapse .navbar-text:last-child{margin-right:0}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{border-width:0 0 1px}@media(min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;border-width:0 0 1px}@media(min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;z-index:1030}.navbar-fixed-bottom{bottom:0;margin-bottom:0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media(min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;border:1px solid transparent;border-radius:4px}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media(min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media(max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media(min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}@media(min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-text{float:left;margin-top:15px;margin-bottom:15px}@media(min-width:768px){.navbar-text{margin-right:15px;margin-left:15px}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#ccc}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e6e6e6}.navbar-default .navbar-nav>.dropdown>a:hover .caret,.navbar-default .navbar-nav>.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.open>a .caret,.navbar-default .navbar-nav>.open>a:hover .caret,.navbar-default .navbar-nav>.open>a:focus .caret{border-top-color:#555;border-bottom-color:#555}.navbar-default .navbar-nav>.dropdown>a .caret{border-top-color:#777;border-bottom-color:#777}@media(max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-nav>.dropdown>a .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .navbar-nav>.open>a .caret,.navbar-inverse .navbar-nav>.open>a:hover .caret,.navbar-inverse .navbar-nav>.open>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}@media(max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eee}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:10px}.badge:empty{display:none}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.btn .badge{position:relative;top:-1px}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eee}.jumbotron h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.container .jumbotron{border-radius:6px}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1{font-size:63px}}.thumbnail{display:inline-block;display:block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img{display:block;height:auto;max-width:100%}a.thumbnail:hover,a.thumbnail:focus{border-color:#428bca}.thumbnail>img{margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#356635}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#2d6987}.alert-warning{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.alert-warning hr{border-top-color:#f8e5be}.alert-warning .alert-link{color:#a47e3c}.alert-danger{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger hr{border-top-color:#e6c1c7}.alert-danger .alert-link{color:#953b39}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table{margin-bottom:0}.panel>.panel-body+.table{border-top:1px solid #ddd}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-title{margin-top:0;margin-bottom:0;font-size:16px}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-warning{border-color:#fbeed5}.panel-warning>.panel-heading{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#fbeed5}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#fbeed5}.panel-danger{border-color:#eed3d7}.panel-danger>.panel-heading{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#eed3d7}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#eed3d7}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}body.modal-open,.modal-open .navbar-fixed-top,.modal-open .navbar-fixed-bottom{margin-right:15px}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{z-index:1050;width:auto;padding:10px;margin-right:auto;margin-left:auto}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media screen and (min-width:768px){.modal-dialog{right:auto;left:50%;width:600px;padding-top:30px;padding-bottom:30px}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}}.tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#000;border-width:0 5px 5px}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0;content:" "}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0;content:" "}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0;content:" "}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0;content:" "}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;height:auto;max-width:100%;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);opacity:.5;filter:alpha(opacity=50)}.carousel-control.left{background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.5)),to(rgba(0,0,0,0.0001)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.5) 0),color-stop(rgba(0,0,0,0.0001) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',endColorstr='#00000000',GradientType=1)}.carousel-control.right{right:0;left:auto;background-image:-webkit-gradient(linear,0 top,100% top,from(rgba(0,0,0,0.0001)),to(rgba(0,0,0,0.5)));background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.0001) 0),color-stop(rgba(0,0,0,0.5) 100%));background-image:-moz-linear-gradient(left,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-image:linear-gradient(to right,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#80000000',GradientType=1)}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;left:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.affix{position:fixed}@-ms-viewport{width:device-width}@media screen and (max-width:400px){@-ms-viewport{width:320px}}.hidden{display:none!important;visibility:hidden!important}.visible-xs{display:none!important}tr.visible-xs{display:none!important}th.visible-xs,td.visible-xs{display:none!important}@media(max-width:767px){.visible-xs{display:block!important}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block!important}tr.visible-xs.visible-sm{display:table-row!important}th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block!important}tr.visible-xs.visible-md{display:table-row!important}th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-xs.visible-lg{display:block!important}tr.visible-xs.visible-lg{display:table-row!important}th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell!important}}.visible-sm{display:none!important}tr.visible-sm{display:none!important}th.visible-sm,td.visible-sm{display:none!important}@media(max-width:767px){.visible-sm.visible-xs{display:block!important}tr.visible-sm.visible-xs{display:table-row!important}th.visible-sm.visible-xs,td.visible-sm.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-sm{display:block!important}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block!important}tr.visible-sm.visible-md{display:table-row!important}th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-sm.visible-lg{display:block!important}tr.visible-sm.visible-lg{display:table-row!important}th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell!important}}.visible-md{display:none!important}tr.visible-md{display:none!important}th.visible-md,td.visible-md{display:none!important}@media(max-width:767px){.visible-md.visible-xs{display:block!important}tr.visible-md.visible-xs{display:table-row!important}th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block!important}tr.visible-md.visible-sm{display:table-row!important}th.visible-md.visible-sm,td.visible-md.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-md{display:block!important}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-md.visible-lg{display:block!important}tr.visible-md.visible-lg{display:table-row!important}th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell!important}}.visible-lg{display:none!important}tr.visible-lg{display:none!important}th.visible-lg,td.visible-lg{display:none!important}@media(max-width:767px){.visible-lg.visible-xs{display:block!important}tr.visible-lg.visible-xs{display:table-row!important}th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell!important}}@media(min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block!important}tr.visible-lg.visible-sm{display:table-row!important}th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell!important}}@media(min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block!important}tr.visible-lg.visible-md{display:table-row!important}th.visible-lg.visible-md,td.visible-lg.visible-md{display:table-cell!important}}@media(min-width:1200px){.visible-lg{display:block!important}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}.hidden-xs{display:block!important}tr.hidden-xs{display:table-row!important}th.hidden-xs,td.hidden-xs{display:table-cell!important}@media(max-width:767px){.hidden-xs{display:none!important}tr.hidden-xs{display:none!important}th.hidden-xs,td.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm{display:none!important}tr.hidden-xs.hidden-sm{display:none!important}th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md{display:none!important}tr.hidden-xs.hidden-md{display:none!important}th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-xs.hidden-lg{display:none!important}tr.hidden-xs.hidden-lg{display:none!important}th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none!important}}.hidden-sm{display:block!important}tr.hidden-sm{display:table-row!important}th.hidden-sm,td.hidden-sm{display:table-cell!important}@media(max-width:767px){.hidden-sm.hidden-xs{display:none!important}tr.hidden-sm.hidden-xs{display:none!important}th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}tr.hidden-sm{display:none!important}th.hidden-sm,td.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md{display:none!important}tr.hidden-sm.hidden-md{display:none!important}th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-sm.hidden-lg{display:none!important}tr.hidden-sm.hidden-lg{display:none!important}th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none!important}}.hidden-md{display:block!important}tr.hidden-md{display:table-row!important}th.hidden-md,td.hidden-md{display:table-cell!important}@media(max-width:767px){.hidden-md.hidden-xs{display:none!important}tr.hidden-md.hidden-xs{display:none!important}th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-md.hidden-sm{display:none!important}tr.hidden-md.hidden-sm{display:none!important}th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}tr.hidden-md{display:none!important}th.hidden-md,td.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-md.hidden-lg{display:none!important}tr.hidden-md.hidden-lg{display:none!important}th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none!important}}.hidden-lg{display:block!important}tr.hidden-lg{display:table-row!important}th.hidden-lg,td.hidden-lg{display:table-cell!important}@media(max-width:767px){.hidden-lg.hidden-xs{display:none!important}tr.hidden-lg.hidden-xs{display:none!important}th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none!important}}@media(min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm{display:none!important}tr.hidden-lg.hidden-sm{display:none!important}th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none!important}}@media(min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md{display:none!important}tr.hidden-lg.hidden-md{display:none!important}th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none!important}}@media(min-width:1200px){.hidden-lg{display:none!important}tr.hidden-lg{display:none!important}th.hidden-lg,td.hidden-lg{display:none!important}}.visible-print{display:none!important}tr.visible-print{display:none!important}th.visible-print,td.visible-print{display:none!important}@media print{.visible-print{display:block!important}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}.hidden-print{display:none!important}tr.hidden-print{display:none!important}th.hidden-print,td.hidden-print{display:none!important}} \ No newline at end of file diff --git a/docs/system-architecture/css/fonts/glyphicons-halflings-regular.eot b/docs/system-architecture/css/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 000000000..87eaa4342 Binary files /dev/null and b/docs/system-architecture/css/fonts/glyphicons-halflings-regular.eot differ diff --git a/docs/system-architecture/css/fonts/glyphicons-halflings-regular.svg b/docs/system-architecture/css/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 000000000..5fee06854 --- /dev/null +++ b/docs/system-architecture/css/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/system-architecture/css/fonts/glyphicons-halflings-regular.ttf b/docs/system-architecture/css/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 000000000..be784dc1d Binary files /dev/null and b/docs/system-architecture/css/fonts/glyphicons-halflings-regular.ttf differ diff --git a/docs/system-architecture/css/fonts/glyphicons-halflings-regular.woff b/docs/system-architecture/css/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 000000000..2cc3e4852 Binary files /dev/null and b/docs/system-architecture/css/fonts/glyphicons-halflings-regular.woff differ diff --git a/docs/system-architecture/css/main.css b/docs/system-architecture/css/main.css new file mode 100644 index 000000000..00a3e30a0 --- /dev/null +++ b/docs/system-architecture/css/main.css @@ -0,0 +1,300 @@ +/* + * HTML5 Boilerplate + * + * What follows is the result of much research on cross-browser styling. + * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal, + * Kroc Camen, and the H5BP dev community and team. + */ + +/* ========================================================================== + Base styles: opinionated defaults + ========================================================================== */ + +html, +button, +input, +select, +textarea { + color: #222; +} + +body { + font-size: 1em; + line-height: 1.4; +} + +/* + * Remove text-shadow in selection highlight: h5bp.com/i + * These selection rule sets have to be separate. + * Customize the background color to match your design. + */ + +::-moz-selection { + background: #b3d4fc; + text-shadow: none; +} + +::selection { + background: #b3d4fc; + text-shadow: none; +} + +/* + * A better looking default horizontal rule + */ + +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 1em 0; + padding: 0; +} + +/* + * Remove the gap between images and the bottom of their containers: h5bp.com/i/440 + */ + +img { + vertical-align: middle; +} + +/* + * Remove default fieldset styles. + */ + +fieldset { + border: 0; + margin: 0; + padding: 0; +} + +/* + * Allow only vertical resizing of textareas. + */ + +textarea { + resize: vertical; +} + +/* ========================================================================== + Chrome Frame prompt + ========================================================================== */ + +.chromeframe { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; +} + +/* ========================================================================== + Author's custom styles + ========================================================================== */ + + + + + + + + + + + + + + + + + +/* ========================================================================== + Helper classes + ========================================================================== */ + +/* + * Image replacement + */ + +.ir { + background-color: transparent; + border: 0; + overflow: hidden; + /* IE 6/7 fallback */ + *text-indent: -9999px; +} + +.ir:before { + content: ""; + display: block; + width: 0; + height: 150%; +} + +/* + * Hide from both screenreaders and browsers: h5bp.com/u + */ + +.hidden { + display: none !important; + visibility: hidden; +} + +/* + * Hide only visually, but have it available for screenreaders: h5bp.com/v + */ + +.visuallyhidden { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +/* + * Extends the .visuallyhidden class to allow the element to be focusable + * when navigated to via the keyboard: h5bp.com/p + */ + +.visuallyhidden.focusable:active, +.visuallyhidden.focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; +} + +/* + * Hide visually and from screenreaders, but maintain layout + */ + +.invisible { + visibility: hidden; +} + +/* + * Clearfix: contain floats + * + * For modern browsers + * 1. The space content is one way to avoid an Opera bug when the + * `contenteditable` attribute is included anywhere else in the document. + * Otherwise it causes space to appear at the top and bottom of elements + * that receive the `clearfix` class. + * 2. The use of `table` rather than `block` is only necessary if using + * `:before` to contain the top-margins of child elements. + */ + +.clearfix:before, +.clearfix:after { + content: " "; /* 1 */ + display: table; /* 2 */ +} + +.clearfix:after { + clear: both; +} + +/* + * For IE 6/7 only + * Include this rule to trigger hasLayout and contain floats. + */ + +.clearfix { + *zoom: 1; +} + +/* ========================================================================== + EXAMPLE Media Queries for Responsive Design. + These examples override the primary ('mobile first') styles. + Modify as content requires. + ========================================================================== */ + +@media only screen and (min-width: 35em) { + /* Style adjustments for viewports that meet the condition */ +} + +@media print, + (-o-min-device-pixel-ratio: 5/4), + (-webkit-min-device-pixel-ratio: 1.25), + (min-resolution: 120dpi) { + /* Style adjustments for high resolution devices */ +} + +/* ========================================================================== + Print styles. + Inlined to avoid required HTTP connection: h5bp.com/r + ========================================================================== */ + +@media print { + * { + background: transparent !important; + color: #000 !important; /* Black prints faster: h5bp.com/s */ + box-shadow: none !important; + text-shadow: none !important; + } + + a, + a:visited { + text-decoration: underline; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + /* + * Don't show links for images, or javascript/internal links + */ + + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + thead { + display: table-header-group; /* h5bp.com/t */ + } + + tr, + img { + page-break-inside: avoid; + } + + img { + max-width: 100% !important; + } + + @page { + margin: 0.5cm; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } +} diff --git a/docs/system-architecture/css/normalize.css b/docs/system-architecture/css/normalize.css new file mode 100644 index 000000000..8d57e3c96 --- /dev/null +++ b/docs/system-architecture/css/normalize.css @@ -0,0 +1,533 @@ +/*! normalize.css v1.1.1 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined in IE 6/7/8/9 and Firefox 3. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} + +/** + * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. + */ + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4. + * Known issue: no IE 6 support. + */ + +[hidden] { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/** + * 1. Prevent system color scheme's background color being used in Firefox, IE, + * and Opera. + * 2. Prevent system color scheme's text color being used in Firefox, IE, and + * Opera. + * 3. Correct text resizing oddly in IE 6/7 when body `font-size` is set using + * `em` units. + * 4. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + background: #fff; /* 1 */ + color: #000; /* 2 */ + font-size: 100%; /* 3 */ + -webkit-text-size-adjust: 100%; /* 4 */ + -ms-text-size-adjust: 100%; /* 4 */ +} + +/** + * Address `font-family` inconsistency between `textarea` and other form + * elements. + */ + +html, +button, +input, +select, +textarea { + font-family: sans-serif; +} + +/** + * Address margins handled incorrectly in IE 6/7. + */ + +body { + margin: 0; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/** + * Address `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/** + * Address font sizes and margins set differently in IE 6/7. + * Address font sizes within `section` and `article` in Firefox 4+, Safari 5, + * and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +h2 { + font-size: 1.5em; + margin: 0.83em 0; +} + +h3 { + font-size: 1.17em; + margin: 1em 0; +} + +h4 { + font-size: 1em; + margin: 1.33em 0; +} + +h5 { + font-size: 0.83em; + margin: 1.67em 0; +} + +h6 { + font-size: 0.67em; + margin: 2.33em 0; +} + +/** + * Address styling not present in IE 7/8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +blockquote { + margin: 1em 40px; +} + +/** + * Address styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address differences between Firefox and other browsers. + * Known issue: no IE 6/7 normalization. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Address styling not present in IE 6/7/8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address margins set differently in IE 6/7. + */ + +p, +pre { + margin: 1em 0; +} + +/** + * Correct font family set oddly in IE 6, Safari 4/5, and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + _font-family: 'courier new', monospace; + font-size: 1em; +} + +/** + * Improve readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +/** + * Address CSS quotes not supported in IE 6/7. + */ + +q { + quotes: none; +} + +/** + * Address `quotes` property not supported in Safari 4. + */ + +q:before, +q:after { + content: ''; + content: none; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Lists + ========================================================================== */ + +/** + * Address margins set differently in IE 6/7. + */ + +dl, +menu, +ol, +ul { + margin: 1em 0; +} + +dd { + margin: 0 0 0 40px; +} + +/** + * Address paddings set differently in IE 6/7. + */ + +menu, +ol, +ul { + padding: 0 0 0 40px; +} + +/** + * Correct list images handled incorrectly in IE 7. + */ + +nav ul, +nav ol { + list-style: none; + list-style-image: none; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/** + * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3. + * 2. Improve image quality when scaled in IE 7. + */ + +img { + border: 0; /* 1 */ + -ms-interpolation-mode: bicubic; /* 2 */ +} + +/** + * Correct overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/** + * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/** + * Correct margin displayed oddly in IE 6/7. + */ + +form { + margin: 0; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct color not being inherited in IE 6/7/8/9. + * 2. Correct text not wrapping in Firefox 3. + * 3. Correct alignment displayed oddly in IE 6/7. + */ + +legend { + border: 0; /* 1 */ + padding: 0; + white-space: normal; /* 2 */ + *margin-left: -7px; /* 3 */ +} + +/** + * 1. Correct font size not being inherited in all browsers. + * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5, + * and Chrome. + * 3. Improve appearance and consistency in all browsers. + */ + +button, +input, +select, +textarea { + font-size: 100%; /* 1 */ + margin: 0; /* 2 */ + vertical-align: baseline; /* 3 */ + *vertical-align: middle; /* 3 */ +} + +/** + * Address Firefox 3+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+. + * Correct `select` style inheritance in Firefox 4+ and Opera. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + * 4. Remove inner spacing in IE 7 without affecting normal text inputs. + * Known issue: inner spacing remains in IE 6. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ + *overflow: visible; /* 4 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * 1. Address box sizing set to content-box in IE 8/9. + * 2. Remove excess padding in IE 8/9. + * 3. Remove excess padding in IE 7. + * Known issue: excess padding remains in IE 6. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ + *height: 13px; /* 3 */ + *width: 13px; /* 3 */ +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Remove inner padding and border in Firefox 3+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * 1. Remove default vertical scrollbar in IE 6/7/8/9. + * 2. Improve readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/* ========================================================================== + Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/docs/system-architecture/css/toc-0.1.2.zip b/docs/system-architecture/css/toc-0.1.2.zip new file mode 100644 index 000000000..ea1d84e13 Binary files /dev/null and b/docs/system-architecture/css/toc-0.1.2.zip differ diff --git a/docs/system-architecture/css/toc-0.1.2/.gitignore b/docs/system-architecture/css/toc-0.1.2/.gitignore new file mode 100644 index 000000000..70e542c50 --- /dev/null +++ b/docs/system-architecture/css/toc-0.1.2/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +node_modules +components +reports diff --git a/docs/system-architecture/css/toc-0.1.2/.gitmodules b/docs/system-architecture/css/toc-0.1.2/.gitmodules new file mode 100644 index 000000000..e69de29bb diff --git a/docs/system-architecture/css/toc-0.1.2/Gruntfile.js b/docs/system-architecture/css/toc-0.1.2/Gruntfile.js new file mode 100644 index 000000000..8680b3712 --- /dev/null +++ b/docs/system-architecture/css/toc-0.1.2/Gruntfile.js @@ -0,0 +1,100 @@ +module.exports = function(grunt) { + grunt.initConfig({ + info: grunt.file.readJSON('component.json'), + meta: { + banner: '/*!\n'+ + ' * <%= info.name %> - <%= info.description %>\n'+ + ' * v<%= info.version %>\n'+ + ' * <%= info.homepage %>\n'+ + ' * copyright <%= info.copyright %> <%= grunt.template.today("yyyy") %>\n'+ + ' * <%= info.license %> License\n'+ + '*/\n' + }, + jshint: { + main: [ + 'grunt.js', + 'component.json', + 'lib/**/*.js', + 'test/*.js' + ] + }, + concat: { + options: { + banner: '<%= meta.banner %>' + }, + dist: { + src: 'lib/toc.js', + dest: 'dist/jquery.toc.js' + } + }, + uglify: { + options: { + banner: '<%= meta.banner %>' + }, + dist: { + src: 'dist/jquery.toc.js', + dest: 'dist/jquery.toc.min.js' + } + }, + watch: { + main: { + files: '<%= jshint.main %>', + tasks: 'default' + }, + ci: { + files: [ + '<%= jshint.main %>', + 'test/index.html' + ], + tasks: ['default', 'mocha'] + } + }, + mocha: { + all: { + src: 'test/index.html', + options: { + run: true + } + } + }, + plato: { + main: { + files: { + 'reports': ['lib/*.js'] + } + } + }, + reloadr: { + test: [ + 'example/*', + 'test/*', + 'dist/*' + ] + }, + connect: { + server:{ + port: 8000, + base: '.' + }, + plato: { + port: 8000, + base: 'reports', + options: { + keepalive: true + } + } + } + }); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-mocha'); + grunt.loadNpmTasks('grunt-reloadr'); + grunt.loadNpmTasks('grunt-plato'); + grunt.registerTask('default', ['jshint', 'concat', 'uglify']); + grunt.registerTask('dev', ['connect:server', 'reloadr', 'watch:main']); + grunt.registerTask('ci', ['connect:server', 'watch:ci']); + grunt.registerTask('reports', ['plato', 'connect:plato']); +}; diff --git a/docs/system-architecture/css/toc-0.1.2/History.md b/docs/system-architecture/css/toc-0.1.2/History.md new file mode 100644 index 000000000..1ff3baef4 --- /dev/null +++ b/docs/system-architecture/css/toc-0.1.2/History.md @@ -0,0 +1,46 @@ + +0.1.2 / 2013-04-08 +================== + + * optimized scroll function. fixes #15 + * migrated to grunt for building + * fixed tabs on docs/index + +0.1.1 / 2012-10-05 +================== + + * updated example + * code cleanup, fixed onHighlight, removed console.log + * Add headerText and itemClass options + +0.1.0 / 2012-07-05 +================== + + * added smoosh to Makefile + * updated docs + * removed site submodule + * Added callback for when a new section is highlighted + * selected event + * adds another option to customize the header link text + * updated site + +0.0.3 / 2012-04-06 +================== + + * fixed smooth scrolling in firefox + * fixed copyright typo + +0.0.2 / 2012-03-09 +================== + + * Issue [#2](https://github.com/jgallen23/toc/issues/2 "Issue #2") + * updated site + * 0.0.2 - updated docs + +0.0.1 / 2012-02-25 +================== + + * updated docs/site + * added readme + * got everything working + * initial commit diff --git a/docs/system-architecture/css/toc-0.1.2/LICENSE b/docs/system-architecture/css/toc-0.1.2/LICENSE new file mode 100644 index 000000000..ce5d8bc79 --- /dev/null +++ b/docs/system-architecture/css/toc-0.1.2/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2013 Greg Allen + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/docs/system-architecture/css/toc-0.1.2/README.md b/docs/system-architecture/css/toc-0.1.2/README.md new file mode 100644 index 000000000..176f0b94a --- /dev/null +++ b/docs/system-architecture/css/toc-0.1.2/README.md @@ -0,0 +1,5 @@ +#TOC + +[TOC](http://projects.jga.me/toc/) is a jQuery plugin for automatically generating a table of contents. + +For more information, check out the [documentation](http://projects.jga.me/toc/). diff --git a/docs/system-architecture/css/toc-0.1.2/component.json b/docs/system-architecture/css/toc-0.1.2/component.json new file mode 100644 index 000000000..b71fcd775 --- /dev/null +++ b/docs/system-architecture/css/toc-0.1.2/component.json @@ -0,0 +1,14 @@ +{ + "name": "toc", + "description": "jQuery Table of Contents Plugin", + "version": "0.1.2", + "homepage": "http://projects.jga.me/toc/", + "license": "MIT", + "copyright": "Greg Allen", + "main": "dist/toc.js", + "dependencies": { + }, + "devDependencies": { + "assert": "*" + } +} diff --git a/docs/system-architecture/css/toc-0.1.2/dist/jquery.toc.js b/docs/system-architecture/css/toc-0.1.2/dist/jquery.toc.js new file mode 100644 index 000000000..9fe50553d --- /dev/null +++ b/docs/system-architecture/css/toc-0.1.2/dist/jquery.toc.js @@ -0,0 +1,107 @@ +/*! + * toc - jQuery Table of Contents Plugin + * v0.1.2 + * http://projects.jga.me/toc/ + * copyright Greg Allen 2013 + * MIT License +*/ +(function($) { +$.fn.toc = function(options) { + var self = this; + var opts = $.extend({}, jQuery.fn.toc.defaults, options); + + var container = $(opts.container); + var headings = $(opts.selectors, container); + var headingOffsets = []; + var activeClassName = opts.prefix+'-active'; + + var scrollTo = function(e) { + if (opts.smoothScrolling) { + e.preventDefault(); + var elScrollTo = $(e.target).attr('href'); + var $el = $(elScrollTo); + + $('body,html').animate({ scrollTop: $el.offset().top }, 400, 'swing', function() { + location.hash = elScrollTo; + }); + } + $('li', self).removeClass(activeClassName); + $(e.target).parent().addClass(activeClassName); + }; + + //highlight on scroll + var timeout; + var highlightOnScroll = function(e) { + if (timeout) { + clearTimeout(timeout); + } + timeout = setTimeout(function() { + var top = $(window).scrollTop(), + highlighted; + for (var i = 0, c = headingOffsets.length; i < c; i++) { + if (headingOffsets[i] >= top) { + $('li', self).removeClass(activeClassName); + highlighted = $('li:eq('+(i-1)+')', self).addClass(activeClassName); + opts.onHighlight(highlighted); + break; + } + } + }, 50); + }; + if (opts.highlightOnScroll) { + $(window).bind('scroll', highlightOnScroll); + highlightOnScroll(); + } + + return this.each(function() { + //build TOC + var el = $(this); + var ul = $('
a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = marginDiv = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + conMarginTop, ptlm, vb, style, html, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; + vb = "visibility:hidden;border:0;"; + style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; + html = "
" + + "" + + "
"; + + container = document.createElement("div"); + container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Figure out if the W3C box model works as expected + div.innerHTML = ""; + div.style.width = div.style.paddingLeft = "1px"; + jQuery.boxModel = support.boxModel = div.offsetWidth === 2; + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } + + div.style.cssText = ptlm + vb; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + body.removeChild( container ); + div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, attr, name, + data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { + attr = this[0].attributes; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( this[0], name, data[ name ] ); + } + } + jQuery._data( this[0], "parsedAttrs", true ); + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var self = jQuery( this ), + args = [ parts[0], value ]; + + self.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? parseFloat( data ) : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return jQuery.queue( this[0], type ); + } + return this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise(); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.attr ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.prop ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + + // See #9699 for explanation of this approach (setting first, then removal) + jQuery.attr( elem, name, "" ); + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /\bhover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Determine handlers that should run if there are delegated events + // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on.call( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + +
+ + + + + + diff --git a/docs/system-architecture/css/toc-0.1.2/test/toc.test.js b/docs/system-architecture/css/toc-0.1.2/test/toc.test.js new file mode 100644 index 000000000..617194730 --- /dev/null +++ b/docs/system-architecture/css/toc-0.1.2/test/toc.test.js @@ -0,0 +1,4 @@ + +suite('toc', function() { + +}); diff --git a/docs/system-architecture/diagrams/command-query.png b/docs/system-architecture/diagrams/command-query.png new file mode 100644 index 000000000..4de18ecb1 Binary files /dev/null and b/docs/system-architecture/diagrams/command-query.png differ diff --git a/docs/system-architecture/diagrams/command-query.xml b/docs/system-architecture/diagrams/command-query.xml new file mode 100644 index 000000000..f2441921b --- /dev/null +++ b/docs/system-architecture/diagrams/command-query.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/system-architecture/diagrams/platform-categories.png b/docs/system-architecture/diagrams/platform-categories.png new file mode 100644 index 000000000..6c464642c Binary files /dev/null and b/docs/system-architecture/diagrams/platform-categories.png differ diff --git a/docs/system-architecture/diagrams/platform-categories.xml b/docs/system-architecture/diagrams/platform-categories.xml new file mode 100644 index 000000000..f63b81734 --- /dev/null +++ b/docs/system-architecture/diagrams/platform-categories.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/system-architecture/diagrams/platform-systemview.png b/docs/system-architecture/diagrams/platform-systemview.png new file mode 100644 index 000000000..aa6603143 Binary files /dev/null and b/docs/system-architecture/diagrams/platform-systemview.png differ diff --git a/docs/system-architecture/diagrams/platform-systemview.xml b/docs/system-architecture/diagrams/platform-systemview.xml new file mode 100644 index 000000000..9fba16124 --- /dev/null +++ b/docs/system-architecture/diagrams/platform-systemview.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/system-architecture/favicon.ico b/docs/system-architecture/favicon.ico new file mode 100644 index 000000000..be74abd69 Binary files /dev/null and b/docs/system-architecture/favicon.ico differ diff --git a/docs/system-architecture/humans.txt b/docs/system-architecture/humans.txt new file mode 100644 index 000000000..d9e1bb981 --- /dev/null +++ b/docs/system-architecture/humans.txt @@ -0,0 +1,15 @@ +# humanstxt.org/ +# The humans responsible & technology colophon + +# TEAM + + -- -- + +# THANKS + + + +# TECHNOLOGY COLOPHON + + HTML5, CSS3 + Normalize.css, jQuery, Modernizr diff --git a/docs/system-architecture/img/mifos-icon.png b/docs/system-architecture/img/mifos-icon.png new file mode 100644 index 000000000..bb0252385 Binary files /dev/null and b/docs/system-architecture/img/mifos-icon.png differ diff --git a/docs/system-architecture/index.html b/docs/system-architecture/index.html new file mode 100644 index 000000000..fdf12d439 --- /dev/null +++ b/docs/system-architecture/index.html @@ -0,0 +1,587 @@ + + + + + + + + + Mifos Platform Docs: System Architecture + + + + + + + + + + + + + + +
+
+
+ + +
+ + + + + + + + + \ No newline at end of file diff --git a/docs/system-architecture/js/plugins.js b/docs/system-architecture/js/plugins.js new file mode 100644 index 000000000..9683075a4 --- /dev/null +++ b/docs/system-architecture/js/plugins.js @@ -0,0 +1,23 @@ +// Avoid `console` errors in browsers that lack a console. +(function() { + var method; + var noop = function () {}; + var methods = [ + 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', + 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', + 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', + 'timeStamp', 'trace', 'warn' + ]; + var length = methods.length; + var console = (window.console = window.console || {}); + + while (length--) { + method = methods[length]; + + // Only stub undefined methods. + if (!console[method]) { + console[method] = noop; + } + } +}()); +// Place any jQuery/helper plugins in here. \ No newline at end of file diff --git a/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/application.js b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/application.js new file mode 100644 index 000000000..81b644b97 --- /dev/null +++ b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/application.js @@ -0,0 +1,83 @@ +// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT +// IT'S ALL JUST JUNK FOR OUR DOCS! +// ++++++++++++++++++++++++++++++++++++++++++ + +!function ($) { + + $(function(){ + + var $window = $(window) + var $body = $(document.body) + + var navHeight = $('.navbar').outerHeight(true) + 10 + + $body.scrollspy({ + target: '.bs-sidebar', + offset: navHeight + }) + + $window.on('load', function () { + $body.scrollspy('refresh') + }) + + $('.bs-docs-container [href=#]').click(function (e) { + e.preventDefault() + }) + + // back to top + setTimeout(function () { + var $sideBar = $('.bs-sidebar') + + $sideBar.affix({ + offset: { + top: function () { + var offsetTop = $sideBar.offset().top + var sideBarMargin = parseInt($sideBar.children(0).css('margin-top'), 10) + var navOuterHeight = $('.bs-docs-nav').height() + + return (this.top = offsetTop - navOuterHeight - sideBarMargin) + } + , bottom: function () { + return (this.bottom = $('.bs-footer').outerHeight(true)) + } + } + }) + }, 100) + + setTimeout(function () { + $('.bs-top').affix() + }, 100) + + // tooltip demo + $('.tooltip-demo').tooltip({ + selector: "[data-toggle=tooltip]", + container: "body" + }) + + $('.tooltip-test').tooltip() + $('.popover-test').popover() + + $('.bs-docs-navbar').tooltip({ + selector: "a[data-toggle=tooltip]", + container: ".bs-docs-navbar .nav" + }) + + // popover demo + $("[data-toggle=popover]") + .popover() + + // button state demo + $('#fat-btn') + .click(function () { + var btn = $(this) + btn.button('loading') + setTimeout(function () { + btn.button('reset') + }, 3000) + }) + + // carousel demo + $('.bs-docs-carousel-example').carousel() +}) + +}(window.jQuery) diff --git a/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/customizer.js b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/customizer.js new file mode 100644 index 000000000..5abfe4228 --- /dev/null +++ b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/customizer.js @@ -0,0 +1,290 @@ +window.onload = function () { // wait for load in a dumb way because B-0 + var cw = '/*!\n * Bootstrap v3.0.0\n *\n * Copyright 2013 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world @twitter by @mdo and @fat.\n */\n\n' + + function showError(msg, err) { + $('
\ +
\ + ×\ +

' + msg + '

' + + (err.extract ? '
' + err.extract.join('\n') + '
' : '') + '\ +
\ +
').appendTo('body').alert() + throw err + } + + function showCallout(msg, showUpTop) { + var callout = $('
\ +

Attention!

\ +

' + msg + '

\ +
') + + if (showUpTop) { + callout.appendTo('.bs-docs-container') + } else { + callout.insertAfter('.bs-customize-download') + } + } + + function getQueryParam(key) { + key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars + var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)")); + return match && decodeURIComponent(match[1].replace(/\+/g, " ")); + } + + function createGist(configData) { + var data = { + "description": "Bootstrap Customizer Config", + "public": true, + "files": { + "config.json": { + "content": JSON.stringify(configData, null, 2) + } + } + } + $.ajax({ + url: 'https://api.github.com/gists', + type: 'POST', + dataType: 'json', + data: JSON.stringify(data) + }) + .success(function(result) { + history.replaceState(false, document.title, window.location.origin + window.location.pathname + '?id=' + result.id) + }) + .error(function(err) { + showError('Ruh roh! Could not save gist file, configuration not saved.', err) + }) + } + + function getCustomizerData() { + var vars = {} + + $('#less-variables-section input') + .each(function () { + $(this).val() && (vars[ $(this).prev().text() ] = $(this).val()) + }) + + var data = { + vars: vars, + css: $('#less-section input:checked') .map(function () { return this.value }).toArray(), + js: $('#plugin-section input:checked').map(function () { return this.value }).toArray() + } + + if ($.isEmptyObject(data.vars) && !data.css.length && !data.js.length) return + + return data + } + + function parseUrl() { + var id = getQueryParam('id') + + if (!id) return + + $.ajax({ + url: 'https://api.github.com/gists/' + id, + type: 'GET', + dataType: 'json' + }) + .success(function(result) { + var data = JSON.parse(result.files['config.json'].content) + if (data.js) { + $('#plugin-section input').each(function () { + $(this).prop('checked', ~$.inArray(this.value, data.js)) + }) + } + if (data.css) { + $('#less-section input').each(function () { + $(this).prop('checked', ~$.inArray(this.value, data.css)) + }) + } + if (data.vars) { + for (var i in data.vars) { + $('input[data-var="' + i + '"]').val(data.vars[i]) + } + } + }) + .error(function(err) { + showError('Error fetching bootstrap config file', err) + }) + } + + function generateZip(css, js, fonts, complete) { + if (!css && !js) return showError('Ruh roh! No Bootstrap files selected.', new Error('no Bootstrap')) + + var zip = new JSZip() + + if (css) { + var cssFolder = zip.folder('css') + for (var fileName in css) { + cssFolder.file(fileName, css[fileName]) + } + } + + if (js) { + var jsFolder = zip.folder('js') + for (var fileName in js) { + jsFolder.file(fileName, js[fileName]) + } + } + + if (fonts) { + var fontsFolder = zip.folder('fonts') + for (var fileName in fonts) { + fontsFolder.file(fileName, fonts[fileName]) + } + } + + var content = zip.generate({type:"blob"}) + + complete(content) + } + + function generateCustomCSS(vars) { + var result = '' + + for (var key in vars) { + result += key + ': ' + vars[key] + ';\n' + } + + return result + '\n\n' + } + + function generateFonts() { + var glyphicons = $('#less-section [value="glyphicons.less"]:checked') + if (glyphicons.length) { + return __fonts + } + } + + function generateCSS() { + var $checked = $('#less-section input:checked') + + if (!$checked.length) return false + + var result = {} + var vars = {} + var css = '' + + $('#less-variables-section input') + .each(function () { + $(this).val() && (vars[ $(this).prev().text() ] = $(this).val()) + }) + + css += __less['variables.less'] + if (vars) css += generateCustomCSS(vars) + css += __less['mixins.less'] + css += __less['normalize.less'] + css += __less['scaffolding.less'] + css += $checked + .map(function () { return __less[this.value] }) + .toArray() + .join('\n') + + css = css.replace(/@import[^\n]*/gi, '') //strip any imports + + try { + var parser = new less.Parser({ + paths: ['variables.less', 'mixins.less'] + , optimization: 0 + , filename: 'bootstrap.css' + }).parse(css, function (err, tree) { + if (err) { + return showError('Ruh roh! Could not parse less files.', err) + } + result = { + 'bootstrap.css' : cw + tree.toCSS(), + 'bootstrap.min.css' : cw + tree.toCSS({ compress: true }) + } + }) + } catch (err) { + return showError('Ruh roh! Could not parse less files.', err) + } + + return result + } + + function generateJavascript() { + var $checked = $('#plugin-section input:checked') + if (!$checked.length) return false + + var js = $checked + .map(function () { return __js[this.value] }) + .toArray() + .join('\n') + + return { + 'bootstrap.js': js, + 'bootstrap.min.js': cw + uglify(js) + } + } + + var inputsComponent = $('#less-section input') + var inputsPlugin = $('#plugin-section input') + var inputsVariables = $('#less-variables-section input') + + $('#less-section .toggle').on('click', function (e) { + e.preventDefault() + inputsComponent.prop('checked', !inputsComponent.is(':checked')) + }) + + $('#plugin-section .toggle').on('click', function (e) { + e.preventDefault() + inputsPlugin.prop('checked', !inputsPlugin.is(':checked')) + }) + + $('#less-variables-section .toggle').on('click', function (e) { + e.preventDefault() + inputsVariables.val('') + }) + + $('[data-dependencies]').on('click', function () { + if (!$(this).is(':checked')) return + var dependencies = this.getAttribute('data-dependencies') + if (!dependencies) return + dependencies = dependencies.split(',') + for (var i = 0; i < dependencies.length; i++) { + var dependency = $('[value="' + dependencies[i] + '"]') + dependency && dependency.prop('checked', true) + } + }) + + $('[data-dependents]').on('click', function () { + if ($(this).is(':checked')) return + var dependents = this.getAttribute('data-dependents') + if (!dependents) return + dependents = dependents.split(',') + for (var i = 0; i < dependents.length; i++) { + var dependent = $('[value="' + dependents[i] + '"]') + dependent && dependent.prop('checked', false) + } + }) + + var $compileBtn = $('#btn-compile') + var $downloadBtn = $('#btn-download') + + $compileBtn.on('click', function (e) { + e.preventDefault() + + $compileBtn.attr('disabled', 'disabled') + + generateZip(generateCSS(), generateJavascript(), generateFonts(), function (blob) { + $compileBtn.removeAttr('disabled') + saveAs(blob, "bootstrap.zip") + createGist(getCustomizerData()) + }) + }) + + // browser support alerts + if (!window.URL && navigator.userAgent.toLowerCase().indexOf('safari') != -1) { + showCallout("Looks like you're using safari, which sadly doesn't have the best support\ + for HTML5 blobs. Because of this your file will be downloaded with the name \"untitled\".\ + However, if you check your downloads folder, just rename this \"untitled\" file\ + to \"bootstrap.zip\" and you should be good to go!") + } else if (!window.URL && !window.webkitURL) { + $('.bs-docs-section, .bs-sidebar').css('display', 'none') + + showCallout("Looks like your current browser doesn't support the Bootstrap Customizer. Please take a second\ + to upgrade to a more modern browser.", true) + } + + parseUrl() +} diff --git a/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/filesaver.js b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/filesaver.js new file mode 100644 index 000000000..adecc88ec --- /dev/null +++ b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/filesaver.js @@ -0,0 +1,169 @@ +/* Blob.js + * A Blob implementation. + * 2013-06-20 + * + * By Eli Grey, http://eligrey.com + * By Devin Samarin, https://github.com/eboyjr + * License: X11/MIT + * See LICENSE.md + */ + +/*global self, unescape */ +/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, + plusplus: true */ + +/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ + +if (typeof Blob !== "function" || typeof URL === "undefined") +if (typeof Blob === "function" && typeof webkitURL !== "undefined") self.URL = webkitURL; +else var Blob = (function (view) { + "use strict"; + + var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) { + var + get_class = function(object) { + return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; + } + , FakeBlobBuilder = function BlobBuilder() { + this.data = []; + } + , FakeBlob = function Blob(data, type, encoding) { + this.data = data; + this.size = data.length; + this.type = type; + this.encoding = encoding; + } + , FBB_proto = FakeBlobBuilder.prototype + , FB_proto = FakeBlob.prototype + , FileReaderSync = view.FileReaderSync + , FileException = function(type) { + this.code = this[this.name = type]; + } + , file_ex_codes = ( + "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " + + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" + ).split(" ") + , file_ex_code = file_ex_codes.length + , real_URL = view.URL || view.webkitURL || view + , real_create_object_URL = real_URL.createObjectURL + , real_revoke_object_URL = real_URL.revokeObjectURL + , URL = real_URL + , btoa = view.btoa + , atob = view.atob + + , ArrayBuffer = view.ArrayBuffer + , Uint8Array = view.Uint8Array + ; + FakeBlob.fake = FB_proto.fake = true; + while (file_ex_code--) { + FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; + } + if (!real_URL.createObjectURL) { + URL = view.URL = {}; + } + URL.createObjectURL = function(blob) { + var + type = blob.type + , data_URI_header + ; + if (type === null) { + type = "application/octet-stream"; + } + if (blob instanceof FakeBlob) { + data_URI_header = "data:" + type; + if (blob.encoding === "base64") { + return data_URI_header + ";base64," + blob.data; + } else if (blob.encoding === "URI") { + return data_URI_header + "," + decodeURIComponent(blob.data); + } if (btoa) { + return data_URI_header + ";base64," + btoa(blob.data); + } else { + return data_URI_header + "," + encodeURIComponent(blob.data); + } + } else if (real_create_object_URL) { + return real_create_object_URL.call(real_URL, blob); + } + }; + URL.revokeObjectURL = function(object_URL) { + if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { + real_revoke_object_URL.call(real_URL, object_URL); + } + }; + FBB_proto.append = function(data/*, endings*/) { + var bb = this.data; + // decode data to a binary string + if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { + var + str = "" + , buf = new Uint8Array(data) + , i = 0 + , buf_len = buf.length + ; + for (; i < buf_len; i++) { + str += String.fromCharCode(buf[i]); + } + bb.push(str); + } else if (get_class(data) === "Blob" || get_class(data) === "File") { + if (FileReaderSync) { + var fr = new FileReaderSync; + bb.push(fr.readAsBinaryString(data)); + } else { + // async FileReader won't work as BlobBuilder is sync + throw new FileException("NOT_READABLE_ERR"); + } + } else if (data instanceof FakeBlob) { + if (data.encoding === "base64" && atob) { + bb.push(atob(data.data)); + } else if (data.encoding === "URI") { + bb.push(decodeURIComponent(data.data)); + } else if (data.encoding === "raw") { + bb.push(data.data); + } + } else { + if (typeof data !== "string") { + data += ""; // convert unsupported types to strings + } + // decode UTF-16 to binary string + bb.push(unescape(encodeURIComponent(data))); + } + }; + FBB_proto.getBlob = function(type) { + if (!arguments.length) { + type = null; + } + return new FakeBlob(this.data.join(""), type, "raw"); + }; + FBB_proto.toString = function() { + return "[object BlobBuilder]"; + }; + FB_proto.slice = function(start, end, type) { + var args = arguments.length; + if (args < 3) { + type = null; + } + return new FakeBlob( + this.data.slice(start, args > 1 ? end : this.data.length) + , type + , this.encoding + ); + }; + FB_proto.toString = function() { + return "[object Blob]"; + }; + return FakeBlobBuilder; + }(view)); + + return function Blob(blobParts, options) { + var type = options ? (options.type || "") : ""; + var builder = new BlobBuilder(); + if (blobParts) { + for (var i = 0, len = blobParts.length; i < len; i++) { + builder.append(blobParts[i]); + } + } + return builder.getBlob(type); + }; +}(self)); + +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ +var saveAs=saveAs||(navigator.msSaveOrOpenBlob&&navigator.msSaveOrOpenBlob.bind(navigator))||(function(h){"use strict";var r=h.document,l=function(){return h.URL||h.webkitURL||h},e=h.URL||h.webkitURL||h,n=r.createElementNS("http://www.w3.org/1999/xhtml","a"),g=!h.externalHost&&"download" in n,j=function(t){var s=r.createEvent("MouseEvents");s.initMouseEvent("click",true,false,h,0,0,0,0,0,false,false,false,false,0,null);t.dispatchEvent(s)},o=h.webkitRequestFileSystem,p=h.requestFileSystem||o||h.mozRequestFileSystem,m=function(s){(h.setImmediate||h.setTimeout)(function(){throw s},0)},c="application/octet-stream",k=0,b=[],i=function(){var t=b.length;while(t--){var s=b[t];if(typeof s==="string"){e.revokeObjectURL(s)}else{s.remove()}}b.length=0},q=function(t,s,w){s=[].concat(s);var v=s.length;while(v--){var x=t["on"+s[v]];if(typeof x==="function"){try{x.call(t,w||t)}catch(u){m(u)}}}},f=function(t,u){var v=this,B=t.type,E=false,x,w,s=function(){var F=l().createObjectURL(t);b.push(F);return F},A=function(){q(v,"writestart progress write writeend".split(" "))},D=function(){if(E||!x){x=s(t)}if(w){w.location.href=x}else{window.open(x,"_blank")}v.readyState=v.DONE;A()},z=function(F){return function(){if(v.readyState!==v.DONE){return F.apply(this,arguments)}}},y={create:true,exclusive:false},C;v.readyState=v.INIT;if(!u){u="download"}if(g){x=s(t);n.href=x;n.download=u;j(n);v.readyState=v.DONE;A();return}if(h.chrome&&B&&B!==c){C=t.slice||t.webkitSlice;t=C.call(t,0,t.size,c);E=true}if(o&&u!=="download"){u+=".download"}if(B===c||o){w=h}if(!p){D();return}k+=t.size;p(h.TEMPORARY,k,z(function(F){F.root.getDirectory("saved",y,z(function(G){var H=function(){G.getFile(u,y,z(function(I){I.createWriter(z(function(J){J.onwriteend=function(K){w.location.href=I.toURL();b.push(I);v.readyState=v.DONE;q(v,"writeend",K)};J.onerror=function(){var K=J.error;if(K.code!==K.ABORT_ERR){D()}};"writestart progress write abort".split(" ").forEach(function(K){J["on"+K]=v["on"+K]});J.write(t);v.abort=function(){J.abort();v.readyState=v.DONE};v.readyState=v.WRITING}),D)}),D)};G.getFile(u,{create:false},z(function(I){I.remove();H()}),z(function(I){if(I.code===I.NOT_FOUND_ERR){H()}else{D()}}))}),D)}),D)},d=f.prototype,a=function(s,t){return new f(s,t)};d.abort=function(){var s=this;s.readyState=s.DONE;q(s,"abort")};d.readyState=d.INIT=0;d.WRITING=1;d.DONE=2;d.error=d.onwritestart=d.onprogress=d.onwrite=d.onabort=d.onerror=d.onwriteend=null;h.addEventListener("unload",i,false);return a}(self)); \ No newline at end of file diff --git a/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/holder.js b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/holder.js new file mode 100644 index 000000000..f717054c3 --- /dev/null +++ b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/holder.js @@ -0,0 +1,419 @@ +/* + +Holder - 2.0 - client side image placeholders +(c) 2012-2013 Ivan Malopinsky / http://imsky.co + +Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0 +Commercial use requires attribution. + +*/ + +var Holder = Holder || {}; +(function (app, win) { + +var preempted = false, +fallback = false, +canvas = document.createElement('canvas'); + +//getElementsByClassName polyfill +document.getElementsByClassName||(document.getElementsByClassName=function(e){var t=document,n,r,i,s=[];if(t.querySelectorAll)return t.querySelectorAll("."+e);if(t.evaluate){r=".//*[contains(concat(' ', @class, ' '), ' "+e+" ')]",n=t.evaluate(r,t,null,0,null);while(i=n.iterateNext())s.push(i)}else{n=t.getElementsByTagName("*"),r=new RegExp("(^|\\s)"+e+"(\\s|$)");for(i=0;i= 0.75) { + text_height = Math.floor(text_height * 0.75 * (width/text_width)); + } + //Resetting font size if necessary + ctx.font = "bold " + (text_height * ratio) + "px " + font; + ctx.fillText(text, (width / 2), (height / 2), width); + return canvas.toDataURL("image/png"); +} + +function render(mode, el, holder, src) { + var dimensions = holder.dimensions, + theme = holder.theme, + text = holder.text ? decodeURIComponent(holder.text) : holder.text; + var dimensions_caption = dimensions.width + "x" + dimensions.height; + theme = (text ? extend(theme, { + text: text + }) : theme); + theme = (holder.font ? extend(theme, { + font: holder.font + }) : theme); + if (mode == "image") { + el.setAttribute("data-src", src); + el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption); + if (fallback || !holder.auto) { + el.style.width = dimensions.width + "px"; + el.style.height = dimensions.height + "px"; + } + if (fallback) { + el.style.backgroundColor = theme.background; + } else { + el.setAttribute("src", draw(ctx, dimensions, theme, ratio)); + } + } else if (mode == "background") { + if (!fallback) { + el.style.backgroundImage = "url(" + draw(ctx, dimensions, theme, ratio) + ")"; + el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px"; + } + } else if (mode == "fluid") { + el.setAttribute("data-src", src); + el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption); + if (dimensions.height.substr(-1) == "%") { + el.style.height = dimensions.height + } else { + el.style.height = dimensions.height + "px" + } + if (dimensions.width.substr(-1) == "%") { + el.style.width = dimensions.width + } else { + el.style.width = dimensions.width + "px" + } + if (el.style.display == "inline" || el.style.display == "") { + el.style.display = "block"; + } + if (fallback) { + el.style.backgroundColor = theme.background; + } else { + el.holderData = holder; + fluid_images.push(el); + fluid_update(el); + } + } +}; + +function fluid_update(element) { + var images; + if (element.nodeType == null) { + images = fluid_images; + } else { + images = [element] + } + for (i in images) { + var el = images[i] + if (el.holderData) { + var holder = el.holderData; + el.setAttribute("src", draw(ctx, { + height: el.clientHeight, + width: el.clientWidth + }, holder.theme, ratio)); + } + } +} + +function parse_flags(flags, options) { + + var ret = { + theme: settings.themes.gray + }, render = false; + + for (sl = flags.length, j = 0; j < sl; j++) { + var flag = flags[j]; + if (app.flags.dimensions.match(flag)) { + render = true; + ret.dimensions = app.flags.dimensions.output(flag); + } else if (app.flags.fluid.match(flag)) { + render = true; + ret.dimensions = app.flags.fluid.output(flag); + ret.fluid = true; + } else if (app.flags.colors.match(flag)) { + ret.theme = app.flags.colors.output(flag); + } else if (options.themes[flag]) { + //If a theme is specified, it will override custom colors + ret.theme = options.themes[flag]; + } else if (app.flags.text.match(flag)) { + ret.text = app.flags.text.output(flag); + } else if (app.flags.font.match(flag)) { + ret.font = app.flags.font.output(flag); + } else if (app.flags.auto.match(flag)) { + ret.auto = true; + } + } + + return render ? ret : false; + +}; + + + +if (!canvas.getContext) { + fallback = true; +} else { + if (canvas.toDataURL("image/png") + .indexOf("data:image/png") < 0) { + //Android doesn't support data URI + fallback = true; + } else { + var ctx = canvas.getContext("2d"); + } +} + +var dpr = 1, bsr = 1; + +if(!fallback){ + dpr = window.devicePixelRatio || 1, + bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; +} + +var ratio = dpr / bsr; + +var fluid_images = []; + +var settings = { + domain: "holder.js", + images: "img", + bgnodes: ".holderjs", + themes: { + "gray": { + background: "#eee", + foreground: "#aaa", + size: 12 + }, + "social": { + background: "#3a5a97", + foreground: "#fff", + size: 12 + }, + "industrial": { + background: "#434A52", + foreground: "#C2F200", + size: 12 + } + }, + stylesheet: ".holderjs-fluid {font-size:16px;font-weight:bold;text-align:center;font-family:sans-serif;margin:0}" +}; + + +app.flags = { + dimensions: { + regex: /^(\d+)x(\d+)$/, + output: function (val) { + var exec = this.regex.exec(val); + return { + width: +exec[1], + height: +exec[2] + } + } + }, + fluid: { + regex: /^([0-9%]+)x([0-9%]+)$/, + output: function (val) { + var exec = this.regex.exec(val); + return { + width: exec[1], + height: exec[2] + } + } + }, + colors: { + regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i, + output: function (val) { + var exec = this.regex.exec(val); + return { + size: settings.themes.gray.size, + foreground: "#" + exec[2], + background: "#" + exec[1] + } + } + }, + text: { + regex: /text\:(.*)/, + output: function (val) { + return this.regex.exec(val)[1]; + } + }, + font: { + regex: /font\:(.*)/, + output: function (val) { + return this.regex.exec(val)[1]; + } + }, + auto: { + regex: /^auto$/ + } +} + +for (var flag in app.flags) { + if (!app.flags.hasOwnProperty(flag)) continue; + app.flags[flag].match = function (val) { + return val.match(this.regex) + } +} + +app.add_theme = function (name, theme) { + name != null && theme != null && (settings.themes[name] = theme); + return app; +}; + +app.add_image = function (src, el) { + var node = selector(el); + if (node.length) { + for (var i = 0, l = node.length; i < l; i++) { + var img = document.createElement("img") + img.setAttribute("data-src", src); + node[i].appendChild(img); + } + } + return app; +}; + +app.run = function (o) { + var options = extend(settings, o), + images = [], imageNodes = [], bgnodes = []; + + if(typeof(options.images) == "string"){ + imageNodes = selector(options.images); + } + else if (window.NodeList && options.images instanceof window.NodeList) { + imageNodes = options.images; + } else if (window.Node && options.images instanceof window.Node) { + imageNodes = [options.images]; + } + + if(typeof(options.bgnodes) == "string"){ + bgnodes = selector(options.bgnodes); + } else if (window.NodeList && options.elements instanceof window.NodeList) { + bgnodes = options.bgnodes; + } else if (window.Node && options.bgnodes instanceof window.Node) { + bgnodes = [options.bgnodes]; + } + + preempted = true; + + for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]); + + var holdercss = document.getElementById("holderjs-style"); + if (!holdercss) { + holdercss = document.createElement("style"); + holdercss.setAttribute("id", "holderjs-style"); + holdercss.type = "text/css"; + document.getElementsByTagName("head")[0].appendChild(holdercss); + } + + if (!options.nocss) { + if (holdercss.styleSheet) { + holdercss.styleSheet.cssText += options.stylesheet; + } else { + holdercss.appendChild(document.createTextNode(options.stylesheet)); + } + } + + var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)"); + + for (var l = bgnodes.length, i = 0; i < l; i++) { + var src = window.getComputedStyle(bgnodes[i], null) + .getPropertyValue("background-image"); + var flags = src.match(cssregex); + var bgsrc = bgnodes[i].getAttribute("data-background-src"); + + if (flags) { + var holder = parse_flags(flags[1].split("/"), options); + if (holder) { + render("background", bgnodes[i], holder, src); + } + } + else if(bgsrc != null){ + var holder = parse_flags(bgsrc.substr(bgsrc.lastIndexOf(options.domain) + options.domain.length + 1) + .split("/"), options); + if(holder){ + render("background", bgnodes[i], holder, src); + } + } + } + + for (l = images.length, i = 0; i < l; i++) { + + var attr_src = attr_data_src = src = null; + + try{ + attr_src = images[i].getAttribute("src"); + attr_datasrc = images[i].getAttribute("data-src"); + }catch(e){} + + if (attr_datasrc == null && !! attr_src && attr_src.indexOf(options.domain) >= 0) { + src = attr_src; + } else if ( !! attr_datasrc && attr_datasrc.indexOf(options.domain) >= 0) { + src = attr_datasrc; + } + + if (src) { + var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1) + .split("/"), options); + if (holder) { + if (holder.fluid) { + render("fluid", images[i], holder, src) + } else { + render("image", images[i], holder, src); + } + } + } + } + return app; +}; + +contentLoaded(win, function () { + if (window.addEventListener) { + window.addEventListener("resize", fluid_update, false); + window.addEventListener("orientationchange", fluid_update, false); + } else { + window.attachEvent("onresize", fluid_update) + } + preempted || app.run(); +}); + +if (typeof define === "function" && define.amd) { + define("Holder", [], function () { + return app; + }); +} + +})(Holder, window); diff --git a/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/html5shiv.js b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/html5shiv.js new file mode 100644 index 000000000..784f221ca --- /dev/null +++ b/docs/system-architecture/js/vendor/bootstrap-3.0.0/assets/html5shiv.js @@ -0,0 +1,8 @@ +/* + HTML5 Shiv v3.6.2pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); +a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; +c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| +"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",version:"3.6.2pre",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); +for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="
",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
a",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="
t
",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t +}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X
","
"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle); +u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("