diff --git a/.jazzy.yaml b/.jazzy.yaml
index fc6e1630a0..d087c50219 100644
--- a/.jazzy.yaml
+++ b/.jazzy.yaml
@@ -1,7 +1,41 @@
-clean: true
+module: Adyen
author: Adyen
author_url: https://adyen.com
-github_url: https://github.com/Adyen
+github_url: https://github.com/Adyen/adyen-ios
+
+output: Docs
+
+theme: fullwidth
skip_undocumented: false
hide_documentation_coverage: true
-theme: fullwidth
+
+custom_categories:
+ - name: UI
+ children:
+ - CheckoutViewController
+ - CheckoutViewControllerDelegate
+ - AppearanceConfiguration
+ - name: Payment
+ children:
+ - Payment
+ - PaymentStatus
+ - name: Payment Request
+ children:
+ - PaymentRequest
+ - PaymentRequestDelegate
+ - PaymentRequestResult
+ - Error
+ - name: Payment Method
+ children:
+ - PaymentMethod
+ - PaymentDetails
+ - InputDetail
+ - InputType
+ - InputSelectItem
+ - name: Utilities
+ children:
+ - CardType
+ - CardValidator
+ - IBANSpecification
+ - IBANValidator
+ - IBANTextField
diff --git a/Example/1-quick-integration-example/.swiftlint.yml b/.swiftlint.yml
similarity index 73%
rename from Example/1-quick-integration-example/.swiftlint.yml
rename to .swiftlint.yml
index cbcd8b8256..988103840a 100644
--- a/Example/1-quick-integration-example/.swiftlint.yml
+++ b/.swiftlint.yml
@@ -11,9 +11,8 @@ disabled_rules:
- function_body_length
- file_length
included:
- - ../../Adyen
- - ../../Example
- - ../../UnitTests
+ - Adyen
+ - Examples
+ - AdyenTests
excluded:
- Pods
- - ../../Adyen/Core/Config.swift
diff --git a/.travis.yml b/.travis.yml
index 0fea8e5018..9208ad8a28 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,16 +4,16 @@ osx_image: xcode8.3
env:
global:
- - WORKSPACE="Example/1-quick-integration-example/ShoppingApp.xcworkspace"
- - SCHEME="ShoppingApp"
+ - WORKSPACE="Adyen.xcworkspace"
+ - SCHEME="Adyen"
- DESTINATION="platform=iOS Simulator,name=iPhone 7,OS=10.3"
before_install:
- gem install cocoapods
- pod repo update
- - (cd Example/1-quick-integration-example && pod install)
+ - pod install
script:
- - (cd Example/1-quick-integration-example && ./Pods/SwiftLint/swiftlint)
+ - ./Pods/SwiftLint/swiftlint
- pod lib lint
- xcodebuild test -workspace "${WORKSPACE}" -scheme "${SCHEME}" -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -destination "${DESTINATION}" | xcpretty -s && exit ${PIPESTATUS[0]}
diff --git a/Adyen.podspec b/Adyen.podspec
index e21ea48277..bd097fe516 100644
--- a/Adyen.podspec
+++ b/Adyen.podspec
@@ -1,6 +1,8 @@
+version = `agvtool vers -terse`
+
Pod::Spec.new do |s|
s.name = 'Adyen'
- s.version = File.read('VERSION')
+ s.version = version
s.summary = "Adyen SDK for iOS"
s.description = <<-DESC
With Adyen SDK you can dynamically list all relevant payment methods for a specific transaction, so your shoppers can always pay with the method of their choice. The methods are listed based on the shopper's country, the transaction currency and amount.
@@ -14,11 +16,10 @@ Pod::Spec.new do |s|
s.ios.deployment_target = '9.0'
s.frameworks = 'Foundation'
- s.default_subspecs = 'Core', 'Cards', 'Ideal', 'UI'
+ s.default_subspecs = 'Core', 'Cards', 'Ideal', 'SEPADirectDebit', 'UI'
s.subspec 'Core' do |plugin|
plugin.source_files = 'Adyen/Core/**/*'
- plugin.resources = ['VERSION']
end
# Payment Methods
@@ -46,6 +47,17 @@ Pod::Spec.new do |s|
plugin.dependency 'Adyen/Core'
end
+ s.subspec 'SEPADirectDebit' do |plugin|
+ plugin.source_files = 'Adyen/Plugins/SEPADirectDebit/**/*'
+ plugin.dependency 'Adyen/Core'
+ plugin.dependency 'Adyen/CoreUI'
+ plugin.resource_bundles = {
+ 'SEPADirectDebit' => [
+ 'Adyen/Plugins/SEPADirectDebit/**/*.xib'
+ ]
+ }
+ end
+
# Internals
s.subspec 'UI' do |plugin|
plugin.source_files = 'Adyen/UI/**/*'
@@ -55,7 +67,12 @@ Pod::Spec.new do |s|
s.subspec 'CoreUI' do |plugin|
plugin.source_files = 'Adyen/CoreUI/**/*.swift'
- plugin.resources = ['Adyen/CoreUI/Assets/Media.xcassets']
+ plugin.resource_bundles = {
+ 'CoreUI' => [
+ 'Adyen/CoreUI/Assets/Media.xcassets',
+ 'Adyen/CoreUI/Assets/*.lproj/*.strings'
+ ]
+ }
plugin.dependency 'Adyen/Core'
end
end
diff --git a/Adyen.xcodeproj/project.pbxproj b/Adyen.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..fb9686f285
--- /dev/null
+++ b/Adyen.xcodeproj/project.pbxproj
@@ -0,0 +1,1463 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 53C0FEFC4B5CD9400E89E4CA /* Pods_AdyenTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3BE1722DC859E029DDBCF09 /* Pods_AdyenTests.framework */; };
+ 7D7AD12FB4E950056731EEB6 /* Pods_Adyen.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B7AEC312DF920BCC1C4BC1C0 /* Pods_Adyen.framework */; };
+ C3A02E02B25D9A9E913FA639 /* Pods_AdyenUIHost.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36FCC0F6EB491A052CC61D81 /* Pods_AdyenUIHost.framework */; };
+ E20AD01A1EFAB0310065B70E /* Adyen.h in Headers */ = {isa = PBXBuildFile; fileRef = E20AD00C1EFAB0310065B70E /* Adyen.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ E20AD0691EFAB0E00065B70E /* BasePlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0241EFAB0E00065B70E /* BasePlugin.swift */; };
+ E20AD06A1EFAB0E00065B70E /* Currency.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0251EFAB0E00065B70E /* Currency.swift */; };
+ E20AD06B1EFAB0E00065B70E /* CardBrandCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0271EFAB0E00065B70E /* CardBrandCode.swift */; };
+ E20AD06C1EFAB0E00065B70E /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0281EFAB0E00065B70E /* Error.swift */; };
+ E20AD06D1EFAB0E00065B70E /* InputType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0291EFAB0E00065B70E /* InputType.swift */; };
+ E20AD06E1EFAB0E00065B70E /* MethodRequiresPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02A1EFAB0E00065B70E /* MethodRequiresPlugin.swift */; };
+ E20AD06F1EFAB0E00065B70E /* PaymentMethodType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02B1EFAB0E00065B70E /* PaymentMethodType.swift */; };
+ E20AD0701EFAB0E00065B70E /* PaymentRequestResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02C1EFAB0E00065B70E /* PaymentRequestResult.swift */; };
+ E20AD0711EFAB0E00065B70E /* PaymentStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02D1EFAB0E00065B70E /* PaymentStatus.swift */; };
+ E20AD0721EFAB0E00065B70E /* ArrayExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD02F1EFAB0E00065B70E /* ArrayExtensions.swift */; };
+ E20AD0731EFAB0E00065B70E /* BoolExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0301EFAB0E00065B70E /* BoolExtensions.swift */; };
+ E20AD0741EFAB0E00065B70E /* DictionaryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0311EFAB0E00065B70E /* DictionaryExtensions.swift */; };
+ E20AD0751EFAB0E00065B70E /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0321EFAB0E00065B70E /* StringExtensions.swift */; };
+ E20AD0761EFAB0E00065B70E /* UIScreenExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0331EFAB0E00065B70E /* UIScreenExtensions.swift */; };
+ E20AD0771EFAB0E00065B70E /* URLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0341EFAB0E00065B70E /* URLExtensions.swift */; };
+ E20AD0781EFAB0E00065B70E /* InputDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0351EFAB0E00065B70E /* InputDetail.swift */; };
+ E20AD0791EFAB0E00065B70E /* InputSelectItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0361EFAB0E00065B70E /* InputSelectItem.swift */; };
+ E20AD07A1EFAB0E00065B70E /* InternalPaymentRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0371EFAB0E00065B70E /* InternalPaymentRequest.swift */; };
+ E20AD07B1EFAB0E00065B70E /* Payment.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0381EFAB0E00065B70E /* Payment.swift */; };
+ E20AD07C1EFAB0E00065B70E /* PaymentDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0391EFAB0E00065B70E /* PaymentDetails.swift */; };
+ E20AD07D1EFAB0E00065B70E /* PaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD03A1EFAB0E00065B70E /* PaymentMethod.swift */; };
+ E20AD07F1EFAB0E00065B70E /* PaymentRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD03C1EFAB0E00065B70E /* PaymentRequest.swift */; };
+ E20AD0801EFAB0E00065B70E /* PaymentServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD03D1EFAB0E00065B70E /* PaymentServer.swift */; };
+ E20AD0811EFAB0E00065B70E /* PluginLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD03E1EFAB0E00065B70E /* PluginLoader.swift */; };
+ E20AD0821EFAB0E00065B70E /* DeviceDependable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0401EFAB0E00065B70E /* DeviceDependable.swift */; };
+ E20AD0841EFAB0E00065B70E /* PaymentRequestDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0421EFAB0E00065B70E /* PaymentRequestDelegate.swift */; };
+ E20AD0851EFAB0E00065B70E /* RequiresFinalState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0431EFAB0E00065B70E /* RequiresFinalState.swift */; };
+ E20AD0871EFAB0E00065B70E /* Version.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0451EFAB0E00065B70E /* Version.swift */; };
+ E20AD0891EFAB0E00065B70E /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0491EFAB0E00065B70E /* Media.xcassets */; };
+ E20AD08A1EFAB0E00065B70E /* CheckoutButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04A1EFAB0E00065B70E /* CheckoutButton.swift */; };
+ E20AD08B1EFAB0E00065B70E /* LoadingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04B1EFAB0E00065B70E /* LoadingTableViewCell.swift */; };
+ E20AD08C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift */; };
+ E20AD08D1EFAB0E00065B70E /* UIColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04D1EFAB0E00065B70E /* UIColorExtensions.swift */; };
+ E20AD08E1EFAB0E00065B70E /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04E1EFAB0E00065B70E /* UIImageExtensions.swift */; };
+ E20AD08F1EFAB0E00065B70E /* UIImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD04F1EFAB0E00065B70E /* UIImageViewExtensions.swift */; };
+ E20AD0901EFAB0E00065B70E /* ApplePayDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0521EFAB0E00065B70E /* ApplePayDetailsPresenter.swift */; };
+ E20AD0911EFAB0E00065B70E /* ApplePayPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0531EFAB0E00065B70E /* ApplePayPlugin.swift */; };
+ E20AD0921EFAB0E00065B70E /* CardFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0551EFAB0E00065B70E /* CardFormViewController.swift */; };
+ E20AD0931EFAB0E00065B70E /* CardFormViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0561EFAB0E00065B70E /* CardFormViewController.xib */; };
+ E20AD0941EFAB0E00065B70E /* CardPaymentFieldManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0571EFAB0E00065B70E /* CardPaymentFieldManager.swift */; };
+ E20AD0951EFAB0E00065B70E /* CardType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0581EFAB0E00065B70E /* CardType.swift */; };
+ E20AD0961EFAB0E00065B70E /* CardValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0591EFAB0E00065B70E /* CardValidator.swift */; };
+ E20AD0971EFAB0E00065B70E /* CardsAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05A1EFAB0E00065B70E /* CardsAlertController.swift */; };
+ E20AD0981EFAB0E00065B70E /* CardsDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05B1EFAB0E00065B70E /* CardsDetailsPresenter.swift */; };
+ E20AD0991EFAB0E00065B70E /* CardsPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05C1EFAB0E00065B70E /* CardsPlugin.swift */; };
+ E20AD09A1EFAB0E00065B70E /* CheckoutTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05D1EFAB0E00065B70E /* CheckoutTextField.swift */; };
+ E20AD09B1EFAB0E00065B70E /* IdealDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD05F1EFAB0E00065B70E /* IdealDetailsPresenter.swift */; };
+ E20AD09C1EFAB0E00065B70E /* IdealIssuerPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0601EFAB0E00065B70E /* IdealIssuerPickerViewController.swift */; };
+ E20AD09D1EFAB0E00065B70E /* IdealPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0611EFAB0E00065B70E /* IdealPlugin.swift */; };
+ E20AD09E1EFAB0E00065B70E /* CheckoutHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0631EFAB0E00065B70E /* CheckoutHeaderView.swift */; };
+ E20AD09F1EFAB0E00065B70E /* CheckoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0641EFAB0E00065B70E /* CheckoutViewController.swift */; };
+ E20AD0A01EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0651EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift */; };
+ E20AD0BD1EFAB1950065B70E /* CardValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0A51EFAB1950065B70E /* CardValidatorTests.swift */; };
+ E20AD0BE1EFAB1950065B70E /* ArrayExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0A71EFAB1950065B70E /* ArrayExtensionTests.swift */; };
+ E20AD0BF1EFAB1950065B70E /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0A81EFAB1950065B70E /* BoolExtensionsTests.swift */; };
+ E20AD0C01EFAB1950065B70E /* CurrencyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0A91EFAB1950065B70E /* CurrencyTests.swift */; };
+ E20AD0C11EFAB1950065B70E /* DictionaryExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AA1EFAB1950065B70E /* DictionaryExtensionTests.swift */; };
+ E20AD0C21EFAB1950065B70E /* InputDetailsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AB1EFAB1950065B70E /* InputDetailsTests.swift */; };
+ E20AD0C31EFAB1950065B70E /* InputSelectItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AC1EFAB1950065B70E /* InputSelectItemTests.swift */; };
+ E20AD0C41EFAB1950065B70E /* PaymentDetailsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AD1EFAB1950065B70E /* PaymentDetailsTests.swift */; };
+ E20AD0C51EFAB1950065B70E /* PaymentMethodTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AE1EFAB1950065B70E /* PaymentMethodTests.swift */; };
+ E20AD0C61EFAB1950065B70E /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0AF1EFAB1950065B70E /* StringExtensionsTests.swift */; };
+ E20AD0C71EFAB1950065B70E /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0B01EFAB1950065B70E /* URLExtensionsTests.swift */; };
+ E20AD0C91EFAB1950065B70E /* PaymentMethodApplePay.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B51EFAB1950065B70E /* PaymentMethodApplePay.json */; };
+ E20AD0CA1EFAB1950065B70E /* PaymentMethodCard.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B61EFAB1950065B70E /* PaymentMethodCard.json */; };
+ E20AD0CB1EFAB1950065B70E /* PaymentMethodCardCvc.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B71EFAB1950065B70E /* PaymentMethodCardCvc.json */; };
+ E20AD0CC1EFAB1950065B70E /* PaymentMethodIdeal.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B81EFAB1950065B70E /* PaymentMethodIdeal.json */; };
+ E20AD0CD1EFAB1950065B70E /* PaymentMethodKlarna.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0B91EFAB1950065B70E /* PaymentMethodKlarna.json */; };
+ E20AD0CE1EFAB1950065B70E /* PaymentMethodPaypal.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0BA1EFAB1950065B70E /* PaymentMethodPaypal.json */; };
+ E20AD0CF1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0BB1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json */; };
+ E20AD0D01EFAB1950065B70E /* PaymentMethodSepa.json in Resources */ = {isa = PBXBuildFile; fileRef = E20AD0BC1EFAB1950065B70E /* PaymentMethodSepa.json */; };
+ E20AD0D31EFAB1BF0065B70E /* JsonReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD0D21EFAB1BF0065B70E /* JsonReader.swift */; };
+ E226F1491EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = E226F1481EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift */; };
+ E240E7531F0BC5600059FA0E /* UITableViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E240E7521F0BC5600059FA0E /* UITableViewControllerExtensions.swift */; };
+ E250E13F1F0E606000BFFF2F /* Adyen.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E20AD0091EFAB0310065B70E /* Adyen.framework */; };
+ E250E1401F0E606000BFFF2F /* Adyen.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E20AD0091EFAB0310065B70E /* Adyen.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ E255C4021F0103DF0075254F /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E255C4011F0103DF0075254F /* NavigationController.swift */; };
+ E25A3FC11F0686F800679DCD /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F627661F063849005D8026 /* Localization.swift */; };
+ E25C87A61F0B81FC00FF3EA0 /* PaymentMethodPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25C87A51F0B81F300FF3EA0 /* PaymentMethodPickerViewController.swift */; };
+ E25C87A71F0B81FF00FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25C87A41F0B81F300FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift */; };
+ E28562591F0FC06F0049E442 /* BundleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28562581F0FC06F0049E442 /* BundleExtensions.swift */; };
+ E28562641F13BA5D0049E442 /* PaymentStatusTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28562631F13BA5D0049E442 /* PaymentStatusTests.swift */; };
+ E28A79991EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28A79981EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift */; };
+ E28A799C1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28A799A1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift */; };
+ E28A799D1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E28A799B1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib */; };
+ E28A799F1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28A799E1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift */; };
+ E2A167C31F0E643A00A27E4A /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2A167C21F0E643A00A27E4A /* Configuration.swift */; };
+ E2A167C61F0E704100A27E4A /* Adyen.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E20AD0091EFAB0310065B70E /* Adyen.framework */; };
+ E2B6207D1F0E5EA5001D4C27 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E2B6207C1F0E5EA5001D4C27 /* Main.storyboard */; };
+ E2B6207F1F0E5F0F001D4C27 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E2B6207E1F0E5F0F001D4C27 /* LaunchScreen.storyboard */; };
+ E2BF6CCD1F0395670065E574 /* TestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CCC1F0395670065E574 /* TestCase.swift */; };
+ E2BF6CCF1F0397060065E574 /* SEPADirectDebitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CCE1F0397060065E574 /* SEPADirectDebitTests.swift */; };
+ E2BF6CD11F0397AC0065E574 /* XCUIElementQueryExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CD01F0397AC0065E574 /* XCUIElementQueryExtensions.swift */; };
+ E2BF6CD31F03A8240065E574 /* CardsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CD21F03A8240065E574 /* CardsTests.swift */; };
+ E2BF6CD71F03CEF60065E574 /* IdealTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BF6CD61F03CEF60065E574 /* IdealTests.swift */; };
+ E2E9D01E1F0389C80056E0AC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2E9D01D1F0389C80056E0AC /* AppDelegate.swift */; };
+ E2E9D0201F0389C80056E0AC /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2E9D01F1F0389C80056E0AC /* ViewController.swift */; };
+ E2E9D0251F0389C80056E0AC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E2E9D0241F0389C80056E0AC /* Assets.xcassets */; };
+ E2EE2E4B1F0141CD008DC96D /* IBANValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EE2E4A1F0141CD008DC96D /* IBANValidatorTests.swift */; };
+ E2EE2E541F026746008DC96D /* IBANSpecification.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EE2E511F026746008DC96D /* IBANSpecification.swift */; };
+ E2EE2E551F026746008DC96D /* IBANTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EE2E521F026746008DC96D /* IBANTextField.swift */; };
+ E2EE2E561F026746008DC96D /* IBANValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EE2E531F026746008DC96D /* IBANValidator.swift */; };
+ E2F627681F06386C005D8026 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E2F627651F063842005D8026 /* Localizable.strings */; };
+ E2F6276E1F06413B005D8026 /* UIPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F6276D1F064127005D8026 /* UIPresentable.swift */; };
+ E2F6276F1F06413D005D8026 /* PaymentMethodDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F6276C1F064127005D8026 /* PaymentMethodDetailsPresenter.swift */; };
+ E2F627701F064270005D8026 /* AppearanceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F627691F063B5D005D8026 /* AppearanceConfiguration.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ E20AD0141EFAB0310065B70E /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = E20AD0001EFAB0310065B70E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = E20AD0081EFAB0310065B70E;
+ remoteInfo = Adyen;
+ };
+ E250E1411F0E606000BFFF2F /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = E20AD0001EFAB0310065B70E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = E20AD0081EFAB0310065B70E;
+ remoteInfo = Adyen;
+ };
+ E2BF6CC61F03952D0065E574 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = E20AD0001EFAB0310065B70E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = E2E9D01A1F0389C80056E0AC;
+ remoteInfo = AdyenUIHost;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ E250E1431F0E606000BFFF2F /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ E250E1401F0E606000BFFF2F /* Adyen.framework in Embed Frameworks */,
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 20191199750F47C401152B90 /* Pods-Adyen.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Adyen.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Adyen/Pods-Adyen.debug.xcconfig"; sourceTree = ""; };
+ 36FCC0F6EB491A052CC61D81 /* Pods_AdyenUIHost.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AdyenUIHost.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 39B692648B2F9A2E64860876 /* Pods-Adyen.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Adyen.release.xcconfig"; path = "Pods/Target Support Files/Pods-Adyen/Pods-Adyen.release.xcconfig"; sourceTree = ""; };
+ 4D2C0B04986E87ADFBF3FD11 /* Pods-AdyenUIHost.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AdyenUIHost.release.xcconfig"; path = "Pods/Target Support Files/Pods-AdyenUIHost/Pods-AdyenUIHost.release.xcconfig"; sourceTree = ""; };
+ 7370242B72CA01D6FB771E34 /* Pods-AdyenTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AdyenTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AdyenTests/Pods-AdyenTests.debug.xcconfig"; sourceTree = ""; };
+ 9D45EFB0559159A56AFB2ED0 /* Pods-AdyenUIHost.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AdyenUIHost.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AdyenUIHost/Pods-AdyenUIHost.debug.xcconfig"; sourceTree = ""; };
+ B7AEC312DF920BCC1C4BC1C0 /* Pods_Adyen.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Adyen.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ D3BE1722DC859E029DDBCF09 /* Pods_AdyenTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AdyenTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ E20AD0091EFAB0310065B70E /* Adyen.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Adyen.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ E20AD00C1EFAB0310065B70E /* Adyen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Adyen.h; sourceTree = ""; };
+ E20AD00D1EFAB0310065B70E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ E20AD0121EFAB0310065B70E /* AdyenTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AdyenTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ E20AD0191EFAB0310065B70E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ E20AD0241EFAB0E00065B70E /* BasePlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasePlugin.swift; sourceTree = ""; };
+ E20AD0251EFAB0E00065B70E /* Currency.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Currency.swift; sourceTree = ""; };
+ E20AD0271EFAB0E00065B70E /* CardBrandCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardBrandCode.swift; sourceTree = ""; };
+ E20AD0281EFAB0E00065B70E /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = ""; };
+ E20AD0291EFAB0E00065B70E /* InputType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputType.swift; sourceTree = ""; };
+ E20AD02A1EFAB0E00065B70E /* MethodRequiresPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MethodRequiresPlugin.swift; sourceTree = ""; };
+ E20AD02B1EFAB0E00065B70E /* PaymentMethodType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentMethodType.swift; sourceTree = ""; };
+ E20AD02C1EFAB0E00065B70E /* PaymentRequestResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentRequestResult.swift; sourceTree = ""; };
+ E20AD02D1EFAB0E00065B70E /* PaymentStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentStatus.swift; sourceTree = ""; };
+ E20AD02F1EFAB0E00065B70E /* ArrayExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensions.swift; sourceTree = ""; };
+ E20AD0301EFAB0E00065B70E /* BoolExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensions.swift; sourceTree = ""; };
+ E20AD0311EFAB0E00065B70E /* DictionaryExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensions.swift; sourceTree = ""; };
+ E20AD0321EFAB0E00065B70E /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = ""; };
+ E20AD0331EFAB0E00065B70E /* UIScreenExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIScreenExtensions.swift; sourceTree = ""; };
+ E20AD0341EFAB0E00065B70E /* URLExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensions.swift; sourceTree = ""; };
+ E20AD0351EFAB0E00065B70E /* InputDetail.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputDetail.swift; sourceTree = ""; };
+ E20AD0361EFAB0E00065B70E /* InputSelectItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputSelectItem.swift; sourceTree = ""; };
+ E20AD0371EFAB0E00065B70E /* InternalPaymentRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InternalPaymentRequest.swift; sourceTree = ""; };
+ E20AD0381EFAB0E00065B70E /* Payment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Payment.swift; sourceTree = ""; };
+ E20AD0391EFAB0E00065B70E /* PaymentDetails.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentDetails.swift; sourceTree = ""; };
+ E20AD03A1EFAB0E00065B70E /* PaymentMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentMethod.swift; sourceTree = ""; };
+ E20AD03C1EFAB0E00065B70E /* PaymentRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentRequest.swift; sourceTree = ""; };
+ E20AD03D1EFAB0E00065B70E /* PaymentServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentServer.swift; sourceTree = ""; };
+ E20AD03E1EFAB0E00065B70E /* PluginLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PluginLoader.swift; sourceTree = ""; };
+ E20AD0401EFAB0E00065B70E /* DeviceDependable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceDependable.swift; sourceTree = ""; };
+ E20AD0421EFAB0E00065B70E /* PaymentRequestDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentRequestDelegate.swift; sourceTree = ""; };
+ E20AD0431EFAB0E00065B70E /* RequiresFinalState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequiresFinalState.swift; sourceTree = ""; };
+ E20AD0451EFAB0E00065B70E /* Version.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Version.swift; sourceTree = ""; };
+ E20AD0491EFAB0E00065B70E /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = ""; };
+ E20AD04A1EFAB0E00065B70E /* CheckoutButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutButton.swift; sourceTree = ""; };
+ E20AD04B1EFAB0E00065B70E /* LoadingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadingTableViewCell.swift; sourceTree = ""; };
+ E20AD04C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentMethodTableViewCell.swift; sourceTree = ""; };
+ E20AD04D1EFAB0E00065B70E /* UIColorExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensions.swift; sourceTree = ""; };
+ E20AD04E1EFAB0E00065B70E /* UIImageExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtensions.swift; sourceTree = ""; };
+ E20AD04F1EFAB0E00065B70E /* UIImageViewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewExtensions.swift; sourceTree = ""; };
+ E20AD0521EFAB0E00065B70E /* ApplePayDetailsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplePayDetailsPresenter.swift; sourceTree = ""; };
+ E20AD0531EFAB0E00065B70E /* ApplePayPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplePayPlugin.swift; sourceTree = ""; };
+ E20AD0551EFAB0E00065B70E /* CardFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardFormViewController.swift; sourceTree = ""; };
+ E20AD0561EFAB0E00065B70E /* CardFormViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CardFormViewController.xib; sourceTree = ""; };
+ E20AD0571EFAB0E00065B70E /* CardPaymentFieldManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardPaymentFieldManager.swift; sourceTree = ""; };
+ E20AD0581EFAB0E00065B70E /* CardType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardType.swift; sourceTree = ""; };
+ E20AD0591EFAB0E00065B70E /* CardValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardValidator.swift; sourceTree = ""; };
+ E20AD05A1EFAB0E00065B70E /* CardsAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardsAlertController.swift; sourceTree = ""; };
+ E20AD05B1EFAB0E00065B70E /* CardsDetailsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardsDetailsPresenter.swift; sourceTree = ""; };
+ E20AD05C1EFAB0E00065B70E /* CardsPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardsPlugin.swift; sourceTree = ""; };
+ E20AD05D1EFAB0E00065B70E /* CheckoutTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutTextField.swift; sourceTree = ""; };
+ E20AD05F1EFAB0E00065B70E /* IdealDetailsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdealDetailsPresenter.swift; sourceTree = ""; };
+ E20AD0601EFAB0E00065B70E /* IdealIssuerPickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdealIssuerPickerViewController.swift; sourceTree = ""; };
+ E20AD0611EFAB0E00065B70E /* IdealPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdealPlugin.swift; sourceTree = ""; };
+ E20AD0631EFAB0E00065B70E /* CheckoutHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutHeaderView.swift; sourceTree = ""; };
+ E20AD0641EFAB0E00065B70E /* CheckoutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutViewController.swift; sourceTree = ""; };
+ E20AD0651EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutViewControllerDelegate.swift; sourceTree = ""; };
+ E20AD0A51EFAB1950065B70E /* CardValidatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardValidatorTests.swift; sourceTree = ""; };
+ E20AD0A71EFAB1950065B70E /* ArrayExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensionTests.swift; sourceTree = ""; };
+ E20AD0A81EFAB1950065B70E /* BoolExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensionsTests.swift; sourceTree = ""; };
+ E20AD0A91EFAB1950065B70E /* CurrencyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencyTests.swift; sourceTree = ""; };
+ E20AD0AA1EFAB1950065B70E /* DictionaryExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensionTests.swift; sourceTree = ""; };
+ E20AD0AB1EFAB1950065B70E /* InputDetailsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputDetailsTests.swift; sourceTree = ""; };
+ E20AD0AC1EFAB1950065B70E /* InputSelectItemTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputSelectItemTests.swift; sourceTree = ""; };
+ E20AD0AD1EFAB1950065B70E /* PaymentDetailsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentDetailsTests.swift; sourceTree = ""; };
+ E20AD0AE1EFAB1950065B70E /* PaymentMethodTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentMethodTests.swift; sourceTree = ""; };
+ E20AD0AF1EFAB1950065B70E /* StringExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensionsTests.swift; sourceTree = ""; };
+ E20AD0B01EFAB1950065B70E /* URLExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensionsTests.swift; sourceTree = ""; };
+ E20AD0B51EFAB1950065B70E /* PaymentMethodApplePay.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodApplePay.json; sourceTree = ""; };
+ E20AD0B61EFAB1950065B70E /* PaymentMethodCard.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodCard.json; sourceTree = ""; };
+ E20AD0B71EFAB1950065B70E /* PaymentMethodCardCvc.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodCardCvc.json; sourceTree = ""; };
+ E20AD0B81EFAB1950065B70E /* PaymentMethodIdeal.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodIdeal.json; sourceTree = ""; };
+ E20AD0B91EFAB1950065B70E /* PaymentMethodKlarna.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodKlarna.json; sourceTree = ""; };
+ E20AD0BA1EFAB1950065B70E /* PaymentMethodPaypal.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodPaypal.json; sourceTree = ""; };
+ E20AD0BB1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodPaypalRecurring.json; sourceTree = ""; };
+ E20AD0BC1EFAB1950065B70E /* PaymentMethodSepa.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodSepa.json; sourceTree = ""; };
+ E20AD0D21EFAB1BF0065B70E /* JsonReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JsonReader.swift; sourceTree = ""; };
+ E20AD1E81EFBE7630065B70E /* AdyenCSE.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdyenCSE.framework; path = Carthage/Build/iOS/AdyenCSE.framework; sourceTree = ""; };
+ E214EF681F0A2C41009A7E3A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; };
+ E214EF691F0A2C49009A7E3A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; };
+ E214EF6A1F0A2C51009A7E3A /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; };
+ E226F1481EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitPlugin.swift; sourceTree = ""; };
+ E240E7521F0BC5600059FA0E /* UITableViewControllerExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewControllerExtensions.swift; sourceTree = ""; };
+ E255C4011F0103DF0075254F /* NavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = ""; };
+ E25C87A41F0B81F300FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodPickerViewControllerDelegate.swift; sourceTree = ""; };
+ E25C87A51F0B81F300FF3EA0 /* PaymentMethodPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodPickerViewController.swift; sourceTree = ""; };
+ E28562581F0FC06F0049E442 /* BundleExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BundleExtensions.swift; sourceTree = ""; };
+ E28562631F13BA5D0049E442 /* PaymentStatusTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentStatusTests.swift; sourceTree = ""; };
+ E28A79981EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitDetailsPresenter.swift; sourceTree = ""; };
+ E28A799A1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitFormViewController.swift; sourceTree = ""; };
+ E28A799B1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SEPADirectDebitFormViewController.xib; sourceTree = ""; };
+ E28A799E1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitFormViewControllerDelegate.swift; sourceTree = ""; };
+ E28ECE001F065383004FCEA6 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; };
+ E2A167C21F0E643A00A27E4A /* Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; };
+ E2AB20EE1F0A31400006FF2A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; };
+ E2AB20F01F0A65000006FF2A /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Localizable.strings; sourceTree = ""; };
+ E2AB20F11F0A650D0006FF2A /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; };
+ E2B6207C1F0E5EA5001D4C27 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
+ E2B6207E1F0E5F0F001D4C27 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
+ E2BF6CC11F03952C0065E574 /* AdyenUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AdyenUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ E2BF6CC51F03952D0065E574 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ E2BF6CCC1F0395670065E574 /* TestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestCase.swift; sourceTree = ""; };
+ E2BF6CCE1F0397060065E574 /* SEPADirectDebitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SEPADirectDebitTests.swift; sourceTree = ""; };
+ E2BF6CD01F0397AC0065E574 /* XCUIElementQueryExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCUIElementQueryExtensions.swift; sourceTree = ""; };
+ E2BF6CD21F03A8240065E574 /* CardsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardsTests.swift; sourceTree = ""; };
+ E2BF6CD61F03CEF60065E574 /* IdealTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdealTests.swift; sourceTree = ""; };
+ E2E9D01B1F0389C80056E0AC /* AdyenUIHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AdyenUIHost.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ E2E9D01D1F0389C80056E0AC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ E2E9D01F1F0389C80056E0AC /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ E2E9D0241F0389C80056E0AC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ E2E9D0291F0389C80056E0AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ E2EE2E4A1F0141CD008DC96D /* IBANValidatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IBANValidatorTests.swift; sourceTree = ""; };
+ E2EE2E511F026746008DC96D /* IBANSpecification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IBANSpecification.swift; sourceTree = ""; };
+ E2EE2E521F026746008DC96D /* IBANTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IBANTextField.swift; sourceTree = ""; };
+ E2EE2E531F026746008DC96D /* IBANValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IBANValidator.swift; sourceTree = ""; };
+ E2F627641F063842005D8026 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; };
+ E2F627661F063849005D8026 /* Localization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Localization.swift; sourceTree = ""; };
+ E2F627691F063B5D005D8026 /* AppearanceConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceConfiguration.swift; sourceTree = ""; };
+ E2F6276C1F064127005D8026 /* PaymentMethodDetailsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodDetailsPresenter.swift; sourceTree = ""; };
+ E2F6276D1F064127005D8026 /* UIPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIPresentable.swift; sourceTree = ""; };
+ EEDFC6FAA3826763FD1E99D3 /* Pods-AdyenTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AdyenTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AdyenTests/Pods-AdyenTests.release.xcconfig"; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ E20AD0051EFAB0310065B70E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 7D7AD12FB4E950056731EEB6 /* Pods_Adyen.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ E20AD00F1EFAB0310065B70E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E2A167C61F0E704100A27E4A /* Adyen.framework in Frameworks */,
+ 53C0FEFC4B5CD9400E89E4CA /* Pods_AdyenTests.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ E2BF6CBE1F03952C0065E574 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ E2E9D0181F0389C80056E0AC /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E250E13F1F0E606000BFFF2F /* Adyen.framework in Frameworks */,
+ C3A02E02B25D9A9E913FA639 /* Pods_AdyenUIHost.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 2C63A3DBF353ABFDA95AC068 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 20191199750F47C401152B90 /* Pods-Adyen.debug.xcconfig */,
+ 39B692648B2F9A2E64860876 /* Pods-Adyen.release.xcconfig */,
+ 7370242B72CA01D6FB771E34 /* Pods-AdyenTests.debug.xcconfig */,
+ EEDFC6FAA3826763FD1E99D3 /* Pods-AdyenTests.release.xcconfig */,
+ 9D45EFB0559159A56AFB2ED0 /* Pods-AdyenUIHost.debug.xcconfig */,
+ 4D2C0B04986E87ADFBF3FD11 /* Pods-AdyenUIHost.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "";
+ };
+ E20ACFFF1EFAB0310065B70E = {
+ isa = PBXGroup;
+ children = (
+ E20AD00B1EFAB0310065B70E /* Adyen */,
+ E20AD0161EFAB0310065B70E /* AdyenTests */,
+ E2BF6CC21F03952C0065E574 /* AdyenUITests */,
+ E2E9D01C1F0389C80056E0AC /* AdyenUIHost */,
+ E20AD00A1EFAB0310065B70E /* Products */,
+ E20AD1E71EFBE7630065B70E /* Frameworks */,
+ 2C63A3DBF353ABFDA95AC068 /* Pods */,
+ );
+ sourceTree = "";
+ };
+ E20AD00A1EFAB0310065B70E /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0091EFAB0310065B70E /* Adyen.framework */,
+ E20AD0121EFAB0310065B70E /* AdyenTests.xctest */,
+ E2E9D01B1F0389C80056E0AC /* AdyenUIHost.app */,
+ E2BF6CC11F03952C0065E574 /* AdyenUITests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ E20AD00B1EFAB0310065B70E /* Adyen */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0231EFAB0E00065B70E /* Core */,
+ E20AD0461EFAB0E00065B70E /* CoreUI */,
+ E20AD0621EFAB0E00065B70E /* UI */,
+ E20AD0501EFAB0E00065B70E /* Plugins */,
+ E20AD00C1EFAB0310065B70E /* Adyen.h */,
+ E20AD00D1EFAB0310065B70E /* Info.plist */,
+ );
+ path = Adyen;
+ sourceTree = "";
+ };
+ E20AD0161EFAB0310065B70E /* AdyenTests */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0A41EFAB1950065B70E /* Cards */,
+ E20AD0A61EFAB1950065B70E /* Core */,
+ E20AD0B11EFAB1950065B70E /* CoreUI */,
+ E2EE2E481F0141C3008DC96D /* Plugins */,
+ E20AD0B31EFAB1950065B70E /* Resources */,
+ E20AD0D11EFAB1BF0065B70E /* Helpers */,
+ E20AD0191EFAB0310065B70E /* Info.plist */,
+ );
+ path = AdyenTests;
+ sourceTree = "";
+ };
+ E20AD0231EFAB0E00065B70E /* Core */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0261EFAB0E00065B70E /* Enum */,
+ E20AD02E1EFAB0E00065B70E /* Extensions */,
+ E20AD03F1EFAB0E00065B70E /* Protocols */,
+ E20AD0241EFAB0E00065B70E /* BasePlugin.swift */,
+ E20AD0251EFAB0E00065B70E /* Currency.swift */,
+ E20AD0351EFAB0E00065B70E /* InputDetail.swift */,
+ E20AD0361EFAB0E00065B70E /* InputSelectItem.swift */,
+ E20AD0371EFAB0E00065B70E /* InternalPaymentRequest.swift */,
+ E20AD0381EFAB0E00065B70E /* Payment.swift */,
+ E20AD0391EFAB0E00065B70E /* PaymentDetails.swift */,
+ E20AD03A1EFAB0E00065B70E /* PaymentMethod.swift */,
+ E20AD03C1EFAB0E00065B70E /* PaymentRequest.swift */,
+ E20AD03D1EFAB0E00065B70E /* PaymentServer.swift */,
+ E20AD03E1EFAB0E00065B70E /* PluginLoader.swift */,
+ E20AD0451EFAB0E00065B70E /* Version.swift */,
+ );
+ path = Core;
+ sourceTree = "";
+ };
+ E20AD0261EFAB0E00065B70E /* Enum */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0271EFAB0E00065B70E /* CardBrandCode.swift */,
+ E20AD0281EFAB0E00065B70E /* Error.swift */,
+ E20AD0291EFAB0E00065B70E /* InputType.swift */,
+ E20AD02A1EFAB0E00065B70E /* MethodRequiresPlugin.swift */,
+ E20AD02B1EFAB0E00065B70E /* PaymentMethodType.swift */,
+ E20AD02C1EFAB0E00065B70E /* PaymentRequestResult.swift */,
+ E20AD02D1EFAB0E00065B70E /* PaymentStatus.swift */,
+ );
+ path = Enum;
+ sourceTree = "";
+ };
+ E20AD02E1EFAB0E00065B70E /* Extensions */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD02F1EFAB0E00065B70E /* ArrayExtensions.swift */,
+ E20AD0301EFAB0E00065B70E /* BoolExtensions.swift */,
+ E20AD0311EFAB0E00065B70E /* DictionaryExtensions.swift */,
+ E20AD0321EFAB0E00065B70E /* StringExtensions.swift */,
+ E20AD0331EFAB0E00065B70E /* UIScreenExtensions.swift */,
+ E20AD0341EFAB0E00065B70E /* URLExtensions.swift */,
+ );
+ path = Extensions;
+ sourceTree = "";
+ };
+ E20AD03F1EFAB0E00065B70E /* Protocols */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0401EFAB0E00065B70E /* DeviceDependable.swift */,
+ E20AD0421EFAB0E00065B70E /* PaymentRequestDelegate.swift */,
+ E20AD0431EFAB0E00065B70E /* RequiresFinalState.swift */,
+ );
+ path = Protocols;
+ sourceTree = "";
+ };
+ E20AD0461EFAB0E00065B70E /* CoreUI */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0471EFAB0E00065B70E /* Assets */,
+ E2F6276B1F064127005D8026 /* Plugins */,
+ E2F627691F063B5D005D8026 /* AppearanceConfiguration.swift */,
+ E20AD04A1EFAB0E00065B70E /* CheckoutButton.swift */,
+ E20AD04B1EFAB0E00065B70E /* LoadingTableViewCell.swift */,
+ E20AD04C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift */,
+ E20AD04D1EFAB0E00065B70E /* UIColorExtensions.swift */,
+ E20AD04E1EFAB0E00065B70E /* UIImageExtensions.swift */,
+ E20AD04F1EFAB0E00065B70E /* UIImageViewExtensions.swift */,
+ E28562581F0FC06F0049E442 /* BundleExtensions.swift */,
+ E2F627661F063849005D8026 /* Localization.swift */,
+ );
+ path = CoreUI;
+ sourceTree = "";
+ };
+ E20AD0471EFAB0E00065B70E /* Assets */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0491EFAB0E00065B70E /* Media.xcassets */,
+ E2F627651F063842005D8026 /* Localizable.strings */,
+ );
+ path = Assets;
+ sourceTree = "";
+ };
+ E20AD0501EFAB0E00065B70E /* Plugins */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0511EFAB0E00065B70E /* ApplePay */,
+ E20AD0541EFAB0E00065B70E /* Cards */,
+ E20AD05E1EFAB0E00065B70E /* Ideal */,
+ E226F1471EFD0A36009E04C9 /* SEPADirectDebit */,
+ );
+ path = Plugins;
+ sourceTree = "";
+ };
+ E20AD0511EFAB0E00065B70E /* ApplePay */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0531EFAB0E00065B70E /* ApplePayPlugin.swift */,
+ E20AD0521EFAB0E00065B70E /* ApplePayDetailsPresenter.swift */,
+ );
+ path = ApplePay;
+ sourceTree = "";
+ };
+ E20AD0541EFAB0E00065B70E /* Cards */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD05C1EFAB0E00065B70E /* CardsPlugin.swift */,
+ E20AD0551EFAB0E00065B70E /* CardFormViewController.swift */,
+ E20AD0561EFAB0E00065B70E /* CardFormViewController.xib */,
+ E20AD0571EFAB0E00065B70E /* CardPaymentFieldManager.swift */,
+ E20AD0581EFAB0E00065B70E /* CardType.swift */,
+ E20AD0591EFAB0E00065B70E /* CardValidator.swift */,
+ E20AD05A1EFAB0E00065B70E /* CardsAlertController.swift */,
+ E20AD05B1EFAB0E00065B70E /* CardsDetailsPresenter.swift */,
+ E20AD05D1EFAB0E00065B70E /* CheckoutTextField.swift */,
+ );
+ path = Cards;
+ sourceTree = "";
+ };
+ E20AD05E1EFAB0E00065B70E /* Ideal */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0611EFAB0E00065B70E /* IdealPlugin.swift */,
+ E20AD05F1EFAB0E00065B70E /* IdealDetailsPresenter.swift */,
+ E20AD0601EFAB0E00065B70E /* IdealIssuerPickerViewController.swift */,
+ );
+ path = Ideal;
+ sourceTree = "";
+ };
+ E20AD0621EFAB0E00065B70E /* UI */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0631EFAB0E00065B70E /* CheckoutHeaderView.swift */,
+ E20AD0641EFAB0E00065B70E /* CheckoutViewController.swift */,
+ E20AD0651EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift */,
+ E255C4011F0103DF0075254F /* NavigationController.swift */,
+ E25C87A51F0B81F300FF3EA0 /* PaymentMethodPickerViewController.swift */,
+ E25C87A41F0B81F300FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift */,
+ E240E7521F0BC5600059FA0E /* UITableViewControllerExtensions.swift */,
+ );
+ path = UI;
+ sourceTree = "";
+ };
+ E20AD0A41EFAB1950065B70E /* Cards */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0A51EFAB1950065B70E /* CardValidatorTests.swift */,
+ );
+ path = Cards;
+ sourceTree = "";
+ };
+ E20AD0A61EFAB1950065B70E /* Core */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0A71EFAB1950065B70E /* ArrayExtensionTests.swift */,
+ E20AD0A81EFAB1950065B70E /* BoolExtensionsTests.swift */,
+ E20AD0A91EFAB1950065B70E /* CurrencyTests.swift */,
+ E20AD0AA1EFAB1950065B70E /* DictionaryExtensionTests.swift */,
+ E20AD0AB1EFAB1950065B70E /* InputDetailsTests.swift */,
+ E20AD0AC1EFAB1950065B70E /* InputSelectItemTests.swift */,
+ E28562631F13BA5D0049E442 /* PaymentStatusTests.swift */,
+ E20AD0AD1EFAB1950065B70E /* PaymentDetailsTests.swift */,
+ E20AD0AE1EFAB1950065B70E /* PaymentMethodTests.swift */,
+ E20AD0AF1EFAB1950065B70E /* StringExtensionsTests.swift */,
+ E20AD0B01EFAB1950065B70E /* URLExtensionsTests.swift */,
+ );
+ path = Core;
+ sourceTree = "";
+ };
+ E20AD0B11EFAB1950065B70E /* CoreUI */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ path = CoreUI;
+ sourceTree = "";
+ };
+ E20AD0B31EFAB1950065B70E /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0B41EFAB1950065B70E /* Json */,
+ );
+ path = Resources;
+ sourceTree = "";
+ };
+ E20AD0B41EFAB1950065B70E /* Json */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0B51EFAB1950065B70E /* PaymentMethodApplePay.json */,
+ E20AD0B61EFAB1950065B70E /* PaymentMethodCard.json */,
+ E20AD0B71EFAB1950065B70E /* PaymentMethodCardCvc.json */,
+ E20AD0B81EFAB1950065B70E /* PaymentMethodIdeal.json */,
+ E20AD0B91EFAB1950065B70E /* PaymentMethodKlarna.json */,
+ E20AD0BA1EFAB1950065B70E /* PaymentMethodPaypal.json */,
+ E20AD0BB1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json */,
+ E20AD0BC1EFAB1950065B70E /* PaymentMethodSepa.json */,
+ );
+ path = Json;
+ sourceTree = "";
+ };
+ E20AD0D11EFAB1BF0065B70E /* Helpers */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD0D21EFAB1BF0065B70E /* JsonReader.swift */,
+ );
+ path = Helpers;
+ sourceTree = "";
+ };
+ E20AD1E71EFBE7630065B70E /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD1E81EFBE7630065B70E /* AdyenCSE.framework */,
+ B7AEC312DF920BCC1C4BC1C0 /* Pods_Adyen.framework */,
+ D3BE1722DC859E029DDBCF09 /* Pods_AdyenTests.framework */,
+ 36FCC0F6EB491A052CC61D81 /* Pods_AdyenUIHost.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ E226F1471EFD0A36009E04C9 /* SEPADirectDebit */ = {
+ isa = PBXGroup;
+ children = (
+ E2EE2E501F026746008DC96D /* IBAN */,
+ E226F1481EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift */,
+ E28A79981EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift */,
+ E28A799A1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift */,
+ E28A799B1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib */,
+ E28A799E1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift */,
+ );
+ path = SEPADirectDebit;
+ sourceTree = "";
+ };
+ E2BF6CC21F03952C0065E574 /* AdyenUITests */ = {
+ isa = PBXGroup;
+ children = (
+ E2BF6CCB1F0395600065E574 /* Base */,
+ E2BF6CD21F03A8240065E574 /* CardsTests.swift */,
+ E2BF6CD61F03CEF60065E574 /* IdealTests.swift */,
+ E2BF6CCE1F0397060065E574 /* SEPADirectDebitTests.swift */,
+ E2BF6CC51F03952D0065E574 /* Info.plist */,
+ );
+ path = AdyenUITests;
+ sourceTree = "";
+ };
+ E2BF6CCB1F0395600065E574 /* Base */ = {
+ isa = PBXGroup;
+ children = (
+ E2BF6CCC1F0395670065E574 /* TestCase.swift */,
+ E2BF6CD01F0397AC0065E574 /* XCUIElementQueryExtensions.swift */,
+ );
+ path = Base;
+ sourceTree = "";
+ };
+ E2E9D01C1F0389C80056E0AC /* AdyenUIHost */ = {
+ isa = PBXGroup;
+ children = (
+ E2A167C21F0E643A00A27E4A /* Configuration.swift */,
+ E2E9D01D1F0389C80056E0AC /* AppDelegate.swift */,
+ E2E9D01F1F0389C80056E0AC /* ViewController.swift */,
+ E2B6207E1F0E5F0F001D4C27 /* LaunchScreen.storyboard */,
+ E2B6207C1F0E5EA5001D4C27 /* Main.storyboard */,
+ E2E9D0241F0389C80056E0AC /* Assets.xcassets */,
+ E2E9D0291F0389C80056E0AC /* Info.plist */,
+ );
+ path = AdyenUIHost;
+ sourceTree = "";
+ };
+ E2EE2E481F0141C3008DC96D /* Plugins */ = {
+ isa = PBXGroup;
+ children = (
+ E2EE2E491F0141C3008DC96D /* SEPADirectDebit */,
+ );
+ path = Plugins;
+ sourceTree = "";
+ };
+ E2EE2E491F0141C3008DC96D /* SEPADirectDebit */ = {
+ isa = PBXGroup;
+ children = (
+ E2EE2E4A1F0141CD008DC96D /* IBANValidatorTests.swift */,
+ );
+ path = SEPADirectDebit;
+ sourceTree = "";
+ };
+ E2EE2E501F026746008DC96D /* IBAN */ = {
+ isa = PBXGroup;
+ children = (
+ E2EE2E511F026746008DC96D /* IBANSpecification.swift */,
+ E2EE2E521F026746008DC96D /* IBANTextField.swift */,
+ E2EE2E531F026746008DC96D /* IBANValidator.swift */,
+ );
+ path = IBAN;
+ sourceTree = "";
+ };
+ E2F6276B1F064127005D8026 /* Plugins */ = {
+ isa = PBXGroup;
+ children = (
+ E2F6276D1F064127005D8026 /* UIPresentable.swift */,
+ E2F6276C1F064127005D8026 /* PaymentMethodDetailsPresenter.swift */,
+ );
+ path = Plugins;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ E20AD0061EFAB0310065B70E /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E20AD01A1EFAB0310065B70E /* Adyen.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ E20AD0081EFAB0310065B70E /* Adyen */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = E20AD01D1EFAB0310065B70E /* Build configuration list for PBXNativeTarget "Adyen" */;
+ buildPhases = (
+ 6B95865FF45820DB15409BA1 /* [CP] Check Pods Manifest.lock */,
+ E20AD0041EFAB0310065B70E /* Sources */,
+ E20AD0051EFAB0310065B70E /* Frameworks */,
+ E20AD0061EFAB0310065B70E /* Headers */,
+ E20AD0071EFAB0310065B70E /* Resources */,
+ E226F1431EFCF50A009E04C9 /* SwiftLint */,
+ 02474A22ADD502EEE43DCD38 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Adyen;
+ productName = Adyen;
+ productReference = E20AD0091EFAB0310065B70E /* Adyen.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+ E20AD0111EFAB0310065B70E /* AdyenTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = E20AD0201EFAB0310065B70E /* Build configuration list for PBXNativeTarget "AdyenTests" */;
+ buildPhases = (
+ FE27A79BD5717B7A94254E4D /* [CP] Check Pods Manifest.lock */,
+ E20AD00E1EFAB0310065B70E /* Sources */,
+ E20AD00F1EFAB0310065B70E /* Frameworks */,
+ E20AD0101EFAB0310065B70E /* Resources */,
+ B2D23B80357D0CC2DABA91CB /* [CP] Embed Pods Frameworks */,
+ 8DAFF072F5EADA4FC2A33B45 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ E20AD0151EFAB0310065B70E /* PBXTargetDependency */,
+ );
+ name = AdyenTests;
+ productName = AdyenTests;
+ productReference = E20AD0121EFAB0310065B70E /* AdyenTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ E2BF6CC01F03952C0065E574 /* AdyenUITests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = E2BF6CC81F03952D0065E574 /* Build configuration list for PBXNativeTarget "AdyenUITests" */;
+ buildPhases = (
+ E2BF6CBD1F03952C0065E574 /* Sources */,
+ E2BF6CBE1F03952C0065E574 /* Frameworks */,
+ E2BF6CBF1F03952C0065E574 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ E2BF6CC71F03952D0065E574 /* PBXTargetDependency */,
+ );
+ name = AdyenUITests;
+ productName = AdyenUITests;
+ productReference = E2BF6CC11F03952C0065E574 /* AdyenUITests.xctest */;
+ productType = "com.apple.product-type.bundle.ui-testing";
+ };
+ E2E9D01A1F0389C80056E0AC /* AdyenUIHost */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = E2E9D02C1F0389C80056E0AC /* Build configuration list for PBXNativeTarget "AdyenUIHost" */;
+ buildPhases = (
+ B07087D0BC32240A0F60E2AC /* [CP] Check Pods Manifest.lock */,
+ E2E9D0171F0389C80056E0AC /* Sources */,
+ E2E9D0181F0389C80056E0AC /* Frameworks */,
+ E2E9D0191F0389C80056E0AC /* Resources */,
+ 2DC1652936EDFD1499FBF286 /* [CP] Embed Pods Frameworks */,
+ 6F9EB542D6DFC7ED0AD003A8 /* [CP] Copy Pods Resources */,
+ E250E1431F0E606000BFFF2F /* Embed Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ E250E1421F0E606000BFFF2F /* PBXTargetDependency */,
+ );
+ name = AdyenUIHost;
+ productName = AdyenUIHost;
+ productReference = E2E9D01B1F0389C80056E0AC /* AdyenUIHost.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ E20AD0001EFAB0310065B70E /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0830;
+ LastUpgradeCheck = 0830;
+ ORGANIZATIONNAME = Adyen;
+ TargetAttributes = {
+ E20AD0081EFAB0310065B70E = {
+ CreatedOnToolsVersion = 8.3.3;
+ DevelopmentTeam = B2NYSS5932;
+ ProvisioningStyle = Manual;
+ };
+ E20AD0111EFAB0310065B70E = {
+ CreatedOnToolsVersion = 8.3.3;
+ ProvisioningStyle = Manual;
+ };
+ E2BF6CC01F03952C0065E574 = {
+ CreatedOnToolsVersion = 8.3.3;
+ ProvisioningStyle = Automatic;
+ TestTargetID = E2E9D01A1F0389C80056E0AC;
+ };
+ E2E9D01A1F0389C80056E0AC = {
+ CreatedOnToolsVersion = 8.3.3;
+ ProvisioningStyle = Manual;
+ };
+ };
+ };
+ buildConfigurationList = E20AD0031EFAB0310065B70E /* Build configuration list for PBXProject "Adyen" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ nl,
+ fr,
+ de,
+ es,
+ it,
+ pt,
+ sv,
+ );
+ mainGroup = E20ACFFF1EFAB0310065B70E;
+ productRefGroup = E20AD00A1EFAB0310065B70E /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ E20AD0081EFAB0310065B70E /* Adyen */,
+ E20AD0111EFAB0310065B70E /* AdyenTests */,
+ E2BF6CC01F03952C0065E574 /* AdyenUITests */,
+ E2E9D01A1F0389C80056E0AC /* AdyenUIHost */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ E20AD0071EFAB0310065B70E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E28A799D1EFD4A0800E148FF /* SEPADirectDebitFormViewController.xib in Resources */,
+ E2F627681F06386C005D8026 /* Localizable.strings in Resources */,
+ E20AD0931EFAB0E00065B70E /* CardFormViewController.xib in Resources */,
+ E20AD0891EFAB0E00065B70E /* Media.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ E20AD0101EFAB0310065B70E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E20AD0CF1EFAB1950065B70E /* PaymentMethodPaypalRecurring.json in Resources */,
+ E20AD0CD1EFAB1950065B70E /* PaymentMethodKlarna.json in Resources */,
+ E20AD0C91EFAB1950065B70E /* PaymentMethodApplePay.json in Resources */,
+ E20AD0CC1EFAB1950065B70E /* PaymentMethodIdeal.json in Resources */,
+ E20AD0CA1EFAB1950065B70E /* PaymentMethodCard.json in Resources */,
+ E20AD0CE1EFAB1950065B70E /* PaymentMethodPaypal.json in Resources */,
+ E20AD0D01EFAB1950065B70E /* PaymentMethodSepa.json in Resources */,
+ E20AD0CB1EFAB1950065B70E /* PaymentMethodCardCvc.json in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ E2BF6CBF1F03952C0065E574 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ E2E9D0191F0389C80056E0AC /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E2B6207F1F0E5F0F001D4C27 /* LaunchScreen.storyboard in Resources */,
+ E2E9D0251F0389C80056E0AC /* Assets.xcassets in Resources */,
+ E2B6207D1F0E5EA5001D4C27 /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 02474A22ADD502EEE43DCD38 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Adyen/Pods-Adyen-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 2DC1652936EDFD1499FBF286 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AdyenUIHost/Pods-AdyenUIHost-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 6B95865FF45820DB15409BA1 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ 6F9EB542D6DFC7ED0AD003A8 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AdyenUIHost/Pods-AdyenUIHost-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 8DAFF072F5EADA4FC2A33B45 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AdyenTests/Pods-AdyenTests-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ B07087D0BC32240A0F60E2AC /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ B2D23B80357D0CC2DABA91CB /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AdyenTests/Pods-AdyenTests-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ E226F1431EFCF50A009E04C9 /* SwiftLint */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = SwiftLint;
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\"";
+ };
+ FE27A79BD5717B7A94254E4D /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ E20AD0041EFAB0310065B70E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E2F627701F064270005D8026 /* AppearanceConfiguration.swift in Sources */,
+ E20AD0911EFAB0E00065B70E /* ApplePayPlugin.swift in Sources */,
+ E2F6276E1F06413B005D8026 /* UIPresentable.swift in Sources */,
+ E20AD0711EFAB0E00065B70E /* PaymentStatus.swift in Sources */,
+ E20AD0941EFAB0E00065B70E /* CardPaymentFieldManager.swift in Sources */,
+ E226F1491EFD0A3F009E04C9 /* SEPADirectDebitPlugin.swift in Sources */,
+ E20AD09B1EFAB0E00065B70E /* IdealDetailsPresenter.swift in Sources */,
+ E2EE2E541F026746008DC96D /* IBANSpecification.swift in Sources */,
+ E20AD08A1EFAB0E00065B70E /* CheckoutButton.swift in Sources */,
+ E20AD0921EFAB0E00065B70E /* CardFormViewController.swift in Sources */,
+ E20AD0721EFAB0E00065B70E /* ArrayExtensions.swift in Sources */,
+ E2F6276F1F06413D005D8026 /* PaymentMethodDetailsPresenter.swift in Sources */,
+ E20AD06C1EFAB0E00065B70E /* Error.swift in Sources */,
+ E20AD07D1EFAB0E00065B70E /* PaymentMethod.swift in Sources */,
+ E240E7531F0BC5600059FA0E /* UITableViewControllerExtensions.swift in Sources */,
+ E20AD06A1EFAB0E00065B70E /* Currency.swift in Sources */,
+ E20AD06F1EFAB0E00065B70E /* PaymentMethodType.swift in Sources */,
+ E20AD0731EFAB0E00065B70E /* BoolExtensions.swift in Sources */,
+ E20AD0701EFAB0E00065B70E /* PaymentRequestResult.swift in Sources */,
+ E28A799C1EFD4A0800E148FF /* SEPADirectDebitFormViewController.swift in Sources */,
+ E20AD07C1EFAB0E00065B70E /* PaymentDetails.swift in Sources */,
+ E20AD0791EFAB0E00065B70E /* InputSelectItem.swift in Sources */,
+ E20AD0811EFAB0E00065B70E /* PluginLoader.swift in Sources */,
+ E20AD0771EFAB0E00065B70E /* URLExtensions.swift in Sources */,
+ E20AD09D1EFAB0E00065B70E /* IdealPlugin.swift in Sources */,
+ E20AD0951EFAB0E00065B70E /* CardType.swift in Sources */,
+ E20AD0971EFAB0E00065B70E /* CardsAlertController.swift in Sources */,
+ E20AD0801EFAB0E00065B70E /* PaymentServer.swift in Sources */,
+ E25C87A71F0B81FF00FF3EA0 /* PaymentMethodPickerViewControllerDelegate.swift in Sources */,
+ E28A799F1EFD5DA200E148FF /* SEPADirectDebitFormViewControllerDelegate.swift in Sources */,
+ E20AD09C1EFAB0E00065B70E /* IdealIssuerPickerViewController.swift in Sources */,
+ E20AD0691EFAB0E00065B70E /* BasePlugin.swift in Sources */,
+ E20AD0991EFAB0E00065B70E /* CardsPlugin.swift in Sources */,
+ E20AD06D1EFAB0E00065B70E /* InputType.swift in Sources */,
+ E20AD0841EFAB0E00065B70E /* PaymentRequestDelegate.swift in Sources */,
+ E20AD07A1EFAB0E00065B70E /* InternalPaymentRequest.swift in Sources */,
+ E28A79991EFD1ABD00E148FF /* SEPADirectDebitDetailsPresenter.swift in Sources */,
+ E20AD06B1EFAB0E00065B70E /* CardBrandCode.swift in Sources */,
+ E20AD06E1EFAB0E00065B70E /* MethodRequiresPlugin.swift in Sources */,
+ E20AD0901EFAB0E00065B70E /* ApplePayDetailsPresenter.swift in Sources */,
+ E20AD0761EFAB0E00065B70E /* UIScreenExtensions.swift in Sources */,
+ E20AD0751EFAB0E00065B70E /* StringExtensions.swift in Sources */,
+ E20AD0961EFAB0E00065B70E /* CardValidator.swift in Sources */,
+ E20AD0981EFAB0E00065B70E /* CardsDetailsPresenter.swift in Sources */,
+ E2EE2E551F026746008DC96D /* IBANTextField.swift in Sources */,
+ E20AD0821EFAB0E00065B70E /* DeviceDependable.swift in Sources */,
+ E20AD07B1EFAB0E00065B70E /* Payment.swift in Sources */,
+ E28562591F0FC06F0049E442 /* BundleExtensions.swift in Sources */,
+ E20AD08E1EFAB0E00065B70E /* UIImageExtensions.swift in Sources */,
+ E20AD09F1EFAB0E00065B70E /* CheckoutViewController.swift in Sources */,
+ E20AD07F1EFAB0E00065B70E /* PaymentRequest.swift in Sources */,
+ E20AD09E1EFAB0E00065B70E /* CheckoutHeaderView.swift in Sources */,
+ E20AD0871EFAB0E00065B70E /* Version.swift in Sources */,
+ E20AD08D1EFAB0E00065B70E /* UIColorExtensions.swift in Sources */,
+ E255C4021F0103DF0075254F /* NavigationController.swift in Sources */,
+ E25A3FC11F0686F800679DCD /* Localization.swift in Sources */,
+ E20AD08B1EFAB0E00065B70E /* LoadingTableViewCell.swift in Sources */,
+ E20AD0A01EFAB0E00065B70E /* CheckoutViewControllerDelegate.swift in Sources */,
+ E25C87A61F0B81FC00FF3EA0 /* PaymentMethodPickerViewController.swift in Sources */,
+ E20AD08C1EFAB0E00065B70E /* PaymentMethodTableViewCell.swift in Sources */,
+ E20AD0741EFAB0E00065B70E /* DictionaryExtensions.swift in Sources */,
+ E20AD0781EFAB0E00065B70E /* InputDetail.swift in Sources */,
+ E20AD08F1EFAB0E00065B70E /* UIImageViewExtensions.swift in Sources */,
+ E20AD0851EFAB0E00065B70E /* RequiresFinalState.swift in Sources */,
+ E2EE2E561F026746008DC96D /* IBANValidator.swift in Sources */,
+ E20AD09A1EFAB0E00065B70E /* CheckoutTextField.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ E20AD00E1EFAB0310065B70E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E20AD0C21EFAB1950065B70E /* InputDetailsTests.swift in Sources */,
+ E20AD0BD1EFAB1950065B70E /* CardValidatorTests.swift in Sources */,
+ E20AD0D31EFAB1BF0065B70E /* JsonReader.swift in Sources */,
+ E20AD0C61EFAB1950065B70E /* StringExtensionsTests.swift in Sources */,
+ E28562641F13BA5D0049E442 /* PaymentStatusTests.swift in Sources */,
+ E20AD0C01EFAB1950065B70E /* CurrencyTests.swift in Sources */,
+ E20AD0C71EFAB1950065B70E /* URLExtensionsTests.swift in Sources */,
+ E20AD0C41EFAB1950065B70E /* PaymentDetailsTests.swift in Sources */,
+ E20AD0C11EFAB1950065B70E /* DictionaryExtensionTests.swift in Sources */,
+ E20AD0BE1EFAB1950065B70E /* ArrayExtensionTests.swift in Sources */,
+ E20AD0C51EFAB1950065B70E /* PaymentMethodTests.swift in Sources */,
+ E20AD0BF1EFAB1950065B70E /* BoolExtensionsTests.swift in Sources */,
+ E2EE2E4B1F0141CD008DC96D /* IBANValidatorTests.swift in Sources */,
+ E20AD0C31EFAB1950065B70E /* InputSelectItemTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ E2BF6CBD1F03952C0065E574 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E2BF6CCF1F0397060065E574 /* SEPADirectDebitTests.swift in Sources */,
+ E2BF6CD71F03CEF60065E574 /* IdealTests.swift in Sources */,
+ E2BF6CD11F0397AC0065E574 /* XCUIElementQueryExtensions.swift in Sources */,
+ E2BF6CCD1F0395670065E574 /* TestCase.swift in Sources */,
+ E2BF6CD31F03A8240065E574 /* CardsTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ E2E9D0171F0389C80056E0AC /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E2A167C31F0E643A00A27E4A /* Configuration.swift in Sources */,
+ E2E9D0201F0389C80056E0AC /* ViewController.swift in Sources */,
+ E2E9D01E1F0389C80056E0AC /* AppDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ E20AD0151EFAB0310065B70E /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = E20AD0081EFAB0310065B70E /* Adyen */;
+ targetProxy = E20AD0141EFAB0310065B70E /* PBXContainerItemProxy */;
+ };
+ E250E1421F0E606000BFFF2F /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = E20AD0081EFAB0310065B70E /* Adyen */;
+ targetProxy = E250E1411F0E606000BFFF2F /* PBXContainerItemProxy */;
+ };
+ E2BF6CC71F03952D0065E574 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = E2E9D01A1F0389C80056E0AC /* AdyenUIHost */;
+ targetProxy = E2BF6CC61F03952D0065E574 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ E2F627651F063842005D8026 /* Localizable.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ E2F627641F063842005D8026 /* en */,
+ E28ECE001F065383004FCEA6 /* nl */,
+ E214EF681F0A2C41009A7E3A /* fr */,
+ E214EF691F0A2C49009A7E3A /* de */,
+ E214EF6A1F0A2C51009A7E3A /* es */,
+ E2AB20EE1F0A31400006FF2A /* it */,
+ E2AB20F01F0A65000006FF2A /* pt */,
+ E2AB20F11F0A650D0006FF2A /* sv */,
+ );
+ name = Localizable.strings;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ E20AD01B1EFAB0310065B70E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1.4.0;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Debug;
+ };
+ E20AD01C1EFAB0310065B70E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1.4.0;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Release;
+ };
+ E20AD01E1EFAB0310065B70E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 20191199750F47C401152B90 /* Pods-Adyen.debug.xcconfig */;
+ buildSettings = {
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = "";
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1.4.0;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = Adyen/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.Adyen;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ E20AD01F1EFAB0310065B70E /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 39B692648B2F9A2E64860876 /* Pods-Adyen.release.xcconfig */;
+ buildSettings = {
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = "";
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1.4.0;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = Adyen/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.Adyen;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
+ E20AD0211EFAB0310065B70E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7370242B72CA01D6FB771E34 /* Pods-AdyenTests.debug.xcconfig */;
+ buildSettings = {
+ INFOPLIST_FILE = AdyenTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ E20AD0221EFAB0310065B70E /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = EEDFC6FAA3826763FD1E99D3 /* Pods-AdyenTests.release.xcconfig */;
+ buildSettings = {
+ INFOPLIST_FILE = AdyenTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
+ E2BF6CC91F03952D0065E574 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ INFOPLIST_FILE = AdyenUITests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenUITests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
+ TEST_TARGET_NAME = AdyenUIHost;
+ };
+ name = Debug;
+ };
+ E2BF6CCA1F03952D0065E574 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ INFOPLIST_FILE = AdyenUITests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenUITests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 3.0;
+ TEST_TARGET_NAME = AdyenUIHost;
+ };
+ name = Release;
+ };
+ E2E9D02A1F0389C80056E0AC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9D45EFB0559159A56AFB2ED0 /* Pods-AdyenUIHost.debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = AdyenUIHost/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenUIHost;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ E2E9D02B1F0389C80056E0AC /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 4D2C0B04986E87ADFBF3FD11 /* Pods-AdyenUIHost.release.xcconfig */;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = AdyenUIHost/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.AdyenUIHost;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ E20AD0031EFAB0310065B70E /* Build configuration list for PBXProject "Adyen" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E20AD01B1EFAB0310065B70E /* Debug */,
+ E20AD01C1EFAB0310065B70E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ E20AD01D1EFAB0310065B70E /* Build configuration list for PBXNativeTarget "Adyen" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E20AD01E1EFAB0310065B70E /* Debug */,
+ E20AD01F1EFAB0310065B70E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ E20AD0201EFAB0310065B70E /* Build configuration list for PBXNativeTarget "AdyenTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E20AD0211EFAB0310065B70E /* Debug */,
+ E20AD0221EFAB0310065B70E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ E2BF6CC81F03952D0065E574 /* Build configuration list for PBXNativeTarget "AdyenUITests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E2BF6CC91F03952D0065E574 /* Debug */,
+ E2BF6CCA1F03952D0065E574 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ E2E9D02C1F0389C80056E0AC /* Build configuration list for PBXNativeTarget "AdyenUIHost" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E2E9D02A1F0389C80056E0AC /* Debug */,
+ E2E9D02B1F0389C80056E0AC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = E20AD0001EFAB0310065B70E /* Project object */;
+}
diff --git a/Example/2-custom-integration-example/Advanced.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Adyen.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 71%
rename from Example/2-custom-integration-example/Advanced.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to Adyen.xcodeproj/project.xcworkspace/contents.xcworkspacedata
index 66e100c0e5..9177a9816f 100644
--- a/Example/2-custom-integration-example/Advanced.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ b/Adyen.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -2,6 +2,6 @@
+ location = "self:Adyen.xcodeproj">
diff --git a/Example/1-quick-integration-example/ShoppingApp.xcodeproj/xcshareddata/xcschemes/ShoppingApp.xcscheme b/Adyen.xcodeproj/xcshareddata/xcschemes/Adyen.xcscheme
similarity index 60%
rename from Example/1-quick-integration-example/ShoppingApp.xcodeproj/xcshareddata/xcschemes/ShoppingApp.xcscheme
rename to Adyen.xcodeproj/xcshareddata/xcschemes/Adyen.xcscheme
index 0502f10e27..104ef93850 100644
--- a/Example/1-quick-integration-example/ShoppingApp.xcodeproj/xcshareddata/xcschemes/ShoppingApp.xcscheme
+++ b/Adyen.xcodeproj/xcshareddata/xcschemes/Adyen.xcscheme
@@ -14,10 +14,10 @@
buildForAnalyzing = "YES">
+ BlueprintIdentifier = "E20AD0081EFAB0310065B70E"
+ BuildableName = "Adyen.framework"
+ BlueprintName = "Adyen"
+ ReferencedContainer = "container:Adyen.xcodeproj">
@@ -32,30 +32,20 @@
skipped = "NO">
-
-
-
-
+ ReferencedContainer = "container:Adyen.xcodeproj">
+ BlueprintIdentifier = "E20AD0081EFAB0310065B70E"
+ BuildableName = "Adyen.framework"
+ BlueprintName = "Adyen"
+ ReferencedContainer = "container:Adyen.xcodeproj">
@@ -71,16 +61,15 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
-
+
+ BlueprintIdentifier = "E20AD0081EFAB0310065B70E"
+ BuildableName = "Adyen.framework"
+ BlueprintName = "Adyen"
+ ReferencedContainer = "container:Adyen.xcodeproj">
-
+
@@ -90,16 +79,15 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
-
+
+ BlueprintIdentifier = "E20AD0081EFAB0310065B70E"
+ BuildableName = "Adyen.framework"
+ BlueprintName = "Adyen"
+ ReferencedContainer = "container:Adyen.xcodeproj">
-
+
diff --git a/Example/2-custom-integration-example/Advanced.xcworkspace/contents.xcworkspacedata b/Adyen.xcworkspace/contents.xcworkspacedata
similarity index 80%
rename from Example/2-custom-integration-example/Advanced.xcworkspace/contents.xcworkspacedata
rename to Adyen.xcworkspace/contents.xcworkspacedata
index fea1c60fe1..9b11c9bbef 100644
--- a/Example/2-custom-integration-example/Advanced.xcworkspace/contents.xcworkspacedata
+++ b/Adyen.xcworkspace/contents.xcworkspacedata
@@ -2,7 +2,7 @@
+ location = "group:Adyen.xcodeproj">
diff --git a/Adyen/Adyen.h b/Adyen/Adyen.h
new file mode 100644
index 0000000000..5bd21cf92e
--- /dev/null
+++ b/Adyen/Adyen.h
@@ -0,0 +1,13 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+#import
+
+//! Project version number for Adyen.
+FOUNDATION_EXPORT double AdyenVersionNumber;
+
+//! Project version string for Adyen.
+FOUNDATION_EXPORT const unsigned char AdyenVersionString[];
diff --git a/Adyen/Core/BasePlugin.swift b/Adyen/Core/BasePlugin.swift
index e8faf8296f..f9e55be208 100644
--- a/Adyen/Core/BasePlugin.swift
+++ b/Adyen/Core/BasePlugin.swift
@@ -19,15 +19,6 @@ class BasePlugin: NSObject {
return UIApplication.shared.keyWindow?.rootViewController
}
- var isRedirectType: Bool {
- // Groupped methods are not redirects.
- guard let method = self.method, method.members != nil else {
- return false
- }
-
- return method.inputDetails.count == 0
- }
-
public required override init() {
super.init()
}
@@ -79,10 +70,6 @@ class BasePlugin: NSObject {
return providedPaymentData
}
- func linnearFlow() -> Bool {
- return false
- }
-
func reset() {
providedPaymentData = nil
}
diff --git a/Adyen/Core/Enum/Error.swift b/Adyen/Core/Enum/Error.swift
index f35a71d956..4f725fadce 100644
--- a/Adyen/Core/Enum/Error.swift
+++ b/Adyen/Core/Enum/Error.swift
@@ -25,6 +25,7 @@ public enum Error: Swift.Error {
/// Payment was canceled.
case canceled
+
}
extension Error: LocalizedError {
diff --git a/Adyen/Core/Extensions/ArrayExtensions.swift b/Adyen/Core/Extensions/ArrayExtensions.swift
index 0ae80a6136..7d8814822d 100644
--- a/Adyen/Core/Extensions/ArrayExtensions.swift
+++ b/Adyen/Core/Extensions/ArrayExtensions.swift
@@ -37,3 +37,17 @@ internal extension Array {
return groups
}
}
+
+internal extension Optional where Wrapped: Collection {
+
+ /// Returns a boolean value indicating whether the wrapped collection is either nil or empty.
+ internal var isNilOrEmpty: Bool {
+ switch self {
+ case let .some(array):
+ return array.isEmpty
+ case .none:
+ return true
+ }
+ }
+
+}
diff --git a/Adyen/Core/Extensions/StringExtensions.swift b/Adyen/Core/Extensions/StringExtensions.swift
index 8371c7493c..968dfa3e49 100644
--- a/Adyen/Core/Extensions/StringExtensions.swift
+++ b/Adyen/Core/Extensions/StringExtensions.swift
@@ -38,4 +38,24 @@ extension String {
let lowerBound = range.lowerBound < 0 ? 0 : range.lowerBound
return substring(with: lowerIndex..<(index(lowerIndex, offsetBy: range.upperBound - lowerBound + 1, limitedBy: endIndex) ?? endIndex))
}
+
+ /// Separates the string into groups of the given length.
+ ///
+ /// - Parameters:
+ /// - length: The maximum length of the groups the string should be separated in.
+ /// - separator: The separator to use inbetween the groups.
+ /// - Returns: A grouped string.
+ internal func grouped(length: Int, separator: String = " ") -> String {
+ let groups = stride(from: 0, to: characters.count, by: length).map { index -> String in
+ let startIndex = self.index(self.startIndex, offsetBy: index)
+
+ let offset = min(length, self.distance(from: startIndex, to: self.endIndex))
+ let endIndex = self.index(startIndex, offsetBy: offset)
+
+ return self.substring(with: startIndex.. Bool {
@@ -85,15 +89,7 @@ public final class PaymentMethod {
}
func requiresPaymentData() -> Bool {
- return !inputDetails.isEmpty && plugin?.fullfilledFields() == nil
- }
-
- func canProvideUI() -> Bool {
- guard (plugin as? UIPresentable) != nil else {
- return false
- }
-
- return true
+ return inputDetails?.isEmpty == false && plugin?.fullfilledFields() == nil
}
func requiresURLAuth() -> Bool {
@@ -107,7 +103,7 @@ public final class PaymentMethod {
internal extension PaymentMethod {
- convenience init?(info: [String: Any], logoBaseURL: String, oneClick: Bool = false) {
+ convenience init?(info: [String: Any], logoBaseURL: String, isOneClick: Bool) {
guard
let type = info["type"] as? String,
let data = info["paymentMethodData"] as? String,
@@ -117,7 +113,6 @@ internal extension PaymentMethod {
}
var displayName = name
-
if let cardInfo = info["card"] as? [String: Any],
let digits = cardInfo["number"] as? String {
displayName = "•••• \(digits)"
@@ -125,37 +120,59 @@ internal extension PaymentMethod {
displayName = emailInfo
}
- self.init(name: name, displayName: displayName, type: type, oneClick: oneClick)
+ let logoURL = URL(string: logoBaseURL + type + UIScreen.retinaExtension() + ".png")
+ let inputDetails = (info["inputDetails"] as? [[String: Any]])?.flatMap { InputDetail(info: $0) }
+
+ var group: Group?
+ if let groupInfo = info["group"] as? [String: Any] {
+ group = Group(info: groupInfo)
+ }
+
+ self.init(name: displayName, type: type, isOneClick: isOneClick, logoURL: logoURL, inputDetails: inputDetails, members: nil, group: group)
paymentMethodData = data
configuration = info["configuration"] as? [String: Any]
self.logoBaseURL = logoBaseURL
- logoURL = URL(string: logoBaseURL + type + UIScreen.retinaExtension() + ".png")
-
- if let inputDetails = info["inputDetails"] as? [[String: Any]] {
- self.inputDetails = inputDetails.flatMap({ InputDetail(info: $0) })
- }
-
- if let groupInfo = info["group"] as? [String: Any] {
- group = PaymentMethodGroup(info: groupInfo)
- }
}
- convenience init?(group: [PaymentMethod]) {
- guard group.count > 0 else {
+ convenience init?(members: [PaymentMethod]) {
+ guard members.count > 0 else {
return nil
}
- let method = group[0]
+ let method = members[0]
+ let group = method.group!
- self.init(name: method.group!.name, displayName: method.group!.name, type: method.group!.type)
+ self.init(name: group.name, type: group.type, isOneClick: false, logoURL: method.groupLogoURL, inputDetails: method.inputDetails, members: members, group: nil)
- members = group
- logoURL = method.groupLogoURL
- inputDetails = method.inputDetails
paymentMethodData = method.group!.data
}
+
+ internal struct Group {
+
+ internal let type: String
+
+ internal let name: String
+
+ internal let data: String
+
+ internal init?(info: [String: Any]) {
+ guard
+ let type = info["type"] as? String,
+ let name = info["name"] as? String,
+ let data = info["paymentMethodData"] as? String
+ else {
+ return nil
+ }
+
+ self.type = type
+ self.name = name
+ self.data = data
+ }
+
+ }
+
}
extension PaymentMethod: Equatable {
@@ -165,3 +182,15 @@ extension PaymentMethod: Equatable {
return lhs.name == rhs.name && lhs.type == rhs.type
}
}
+
+// MARK: - Deprecated
+
+public extension PaymentMethod {
+
+ /// A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user.
+ @available(*, deprecated, message: "Use isOneClick instead.")
+ public var oneClick: Bool {
+ return isOneClick
+ }
+
+}
diff --git a/Adyen/Core/PaymentMethodGroup.swift b/Adyen/Core/PaymentMethodGroup.swift
deleted file mode 100644
index 39d8e63a3c..0000000000
--- a/Adyen/Core/PaymentMethodGroup.swift
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (c) 2017 Adyen B.V.
-//
-// This file is open source and available under the MIT license. See the LICENSE file for more info.
-//
-
-import Foundation
-
-class PaymentMethodGroup {
-
- let type: String
- let name: String
- let data: String
-
- init(type: String, name: String, data: String) {
- self.type = type
- self.name = name
- self.data = data
- }
-
- convenience init?(info: [String: Any]) {
-
- guard
- let type = info["type"] as? String,
- let name = info["name"] as? String,
- let data = info["paymentMethodData"] as? String
- else {
- return nil
- }
-
- self.init(type: type, name: name, data: data)
- }
-}
diff --git a/Adyen/Core/PaymentRequest.swift b/Adyen/Core/PaymentRequest.swift
index aaff8732ce..830f334ff0 100644
--- a/Adyen/Core/PaymentRequest.swift
+++ b/Adyen/Core/PaymentRequest.swift
@@ -18,34 +18,34 @@ public typealias PaymentDetailsCompletion = (PaymentDetails) -> Void
public final class PaymentRequest {
/// Delegate for controlling the payment flow. See `PaymentRequestDelegate`.
- internal(set) public weak var delegate: PaymentRequestDelegate?
+ public internal(set) weak var delegate: PaymentRequestDelegate?
/// The selected payment method.
- private(set) public var paymentMethod: PaymentMethod?
+ public private(set) var paymentMethod: PaymentMethod?
/// Amount to be charged.
- private(set) public var amount: Int?
+ public private(set) var amount: Int?
/// Payment currency.
- private(set) public var currency: String?
+ public private(set) var currency: String?
/// Payment reference.
- private(set) public var reference: String?
+ public private(set) var reference: String?
/// Payment country code.
- private(set) public var countryCode: String?
+ public private(set) var countryCode: String?
/// Shopper locale.
- private(set) public var shopperLocale: String?
+ public private(set) var shopperLocale: String?
/// Shopper reference.
- private(set) public var shopperReference: String?
+ public private(set) var shopperReference: String?
/// Generation time. Used for generating a token for card payments.
- private(set) public var generationTime: String?
+ public private(set) var generationTime: String?
/// Public key. Used for generating a token for card payments.
- private(set) public var publicKey: String?
+ public private(set) var publicKey: String?
var paymentRequest: InternalPaymentRequest?
@@ -300,21 +300,21 @@ public final class PaymentRequest {
return
}
- let available = methodsInfo.flatMap({ PaymentMethod(info: $0, logoBaseURL: payment.logoBaseURL) })
+ let available = methodsInfo.flatMap { PaymentMethod(info: $0, logoBaseURL: payment.logoBaseURL, isOneClick: false) }
// Group available PM's
let groupped = available.groupBy { element in
return element.group?.type ?? UUID().uuidString
}
- let availableGroupped = groupped.flatMap { group -> PaymentMethod? in
- return group.count == 1 ? group[0] : PaymentMethod(group: group)
+ let availableGroupped = groupped.flatMap { members -> PaymentMethod? in
+ return members.count == 1 ? members[0] : PaymentMethod(members: members)
}
// Parse one-click methods
var preferredMethods = [PaymentMethod]()
if let recurringDetails = info["recurringDetails"] as? [[String: Any]] {
- preferredMethods = recurringDetails.flatMap({ PaymentMethod(info: $0, logoBaseURL: payment.logoBaseURL, oneClick: true) })
+ preferredMethods = recurringDetails.flatMap({ PaymentMethod(info: $0, logoBaseURL: payment.logoBaseURL, isOneClick: true) })
}
completion(preferredMethods, availableGroupped, nil)
@@ -398,7 +398,10 @@ internal extension PaymentRequest {
return
}
- let result = Payment(payment: paymentRequest, status: status, payload: payload)
+ let result = Payment(status: status,
+ method: paymentMethod!,
+ payload: payload,
+ internalRequest: paymentRequest)
processorFinished(with: result)
}
diff --git a/Adyen/Core/Protocols/PaymentRequestDelegate.swift b/Adyen/Core/Protocols/PaymentRequestDelegate.swift
index e02b298969..b909b944a2 100644
--- a/Adyen/Core/Protocols/PaymentRequestDelegate.swift
+++ b/Adyen/Core/Protocols/PaymentRequestDelegate.swift
@@ -21,4 +21,5 @@ public protocol PaymentRequestDelegate: class {
/// This method is called when the payment flow is finished.
func paymentRequest(_ request: PaymentRequest, didFinishWith result: PaymentRequestResult)
+
}
diff --git a/Adyen/Core/Version.swift b/Adyen/Core/Version.swift
index 5b38b98704..69e817bbbf 100644
--- a/Adyen/Core/Version.swift
+++ b/Adyen/Core/Version.swift
@@ -7,11 +7,10 @@
import Foundation
var sdkVersion: String {
- if let file = Bundle(for: PaymentRequest.self).path(forResource: "VERSION", ofType: ""),
- let lines = try? String(contentsOfFile: file).components(separatedBy: .newlines),
- let version = lines.first {
- return version
+ let bundle = Bundle(for: PaymentRequest.self)
+ guard let version = bundle.infoDictionary?["CFBundleShortVersionString"] as? String else {
+ fatalError("Failed to read version number from Info.plist.")
}
- fatalError("Could not read VERSION file")
+ return version
}
diff --git a/Adyen/CoreUI/AppearanceConfiguration.swift b/Adyen/CoreUI/AppearanceConfiguration.swift
new file mode 100644
index 0000000000..d0b51dcbff
--- /dev/null
+++ b/Adyen/CoreUI/AppearanceConfiguration.swift
@@ -0,0 +1,124 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+/// Provides properties to customize the appearance of the UI components provided by this library.
+/// Note that `AppearanceConfiguration` is only used when the `CheckoutViewController` is first initialized. Changes to this object after it has been created are ignored.
+public final class AppearanceConfiguration {
+
+ /// Initializes the appearance configuration.
+ public init() {
+
+ }
+
+ // MARK: Status Bar
+
+ /// The preferred status bar style.
+ public var preferredStatusBarStyle = UIStatusBarStyle.default
+
+ // MARK: Navigation Bar
+
+ /// The attributes used for the navigation bar's title.
+ public var navigationBarTitleTextAttributes: [String: Any]?
+
+ /// The navigation bar's tint color.
+ public var navigationBarTintColor: UIColor?
+
+ /// The navigation bar's background color.
+ public var navigationBarBackgroundColor: UIColor?
+
+ /// A Boolean value indicating whether the navigation bar is translucent.
+ public var isNavigationBarTranslucent = true
+
+ /// The image of the cancel button in the navigation bar, or `nil` if a title should be used instead.
+ public var navigationBarCancelButtonImage: UIImage?
+
+ // MARK: Checkout Button
+
+ /// The attributes used for the checkout button's title.
+ public var checkoutButtonTitleTextAttributes: [String: Any]?
+
+ /// The insets from the edges of the checkout button to the title.
+ public var checkoutButtonTitleEdgeInsets: UIEdgeInsets?
+
+ /// The corner radius of the checkout button.
+ public var checkoutButtonCornerRadius: CGFloat = 0.0
+
+ // MARK: Other
+
+ /// The tint color of most buttons and actionable elements.
+ public var tintColor: UIColor?
+
+ // MARK: Default Configuration
+
+ /// The default appearance configuration.
+ public static var `default`: AppearanceConfiguration = {
+ let appearanceConfiguration = AppearanceConfiguration()
+ appearanceConfiguration.navigationBarTitleTextAttributes = [
+ NSFontAttributeName: UIFont.systemFont(ofSize: 18.0),
+ NSForegroundColorAttributeName: UIColor.checkoutDarkGray
+ ]
+ appearanceConfiguration.navigationBarTintColor = UIColor.checkoutDarkGray
+ appearanceConfiguration.navigationBarBackgroundColor = UIColor.white
+ appearanceConfiguration.isNavigationBarTranslucent = false
+ appearanceConfiguration.navigationBarCancelButtonImage = UIImage.bundleImage("close")
+
+ appearanceConfiguration.checkoutButtonTitleTextAttributes = [
+ NSFontAttributeName: UIFont.systemFont(ofSize: 18.0),
+ NSForegroundColorAttributeName: UIColor.white
+ ]
+ appearanceConfiguration.checkoutButtonTitleEdgeInsets = UIEdgeInsets(top: 16.0, left: 0.0, bottom: 16.0, right: 0.0)
+ appearanceConfiguration.checkoutButtonCornerRadius = 4.0
+
+ appearanceConfiguration.tintColor = #colorLiteral(red: 0.03921568627, green: 0.7490196078, blue: 0.3254901961, alpha: 1)
+
+ return appearanceConfiguration
+ }()
+
+}
+
+extension AppearanceConfiguration: NSCopying {
+
+ /// :nodoc:
+ public func copy(with zone: NSZone? = nil) -> Any {
+ let appearanceConfiguration = AppearanceConfiguration()
+ appearanceConfiguration.preferredStatusBarStyle = preferredStatusBarStyle
+ appearanceConfiguration.navigationBarTitleTextAttributes = navigationBarTitleTextAttributes
+ appearanceConfiguration.navigationBarTintColor = navigationBarTintColor
+ appearanceConfiguration.navigationBarBackgroundColor = navigationBarBackgroundColor
+ appearanceConfiguration.isNavigationBarTranslucent = isNavigationBarTranslucent
+ appearanceConfiguration.navigationBarCancelButtonImage = navigationBarCancelButtonImage
+ appearanceConfiguration.checkoutButtonTitleTextAttributes = checkoutButtonTitleTextAttributes
+ appearanceConfiguration.checkoutButtonTitleEdgeInsets = checkoutButtonTitleEdgeInsets
+ appearanceConfiguration.checkoutButtonCornerRadius = checkoutButtonCornerRadius
+ appearanceConfiguration.tintColor = tintColor
+
+ return appearanceConfiguration
+ }
+
+ /// Creates and returns a copied version of the receiver.
+ internal var copied: AppearanceConfiguration {
+ return copy() as! AppearanceConfiguration // swiftlint:disable:this force_cast
+ }
+
+}
+
+internal extension AppearanceConfiguration {
+
+ internal func cancelButtonItem(target: Any, selector: Selector) -> UIBarButtonItem {
+ var cancelButtonItem: UIBarButtonItem!
+ if let cancelButtonImage = navigationBarCancelButtonImage {
+ cancelButtonItem = UIBarButtonItem(image: cancelButtonImage, style: .plain, target: target, action: selector)
+ cancelButtonItem.accessibilityLabel = ADYLocalizedString("cancelButton.title")
+ } else {
+ cancelButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: target, action: selector)
+ }
+
+ return cancelButtonItem
+ }
+
+}
diff --git a/Adyen/CoreUI/Assets/.gitkeep b/Adyen/CoreUI/Assets/.gitkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/Contents.json b/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/Contents.json
deleted file mode 100644
index 3340abb0b1..0000000000
--- a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/Contents.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "filename" : "back-button.png",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "filename" : "back-button@2x.png",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "filename" : "back-button@3x.png",
- "scale" : "3x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button.png b/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button.png
deleted file mode 100644
index ab0b7782de..0000000000
Binary files a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button.png and /dev/null differ
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@2x.png b/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@2x.png
deleted file mode 100644
index cfa2fc9e3f..0000000000
Binary files a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@2x.png and /dev/null differ
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@3x.png b/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@3x.png
deleted file mode 100644
index 528b4e5b56..0000000000
Binary files a/Adyen/CoreUI/Assets/Media.xcassets/back-button.imageset/back-button@3x.png and /dev/null differ
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/Contents.json b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/Contents.json
index afe31cefcd..529efd661f 100644
--- a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/Contents.json
+++ b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/Contents.json
@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
}
}
\ No newline at end of file
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active.png
index 8e7f533820..a8f00ce411 100644
Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active.png differ
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@2x.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@2x.png
index 8840886d93..08883848d2 100644
Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@2x.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@2x.png differ
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@3x.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@3x.png
index aaaf036e74..b6de5a34ca 100644
Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@3x.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_active.imageset/checkbox_active@3x.png differ
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/Contents.json b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/Contents.json
index ee217d61ff..a1a1a18dbd 100644
--- a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/Contents.json
+++ b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/Contents.json
@@ -19,5 +19,8 @@
"info" : {
"version" : 1,
"author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
}
}
\ No newline at end of file
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive.png
index 7978455d4a..84b12f58af 100644
Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive.png differ
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@2x.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@2x.png
index c07a4c4086..60751a269c 100644
Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@2x.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@2x.png differ
diff --git a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@3x.png b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@3x.png
index 51a129c53b..4f725ba8db 100644
Binary files a/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@3x.png and b/Adyen/CoreUI/Assets/Media.xcassets/checkbox_inactive.imageset/checkbox_inactive@3x.png differ
diff --git a/Adyen/CoreUI/Assets/de.lproj/Localizable.strings b/Adyen/CoreUI/Assets/de.lproj/Localizable.strings
new file mode 100644
index 0000000000..187cbbc1f8
--- /dev/null
+++ b/Adyen/CoreUI/Assets/de.lproj/Localizable.strings
@@ -0,0 +1,26 @@
+"paymentMethods.title" = "Bezahlmöglichkeiten";
+"paymentMethods.storedMethods.title" = "Ihre Bezahlmethoden";
+"paymentMethods.otherMethods.title" = "Andere Bezahlmöglichkeiten";
+"creditCard.title" = "Karteneingabe";
+"creditCard.numberField.title" = "Kartennummer";
+"creditCard.numberField.placeholder" = "1234 5678 9012 3456";
+"creditCard.expiryDateField.title" = "Verfalldatum";
+"creditCard.expiryDateField.placeholder" = "MM/JJ";
+"creditCard.cvcField.title" = "CVC / CVV";
+"creditCard.cvcField.placeholder" = "123";
+"creditCard.storeDetailsButton.title" = "Karte speichern";
+"creditCard.oneClickVerification.title" = "Karte verifizieren";
+"creditCard.oneClickVerification.message" = "Bitte CVC code fĂĽr %@ eingeben.";
+"creditCard.oneClickVerification.invalidInput.title" = "Ungültiger Bestätigungscode";
+"creditCard.oneClickVerification.invalidInput.message" = "Bitte geben Sie einen gültigen Bestätigungscode ein.";
+"sepaDirectDebit.ibanField.title" = "Kontonummer (IBAN)";
+"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122";
+"sepaDirectDebit.nameField.title" = "Name des Kontoinhabers";
+"sepaDirectDebit.nameField.placeholder" = "L. Schmidt";
+"sepaDirectDebit.consentButton.title" = "Ich bin damit einverstanden, dass der folgende genannten Betrage von meinem Konto abgebucht wird.";
+"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl";
+"giropay.minimumLength.title" = "Mindestens drei Zeichen";
+"cancelButton.title" = "Abbrechen";
+"dismissButton.title" = "Okay";
+"payButton.title" = "Zahlen";
+"payButton.title.formatted" = "%@ bezahlen";
diff --git a/Adyen/CoreUI/Assets/en.lproj/Localizable.strings b/Adyen/CoreUI/Assets/en.lproj/Localizable.strings
new file mode 100644
index 0000000000..a13aae5aa5
--- /dev/null
+++ b/Adyen/CoreUI/Assets/en.lproj/Localizable.strings
@@ -0,0 +1,26 @@
+"paymentMethods.title" = "Payment Methods";
+"paymentMethods.storedMethods.title" = "Your payment methods";
+"paymentMethods.otherMethods.title" = "Select other method";
+"creditCard.title" = "Card Details";
+"creditCard.numberField.title" = "Card Number";
+"creditCard.numberField.placeholder" = "1234 5678 9012 3456";
+"creditCard.expiryDateField.title" = "Expiry Date";
+"creditCard.expiryDateField.placeholder" = "MM/YY";
+"creditCard.cvcField.title" = "CVC / CVV";
+"creditCard.cvcField.placeholder" = "123";
+"creditCard.storeDetailsButton.title" = "Remember this card for my next payment";
+"creditCard.oneClickVerification.title" = "Verify your card";
+"creditCard.oneClickVerification.message" = "Please enter the CVC code for %@";
+"creditCard.oneClickVerification.invalidInput.title" = "Invalid CVC";
+"creditCard.oneClickVerification.invalidInput.message" = "Please enter a valid CVC to continue.";
+"sepaDirectDebit.ibanField.title" = "Account Number (IBAN)";
+"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122";
+"sepaDirectDebit.nameField.title" = "Holder Name";
+"sepaDirectDebit.nameField.placeholder" = "J. Smith";
+"sepaDirectDebit.consentButton.title" = "I agree that the amount below will be debited from my bank account.";
+"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl";
+"giropay.minimumLength.title" = "Min. 3 characters";
+"cancelButton.title" = "Cancel";
+"dismissButton.title" = "OK";
+"payButton.title" = "Pay";
+"payButton.title.formatted" = "Pay %@";
diff --git a/Adyen/CoreUI/Assets/es.lproj/Localizable.strings b/Adyen/CoreUI/Assets/es.lproj/Localizable.strings
new file mode 100644
index 0000000000..a69b10706d
--- /dev/null
+++ b/Adyen/CoreUI/Assets/es.lproj/Localizable.strings
@@ -0,0 +1,26 @@
+"paymentMethods.title" = "MĂ©todos de pago";
+"paymentMethods.storedMethods.title" = "MĂ©todos de pago anteriores";
+"paymentMethods.otherMethods.title" = "Otros métodos de pago";
+"creditCard.title" = "Detalles de la tarjeta";
+"creditCard.numberField.title" = "NĂşmero de tarjeta";
+"creditCard.numberField.placeholder" = "1234 5678 9012 3456";
+"creditCard.expiryDateField.title" = "Fecha de caducidad";
+"creditCard.expiryDateField.placeholder" = "MM/AA";
+"creditCard.cvcField.title" = "CVC / CVV";
+"creditCard.cvcField.placeholder" = "123";
+"creditCard.storeDetailsButton.title" = "Recordar estos detalles";
+"creditCard.oneClickVerification.title" = "Validar tarjeta";
+"creditCard.oneClickVerification.message" = "Porfavor entre el nĂşmero CVC para %@";
+"creditCard.oneClickVerification.invalidInput.title" = "CĂłdigo de verificaciĂłn invalido";
+"creditCard.oneClickVerification.invalidInput.message" = "Por favor, introduzca un código de verificación válido.";
+"sepaDirectDebit.ibanField.title" = "NĂşmero de cuenta (IBAN)";
+"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122";
+"sepaDirectDebit.nameField.title" = "Nombre del titular de cuenta";
+"sepaDirectDebit.nameField.placeholder" = "C. Smith";
+"sepaDirectDebit.consentButton.title" = "Estoy de acuerdo en que la cantidad descripta será deducida de mi cuenta bancaria.";
+"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl";
+"giropay.minimumLength.title" = "MĂnimo 3 caracteres";
+"cancelButton.title" = "Cancelar";
+"dismissButton.title" = "Okay";
+"payButton.title" = "Pagar";
+"payButton.title.formatted" = "Pagar %@";
diff --git a/Adyen/CoreUI/Assets/fr.lproj/Localizable.strings b/Adyen/CoreUI/Assets/fr.lproj/Localizable.strings
new file mode 100644
index 0000000000..4988b53ab1
--- /dev/null
+++ b/Adyen/CoreUI/Assets/fr.lproj/Localizable.strings
@@ -0,0 +1,26 @@
+"paymentMethods.title" = "MĂ©thodes de paiement";
+"paymentMethods.storedMethods.title" = "Votre méthodes the paiement";
+"paymentMethods.otherMethods.title" = "Autre méthode de paiement";
+"creditCard.title" = "DĂ©tails de paiement";
+"creditCard.numberField.title" = "Numéro de carte";
+"creditCard.numberField.placeholder" = "1234 5678 9012 3456";
+"creditCard.expiryDateField.title" = "Date d'expiration";
+"creditCard.expiryDateField.placeholder" = "MM/AA";
+"creditCard.cvcField.title" = "CVC / CVV";
+"creditCard.cvcField.placeholder" = "123";
+"creditCard.storeDetailsButton.title" = "Se souvenir de ma carte";
+"creditCard.oneClickVerification.title" = "VĂ©rifiez votre carte";
+"creditCard.oneClickVerification.message" = "Entrez votre CVC code pour %@ s'il vous plaît.";
+"creditCard.oneClickVerification.invalidInput.title" = "Code de vérification invalide";
+"creditCard.oneClickVerification.invalidInput.message" = "S'il vous plaît entrer un code de vérification valide.";
+"sepaDirectDebit.ibanField.title" = "Numéro de compte (IBAN)";
+"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122";
+"sepaDirectDebit.nameField.title" = "Au nom de";
+"sepaDirectDebit.nameField.placeholder" = "N. Bernard";
+"sepaDirectDebit.consentButton.title" = "J'accepte que le montant ci-dessous soit débité de mon compte bancaire.";
+"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl";
+"giropay.minimumLength.title" = "3 caractères minimum";
+"cancelButton.title" = "Annuler";
+"dismissButton.title" = "OK";
+"payButton.title" = "Valider";
+"payButton.title.formatted" = "Payer %@";
diff --git a/Adyen/CoreUI/Assets/it.lproj/Localizable.strings b/Adyen/CoreUI/Assets/it.lproj/Localizable.strings
new file mode 100644
index 0000000000..372d461246
--- /dev/null
+++ b/Adyen/CoreUI/Assets/it.lproj/Localizable.strings
@@ -0,0 +1,26 @@
+"paymentMethods.title" = "Metodo di Pagamento";
+"paymentMethods.storedMethods.title" = "Metodi di pagamento";
+"paymentMethods.otherMethods.title" = "Scegli altro metodo di pagamento";
+"creditCard.title" = "Dettagli Carta";
+"creditCard.numberField.title" = "Numero di Carta";
+"creditCard.numberField.placeholder" = "1234 5678 9012 3456";
+"creditCard.expiryDateField.title" = "Data di Scadenza";
+"creditCard.expiryDateField.placeholder" = "MM/AA";
+"creditCard.cvcField.title" = "CVC / CVV";
+"creditCard.cvcField.placeholder" = "123";
+"creditCard.storeDetailsButton.title" = "Salva i Dettagli della Carta";
+"creditCard.oneClickVerification.title" = "Verifica la Carta";
+"creditCard.oneClickVerification.message" = "Inserire il codice CVC per %@";
+"creditCard.oneClickVerification.invalidInput.title" = "Codice di verifica non valido.";
+"creditCard.oneClickVerification.invalidInput.message" = "Si prega di inserire un codice di verifica valido.";
+"sepaDirectDebit.ibanField.title" = "Numero di conto (IBAN)";
+"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122";
+"sepaDirectDebit.nameField.title" = "Nome Intestatario Conto";
+"sepaDirectDebit.nameField.placeholder" = "A. Bianchi";
+"sepaDirectDebit.consentButton.title" = "Accetto che l'importo indicato sia addebitato sul mio conto corrente.";
+"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl";
+"giropay.minimumLength.title" = "MĂnimo 3 caracteres";
+"cancelButton.title" = "Annulla";
+"dismissButton.title" = "OK";
+"payButton.title" = "Paga";
+"payButton.title.formatted" = "Paga %@";
diff --git a/Adyen/CoreUI/Assets/nl.lproj/Localizable.strings b/Adyen/CoreUI/Assets/nl.lproj/Localizable.strings
new file mode 100644
index 0000000000..c3b1d51ae6
--- /dev/null
+++ b/Adyen/CoreUI/Assets/nl.lproj/Localizable.strings
@@ -0,0 +1,26 @@
+"paymentMethods.title" = "Betaalmethodes";
+"paymentMethods.storedMethods.title" = "Opgeslagen betaalmethodes";
+"paymentMethods.otherMethods.title" = "Alle betaalmethodes";
+"creditCard.title" = "Kaartgegevens";
+"creditCard.numberField.title" = "Kaartnummer";
+"creditCard.numberField.placeholder" = "1234 5678 9012 3456";
+"creditCard.expiryDateField.title" = "Vervaldatum";
+"creditCard.expiryDateField.placeholder" = "MM/JJ";
+"creditCard.cvcField.title" = "Verificatiecode";
+"creditCard.cvcField.placeholder" = "123";
+"creditCard.storeDetailsButton.title" = "Bewaar deze kaart voor mijn volgende betaling";
+"creditCard.oneClickVerification.title" = "Verifieer uw kaart";
+"creditCard.oneClickVerification.message" = "Voer de verificatiecode in voor %@";
+"creditCard.oneClickVerification.invalidInput.title" = "Ongeldige verificatiecode";
+"creditCard.oneClickVerification.invalidInput.message" = "Gelieve een geldige verificatiecode in te voeren om de betaling af te ronden.";
+"sepaDirectDebit.ibanField.title" = "Rekeningnummer (IBAN)";
+"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122";
+"sepaDirectDebit.nameField.title" = "Ten name van";
+"sepaDirectDebit.nameField.placeholder" = "P. de Ridder";
+"sepaDirectDebit.consentButton.title" = "Ik ga akkoord met een eenmalige afschrijving van het onderstaande bedrag.";
+"giropay.searchField.placeholder" = "Banknaam / BIC / Bankleitzahl";
+"giropay.minimumLength.title" = "Min. 3 karakters";
+"cancelButton.title" = "Annuleer";
+"dismissButton.title" = "Oké";
+"payButton.title" = "Betaal";
+"payButton.title.formatted" = "Betaal %@";
diff --git a/Adyen/CoreUI/Assets/pt.lproj/Localizable.strings b/Adyen/CoreUI/Assets/pt.lproj/Localizable.strings
new file mode 100644
index 0000000000..8936432bc4
--- /dev/null
+++ b/Adyen/CoreUI/Assets/pt.lproj/Localizable.strings
@@ -0,0 +1,26 @@
+"paymentMethods.title" = "Meios de pagamento";
+"paymentMethods.storedMethods.title" = "Meus métodos de pagamento";
+"paymentMethods.otherMethods.title" = "Todos os métodos de pagamento";
+"creditCard.title" = "Detalhes do cartĂŁo";
+"creditCard.numberField.title" = "NĂşmero do CartĂŁo";
+"creditCard.numberField.placeholder" = "1234 5678 9012 3456";
+"creditCard.expiryDateField.title" = "Data de Vencimento";
+"creditCard.expiryDateField.placeholder" = "MM/AA";
+"creditCard.cvcField.title" = "CVC / CVV";
+"creditCard.cvcField.placeholder" = "123";
+"creditCard.storeDetailsButton.title" = "Lembrar o cartĂŁo";
+"creditCard.oneClickVerification.title" = "Verifique o seu cartĂŁo";
+"creditCard.oneClickVerification.message" = "Por favor insira o cĂłdigo CVC para %@";
+"creditCard.oneClickVerification.invalidInput.title" = "Código de verificação inválido.";
+"creditCard.oneClickVerification.invalidInput.message" = "Por favor insira um código de verificação válido.";
+"sepaDirectDebit.ibanField.title" = "NĂşmero de conta (NIB)";
+"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122";
+"sepaDirectDebit.nameField.title" = "Nome do titular da conta bancária";
+"sepaDirectDebit.nameField.placeholder" = "J. Silva";
+"sepaDirectDebit.consentButton.title" = "Concordo que o seguinte valor será deduzido da minha conta bancária.";
+"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl";
+"giropay.minimumLength.title" = "MĂnimo de 3 caracteres";
+"cancelButton.title" = "Cancelar";
+"dismissButton.title" = "OK";
+"payButton.title" = "Pagar";
+"payButton.title.formatted" = "Pagar %@";
diff --git a/Adyen/CoreUI/Assets/sv.lproj/Localizable.strings b/Adyen/CoreUI/Assets/sv.lproj/Localizable.strings
new file mode 100644
index 0000000000..5e89d4a418
--- /dev/null
+++ b/Adyen/CoreUI/Assets/sv.lproj/Localizable.strings
@@ -0,0 +1,26 @@
+"paymentMethods.title" = "Betalningsmetoder";
+"paymentMethods.storedMethods.title" = "Dina sparade betalningsmetoder";
+"paymentMethods.otherMethods.title" = "Välj annan betalningsmetod";
+"creditCard.title" = "Kortuppgifter";
+"creditCard.numberField.title" = "Kortnummer";
+"creditCard.numberField.placeholder" = "1234 5678 9012 3456";
+"creditCard.expiryDateField.title" = "Förfallodatum";
+"creditCard.expiryDateField.placeholder" = "MM/AA";
+"creditCard.cvcField.title" = "CVC / CVV";
+"creditCard.cvcField.placeholder" = "123";
+"creditCard.storeDetailsButton.title" = "Spara kortuppgifter";
+"creditCard.oneClickVerification.title" = "Verifiera ditt kort";
+"creditCard.oneClickVerification.message" = "Vänligen fyll i CVC kod för %@";
+"creditCard.oneClickVerification.invalidInput.title" = "Ogiltig verifieringskod.";
+"creditCard.oneClickVerification.invalidInput.message" = "Ange en giltig verifieringskod.";
+"sepaDirectDebit.ibanField.title" = "Kontonummer (IBAN)";
+"sepaDirectDebit.ibanField.placeholder" = "NL53 ABNA 1925 1294 122";
+"sepaDirectDebit.nameField.title" = "Känt av kontoinnehavaren";
+"sepaDirectDebit.nameField.placeholder" = "J. Johansson";
+"sepaDirectDebit.consentButton.title" = "Jag hĂĄller med om att beloppet nedan debiteras frĂĄn mitt bankkonto.";
+"giropay.searchField.placeholder" = "Bankname / BIC / Bankleitzahl";
+"giropay.minimumLength.title" = "Minst 3 tecken";
+"cancelButton.title" = "Avbryt";
+"dismissButton.title" = "OK";
+"payButton.title" = "Betala";
+"payButton.title.formatted" = "Betala %@";
diff --git a/Adyen/CoreUI/BundleExtensions.swift b/Adyen/CoreUI/BundleExtensions.swift
new file mode 100644
index 0000000000..d5d81e5577
--- /dev/null
+++ b/Adyen/CoreUI/BundleExtensions.swift
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+internal extension Bundle {
+
+ /// The bundle in which the framework's resources are located.
+ internal static let resources: Bundle = {
+ let mainBundle = Bundle(for: PaymentRequest.self)
+
+ // If we're installed through CocoaPods, there should be a CoreUI bundle with the resources.
+ // If not, simply return the main bundle.
+ guard
+ let resourcesBundlePath = mainBundle.path(forResource: "CoreUI", ofType: "bundle"),
+ let resourcesBundle = Bundle(path: resourcesBundlePath)
+ else {
+ return mainBundle
+ }
+
+ return resourcesBundle
+ }()
+
+}
diff --git a/Adyen/CoreUI/CheckoutButton.swift b/Adyen/CoreUI/CheckoutButton.swift
index 1aec5a4c2e..b39c0f19ed 100644
--- a/Adyen/CoreUI/CheckoutButton.swift
+++ b/Adyen/CoreUI/CheckoutButton.swift
@@ -6,46 +6,158 @@
import UIKit
-class CheckoutButton: UIButton {
+/// The CheckoutButton class provides a large, tinted button to complete a checkout.
+@IBDesignable
+internal class CheckoutButton: UIControl {
- override var isEnabled: Bool {
+ internal override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ commonInit()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+
+ commonInit()
+ }
+
+ private func commonInit() {
+ layer.cornerRadius = 4.0
+
+ accessibilityTraits = UIAccessibilityTraitButton
+
+ addSubview(titleLabel)
+ addSubview(activityIndicatorView)
+
+ configureConstraints()
+ updateAppearance()
+
+ isAccessibilityElement = true
+ accessibilityTraits = UIAccessibilityTraitButton
+ }
+
+ override func tintColorDidChange() {
+ super.tintColorDidChange()
+
+ backgroundColor = tintColor
+ }
+
+ // MARK: Layout
+
+ private func configureConstraints() {
+ let constraints = [
+ titleLabelTopAnchorConstraint,
+ titleLabelBottomAnchorConstraint,
+ titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
+ activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor),
+ activityIndicatorView.centerYAnchor.constraint(equalTo: centerYAnchor)
+ ]
+
+ NSLayoutConstraint.activate(constraints)
+ }
+
+ private lazy var titleLabelTopAnchorConstraint: NSLayoutConstraint = {
+ self.titleLabel.topAnchor.constraint(equalTo: self.topAnchor)
+ }()
+
+ private lazy var titleLabelBottomAnchorConstraint: NSLayoutConstraint = {
+ self.titleLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor)
+ }()
+
+ // MARK: Appearance Configuration
+
+ internal var appearanceConfiguration: AppearanceConfiguration = .default {
didSet {
- backgroundColor = backgroundColor?.withAlphaComponent(isEnabled ? 1 : 0.5)
+ updateAppearance()
}
}
- func startLoading() {
- let indicator = UIActivityIndicatorView(activityIndicatorStyle: .white)
- indicator.hidesWhenStopped = true
- indicator.translatesAutoresizingMaskIntoConstraints = false
+ private func updateAppearance() {
+ tintColor = appearanceConfiguration.tintColor
- addSubview(indicator)
- addConstraints(indicator)
+ let cornerRadius = appearanceConfiguration.checkoutButtonCornerRadius
+ clipsToBounds = cornerRadius > 0.0
+ layer.cornerRadius = cornerRadius
- setTitleColor(titleColor(for: .normal)?.withAlphaComponent(0), for: .normal)
+ let titleLabelEdgeInsets = appearanceConfiguration.checkoutButtonTitleEdgeInsets ?? .zero
+ titleLabelTopAnchorConstraint.constant = titleLabelEdgeInsets.top
+ titleLabelBottomAnchorConstraint.constant = -titleLabelEdgeInsets.bottom
- indicator.startAnimating()
+ updateTitle()
}
- private func addConstraints(_ indicator: UIActivityIndicatorView) {
- addConstraint(NSLayoutConstraint(
- item: indicator,
- attribute: .centerX,
- relatedBy: .equal,
- toItem: self,
- attribute: .centerX,
- multiplier: 1,
- constant: 0
- ))
+ // MARK: Title Label
+
+ private lazy var titleLabel: UILabel = {
+ let titleLabel = UILabel()
+ titleLabel.isUserInteractionEnabled = false
+ titleLabel.isAccessibilityElement = false
+ titleLabel.translatesAutoresizingMaskIntoConstraints = false
- addConstraint(NSLayoutConstraint(
- item: indicator,
- attribute: .centerY,
- relatedBy: .equal,
- toItem: self,
- attribute: .centerY,
- multiplier: 1,
- constant: 0
- ))
+ return titleLabel
+ }()
+
+ @IBInspectable
+ internal var title: String? {
+ didSet {
+ updateTitle()
+
+ accessibilityLabel = title
+ }
+ }
+
+ private func updateTitle() {
+ let attributedTitle = NSAttributedString(string: title ?? "",
+ attributes: appearanceConfiguration.checkoutButtonTitleTextAttributes)
+ titleLabel.attributedText = attributedTitle
+ }
+
+ // MARK: Enabled State
+
+ override var isEnabled: Bool {
+ didSet {
+ alpha = isEnabled ? 1.0 : 0.5
+
+ if isEnabled {
+ accessibilityTraits = UIAccessibilityTraitButton
+ } else {
+ accessibilityTraits = UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled
+ }
+ }
+ }
+
+ // MARK: Highlighted State
+
+ override var isHighlighted: Bool {
+ didSet {
+ alpha = isHighlighted ? 0.75 : 1.0
+ }
+ }
+
+ // MARK: Loading State
+
+ /// Boolean value indicating whether the button should display an activity indicator.
+ internal var isLoading: Bool = false {
+ didSet {
+ titleLabel.isHidden = isLoading
+
+ if isLoading {
+ activityIndicatorView.startAnimating()
+ } else {
+ activityIndicatorView.stopAnimating()
+ }
+
+ isUserInteractionEnabled = !isLoading
+ }
}
+
+ private lazy var activityIndicatorView: UIActivityIndicatorView = {
+ let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .white)
+ activityIndicatorView.isUserInteractionEnabled = false
+ activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
+
+ return activityIndicatorView
+ }()
+
}
diff --git a/Adyen/CoreUI/Localization.swift b/Adyen/CoreUI/Localization.swift
new file mode 100644
index 0000000000..d03c5e709d
--- /dev/null
+++ b/Adyen/CoreUI/Localization.swift
@@ -0,0 +1,80 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+/// Returns a localized string for the given key, and optionally uses it as a template in which the remaining argument values are substituted.
+///
+/// - Parameters:
+/// - key: The key used to identify the localized string.
+/// - arguments: The arguments to substitute in the templated localized string.
+/// - Returns: The localized string for the given key, or the key itself if the localized string could not be found.
+internal func ADYLocalizedString(_ key: String, _ arguments: CVarArg...) -> String {
+ let localizedString = NSLocalizedString(key,
+ tableName: nil,
+ bundle: .resources,
+ comment: "")
+
+ guard arguments.isEmpty == false else {
+ return localizedString
+ }
+
+ return String(format: localizedString, arguments: arguments)
+}
+
+internal extension UIView {
+
+ /// The key to the localized string that should be set to the label's accessibility label property.
+ @IBInspectable
+ internal var localizedAccessibilityLabelKey: String? {
+ get { return nil }
+
+ set {
+ if let key = newValue {
+ accessibilityLabel = ADYLocalizedString(key)
+ } else {
+ accessibilityLabel = nil
+ }
+ }
+ }
+
+}
+
+internal extension UILabel {
+
+ /// The key to the localized string that should be set to the label's text property.
+ @IBInspectable
+ internal var localizedTextKey: String? {
+ get { return nil }
+
+ set {
+ if let key = newValue {
+ text = ADYLocalizedString(key)
+ } else {
+ text = nil
+ }
+ }
+ }
+
+}
+
+internal extension UITextField {
+
+ /// The key to the localized string that should be set to the text field's placeholder property.
+ @IBInspectable
+ internal var localizedPlaceholderKey: String? {
+ get { return nil }
+
+ set {
+ if let key = newValue {
+ placeholder = ADYLocalizedString(key)
+ } else {
+ placeholder = nil
+ }
+ }
+ }
+
+}
diff --git a/Adyen/CoreUI/PaymentMethodTableViewCell.swift b/Adyen/CoreUI/PaymentMethodTableViewCell.swift
index be0ba2076c..e454066ae8 100644
--- a/Adyen/CoreUI/PaymentMethodTableViewCell.swift
+++ b/Adyen/CoreUI/PaymentMethodTableViewCell.swift
@@ -7,147 +7,132 @@
import UIKit
class PaymentMethodTableViewCell: LoadingTableViewCell {
- fileprivate let nameLabel = UILabel()
- fileprivate let logoImageView = UIImageView()
- var name: String? {
- didSet {
- nameLabel.text = name
- }
+ override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
+ super.init(style: style, reuseIdentifier: reuseIdentifier)
+
+ commonInit()
}
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+
+ commonInit()
+ }
+
+ private func commonInit() {
+ contentView.addSubview(logoView)
+ contentView.addSubview(nameLabel)
+
+ accessibilityTraits |= UIAccessibilityTraitButton
+
+ configureConstraints()
+ }
+
+ override func stopLoadingAnimation() {
+ super.stopLoadingAnimation()
+
+ // Reset the disclosure indicator, in case it was visible before the loading animation was shown.
+ let showsDisclosureIndicator = self.showsDisclosureIndicator
+ self.showsDisclosureIndicator = showsDisclosureIndicator
+ }
+
+ // MARK: Layout
+
+ private func configureConstraints() {
+ let marginsGuide = contentView.layoutMarginsGuide
+
+ let constraints = [
+ logoView.leadingAnchor.constraint(equalTo: marginsGuide.leadingAnchor),
+ logoView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
+ logoView.widthAnchor.constraint(equalToConstant: 40.0),
+ logoView.heightAnchor.constraint(equalToConstant: 26.0),
+ nameLabel.leadingAnchor.constraint(equalTo: logoView.trailingAnchor, constant: 20.0),
+ nameLabel.trailingAnchor.constraint(lessThanOrEqualTo: marginsGuide.trailingAnchor),
+ nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
+ ]
+
+ NSLayoutConstraint.activate(constraints)
+ }
+
+ // MARK: Logo Image View
+
var logoURL: URL? {
didSet {
guard let url = logoURL else {
- logoImageView.image = nil
+ logoView.image = nil
return
}
- logoImageView.downloadedFrom(url: url)
- logoImageView.contentMode = .scaleAspectFit
- logoImageView.layer.cornerRadius = 4
- logoImageView.layer.borderWidth = 1 / UIScreen.main.nativeScale
- logoImageView.layer.borderColor = UIColor.black.withAlphaComponent(0.2).cgColor
- logoImageView.clipsToBounds = true
+ logoView.downloadedFrom(url: url)
+ logoView.contentMode = .scaleAspectFit
+ logoView.layer.cornerRadius = 4
+ logoView.layer.borderWidth = 1 / UIScreen.main.nativeScale
+ logoView.layer.borderColor = UIColor.black.withAlphaComponent(0.2).cgColor
+ logoView.clipsToBounds = true
}
}
- override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
- super.init(style: style, reuseIdentifier: reuseIdentifier)
- setupViews()
- }
+ fileprivate lazy var logoView: UIImageView = {
+ let logoView = UIImageView()
+ logoView.contentMode = .scaleAspectFit
+ logoView.translatesAutoresizingMaskIntoConstraints = false
+
+ return logoView
+ }()
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- setupViews()
+ // MARK: Name Label
+
+ var name: String? {
+ didSet {
+ nameLabel.text = name
+
+ accessibilityLabel = name
+ }
}
-}
-
-// MARK: Subviews Stack
-
-extension PaymentMethodTableViewCell {
- func setupViews() {
+ fileprivate lazy var nameLabel: UILabel = {
+ let nameLabel = UILabel()
+ nameLabel.font = UIFont.systemFont(ofSize: 16.0)
+ nameLabel.textColor = UIColor.checkoutDarkGray
nameLabel.translatesAutoresizingMaskIntoConstraints = false
- logoImageView.translatesAutoresizingMaskIntoConstraints = false
+ nameLabel.isAccessibilityElement = false
- addSubview(nameLabel)
- addSubview(logoImageView)
-
- applyLogoConstraints()
- applyNameConstraints()
- applyStyling()
- }
+ return nameLabel
+ }()
- func applyLogoConstraints() {
- self.addConstraint(NSLayoutConstraint(
- item: logoImageView,
- attribute: .width,
- relatedBy: .equal,
- toItem: nil,
- attribute: .notAnAttribute,
- multiplier: 1,
- constant: 40
- ))
- self.addConstraint(NSLayoutConstraint(
- item: logoImageView,
- attribute: .height,
- relatedBy: .equal,
- toItem: nil,
- attribute: .notAnAttribute,
- multiplier: 1,
- constant: 26
- ))
- self.addConstraint(NSLayoutConstraint(
- item: logoImageView,
- attribute: .centerY,
- relatedBy: .equal,
- toItem: self,
- attribute: .centerY,
- multiplier: 1,
- constant: 0
- ))
- self.addConstraint(NSLayoutConstraint(
- item: logoImageView,
- attribute: .leading,
- relatedBy: .equal,
- toItem: self,
- attribute: .leading,
- multiplier: 1,
- constant: 20
- ))
- }
+ // MARK: Disclosure Indicator
- func applyNameConstraints() {
- self.addConstraint(NSLayoutConstraint(
- item: nameLabel,
- attribute: .centerY,
- relatedBy: .equal,
- toItem: self,
- attribute: .centerY,
- multiplier: 1,
- constant: 0
- ))
- self.addConstraint(NSLayoutConstraint(
- item: nameLabel,
- attribute: .leading,
- relatedBy: .equal,
- toItem: logoImageView,
- attribute: .trailing,
- multiplier: 1,
- constant: 20
- ))
- self.addConstraint(NSLayoutConstraint(
- item: nameLabel,
- attribute: .trailing,
- relatedBy: .lessThanOrEqual,
- toItem: self,
- attribute: .trailing,
- multiplier: 1,
- constant: -35
- ))
+ /// Boolean value indicating whether the detail indicator should be shown as an accessory.
+ internal var showsDisclosureIndicator: Bool = false {
+ didSet {
+ if showsDisclosureIndicator {
+ accessoryView = UIImageView(image: UIImage.bundleImage("cell_disclosure_indicator"))
+ } else {
+ accessoryView = nil
+ }
+ }
}
- func applyStyling() {
- logoImageView.contentMode = .scaleAspectFit
-
- nameLabel.font = UIFont.systemFont(ofSize: 16)
- nameLabel.textColor = UIColor.checkoutDark()
-
- self.accessoryView = UIImageView(image: UIImage.bundleImage("cell_disclosure_indicator"))
- }
}
-// MARK: Configuration
+// MARK: PaymentMethod Configuration
extension PaymentMethodTableViewCell {
func configure(with method: PaymentMethod) {
- self.name = method.name
- self.logoURL = method.logoURL
-
- if let linnearFlow = method.plugin?.linnearFlow(), linnearFlow == false {
- self.accessoryView = nil
+ name = method.name
+ logoURL = method.logoURL
+ showsDisclosureIndicator = shouldShowDisclosureIndicator(for: method)
+ }
+
+ fileprivate func shouldShowDisclosureIndicator(for method: PaymentMethod) -> Bool {
+ switch method.txVariant {
+ case .ideal, .card, .sepadirectdebit:
+ return true
+ default:
+ return false
}
}
+
}
diff --git a/Adyen/Core/Protocols/PaymentMethodDetailsPresenter.swift b/Adyen/CoreUI/Plugins/PaymentMethodDetailsPresenter.swift
similarity index 69%
rename from Adyen/Core/Protocols/PaymentMethodDetailsPresenter.swift
rename to Adyen/CoreUI/Plugins/PaymentMethodDetailsPresenter.swift
index a32380a6f8..b1e02e302a 100644
--- a/Adyen/Core/Protocols/PaymentMethodDetailsPresenter.swift
+++ b/Adyen/CoreUI/Plugins/PaymentMethodDetailsPresenter.swift
@@ -7,7 +7,7 @@
import Foundation
protocol PaymentMethodDetailsPresenter {
- func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, completion: @escaping (PaymentDetails) -> Void)
+ func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, appearanceConfiguration: AppearanceConfiguration, completion: @escaping (PaymentDetails) -> Void)
func present()
func dismiss(animated: Bool, completion: @escaping () -> Void)
}
diff --git a/Adyen/Core/Protocols/UIPresentable.swift b/Adyen/CoreUI/Plugins/UIPresentable.swift
similarity index 100%
rename from Adyen/Core/Protocols/UIPresentable.swift
rename to Adyen/CoreUI/Plugins/UIPresentable.swift
diff --git a/Adyen/CoreUI/UIColorExtensions.swift b/Adyen/CoreUI/UIColorExtensions.swift
index dda04e03b1..68ad76b94e 100644
--- a/Adyen/CoreUI/UIColorExtensions.swift
+++ b/Adyen/CoreUI/UIColorExtensions.swift
@@ -9,36 +9,20 @@ import UIKit
internal extension UIColor {
- convenience init(hexString: String, alpha: Double = 1.0) {
-
- let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
- var int = UInt32()
- Scanner(string: hex).scanHexInt32(&int)
- let r, g, b: UInt32
- switch hex.characters.count {
- case 3: // RGB (12-bit)
- (r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
- case 6: // RGB (24-bit)
- (r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
- default:
- (r, g, b) = (1, 1, 0)
- }
-
- self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(255 * alpha) / 255)
+ internal static var checkoutLightGray: UIColor {
+ return #colorLiteral(red: 0.9764705882, green: 0.9764705882, blue: 0.9764705882, alpha: 1)
}
-}
-
-internal extension UIColor {
- class func checkoutDark() -> UIColor {
- return UIColor(hexString: "353535")
+ internal static var checkoutGray: UIColor {
+ return #colorLiteral(red: 0.4431372549, green: 0.4431372549, blue: 0.4431372549, alpha: 1)
}
- class func checkoutBackground() -> UIColor {
- return UIColor(hexString: "F9F9F9")
+ internal static var checkoutDarkGray: UIColor {
+ return #colorLiteral(red: 0.2078431373, green: 0.2078431373, blue: 0.2078431373, alpha: 1)
}
- class func checkoutLightDark() -> UIColor {
- return UIColor(hexString: "717171")
+ internal static var checkoutBackground: UIColor {
+ return checkoutLightGray
}
+
}
diff --git a/Adyen/CoreUI/UIImageExtensions.swift b/Adyen/CoreUI/UIImageExtensions.swift
index d63dac51c6..ca000ed75c 100644
--- a/Adyen/CoreUI/UIImageExtensions.swift
+++ b/Adyen/CoreUI/UIImageExtensions.swift
@@ -8,8 +8,6 @@ import Foundation
internal extension UIImage {
class func bundleImage(_ name: String) -> UIImage? {
- let bundle = Bundle(for: PaymentRequest.self)
- let image = UIImage(named: name, in: bundle, compatibleWith: nil)
- return image
+ return UIImage(named: name, in: .resources, compatibleWith: nil)
}
}
diff --git a/Adyen/Info.plist b/Adyen/Info.plist
new file mode 100644
index 0000000000..09738dfd75
--- /dev/null
+++ b/Adyen/Info.plist
@@ -0,0 +1,24 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ $(CURRENT_PROJECT_VERSION)
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ NSPrincipalClass
+
+
+
diff --git a/Adyen/Plugins/ApplePay/ApplePayDetailsPresenter.swift b/Adyen/Plugins/ApplePay/ApplePayDetailsPresenter.swift
index aae0bf8717..74725bda81 100644
--- a/Adyen/Plugins/ApplePay/ApplePayDetailsPresenter.swift
+++ b/Adyen/Plugins/ApplePay/ApplePayDetailsPresenter.swift
@@ -32,7 +32,7 @@ class ApplePayDetailsPresenter: NSObject, PaymentMethodDetailsPresenter {
return request
}
- func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, completion: @escaping (PaymentDetails) -> Void) {
+ func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, appearanceConfiguration: AppearanceConfiguration, completion: @escaping (PaymentDetails) -> Void) {
self.hostViewController = hostViewController
requiredPaymentDetails = paymentDetails
detailsCompletion = completion
diff --git a/Adyen/Plugins/Cards/CardFormViewController.swift b/Adyen/Plugins/Cards/CardFormViewController.swift
index 6df84a2917..f1dd3c796b 100644
--- a/Adyen/Plugins/Cards/CardFormViewController.swift
+++ b/Adyen/Plugins/Cards/CardFormViewController.swift
@@ -7,45 +7,21 @@
import UIKit
import QuartzCore
-class CardFormViewController: UIViewController {
- // Interface Builder
- @IBOutlet weak var lockImageView: UIImageView!
-
- // Card Number Field
- @IBOutlet weak var cardNumberLabel: UILabel!
- @IBOutlet weak var cardNumberLogoImageView: UIImageView!
- @IBOutlet weak var cardNumberUnderlineView: UIView!
- @IBOutlet weak var cardNumberTextField: CardNumberField!
-
- // Expiry Date Field
- @IBOutlet weak var expiryDateLabel: UILabel!
- @IBOutlet weak var expiryDateUnderlineView: UIView!
- @IBOutlet weak var expiryDateTextField: CardExpirationField!
-
- // CVC Field
- @IBOutlet weak var cvcLabel: UILabel!
- @IBOutlet weak var cvcUnderlineView: UIView!
- @IBOutlet weak var cvcTextField: CardCvcField!
-
- // Store Details
- @IBOutlet weak var storeDetailsLabel: UILabel!
- @IBOutlet weak var storeDetailsButton: UIButton!
+class CardFormViewController: UIViewController, CheckoutPaymentFieldDelegate {
- @IBOutlet weak var payButton: CheckoutButton!
- @IBOutlet weak var scrollView: UIScrollView!
- @IBOutlet weak var keyboardTopLineBottomConstraint: NSLayoutConstraint!
- @IBOutlet weak var formHeightConstraint: NSLayoutConstraint!
+ // MARK: - Object Lifecycle
- fileprivate let inactiveColor = UIColor(hexString: "D8D8D8")
- fileprivate let activeColor = UIColor(hexString: "757575")
+ init(appearanceConfiguration: AppearanceConfiguration) {
+ self.appearanceConfiguration = appearanceConfiguration
+
+ super.init(nibName: "CardFormViewController", bundle: Bundle(for: CardFormViewController.self))
+ }
- fileprivate var cardFieldManager: CardPaymentFieldManager?
- fileprivate var detectedCardType = CardType.unknown
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
- var cardDetailsHandler: (([String: Any], @escaping ((Bool) -> Void)) -> Void)?
- var formattedAmount: String?
- var paymentMethod: PaymentMethod?
- var shouldHideStoreDetails = false
+ // MARK: - UIViewController
override func viewDidLoad() {
super.viewDidLoad()
@@ -56,17 +32,78 @@ class CardFormViewController: UIViewController {
cardFieldManager?.delegate = self
}
+ // MARK: - CheckoutPaymentFieldDelegate
+
+ func paymentFieldChangedValidity(_ valid: Bool) {
+ payButton.isEnabled = valid
+ }
+
+ func paymentFieldDidDetectCard(type: CardType) {
+ updateCardLogoWith(type: type)
+ updateCvcRequirementWith(type: type)
+ }
+
+ func paymentFieldDidUpdateActive(field: UITextField) {
+ updateFieldsPresentationWith(field: field)
+ }
+
+ // MARK: - Public
+
+ var cardDetailsHandler: (([String: Any], @escaping ((Bool) -> Void)) -> Void)?
+ var formattedAmount: String?
+ var paymentMethod: PaymentMethod?
+ var shouldHideStoreDetails = false
+
+ // MARK: - Private
+
+ // Interface Builder
+ @IBOutlet private weak var lockImageView: UIImageView!
+
+ // Card Number Field
+ @IBOutlet private weak var cardNumberLabel: UILabel!
+ @IBOutlet private weak var cardNumberLogoImageView: UIImageView!
+ @IBOutlet private weak var cardNumberUnderlineView: UIView!
+ @IBOutlet private weak var cardNumberTextField: CardNumberField!
+
+ // Expiry Date Field
+ @IBOutlet private weak var expiryDateLabel: UILabel!
+ @IBOutlet private weak var expiryDateUnderlineView: UIView!
+ @IBOutlet private weak var expiryDateTextField: CardExpirationField!
+
+ // CVC Field
+ @IBOutlet private weak var cvcLabel: UILabel!
+ @IBOutlet private weak var cvcUnderlineView: UIView!
+ @IBOutlet private weak var cvcTextField: CardCvcField!
+
+ // Store Details
+ @IBOutlet private weak var storeDetailsLabel: UILabel!
+ @IBOutlet private weak var storeDetailsButton: UIButton!
+
+ @IBOutlet private weak var payButton: CheckoutButton!
+ @IBOutlet private weak var scrollView: UIScrollView!
+ @IBOutlet private weak var keyboardTopLineBottomConstraint: NSLayoutConstraint!
+ @IBOutlet private weak var formHeightConstraint: NSLayoutConstraint!
+
+ private let inactiveColor = #colorLiteral(red: 0.8470588235, green: 0.8470588235, blue: 0.8470588235, alpha: 1)
+ private let activeColor = #colorLiteral(red: 0.4588235294, green: 0.4588235294, blue: 0.4588235294, alpha: 1)
+
+ private var cardFieldManager: CardPaymentFieldManager?
+ private var detectedCardType: CardType?
+
+ private let appearanceConfiguration: AppearanceConfiguration
+
private func applyStyling() {
- title = "Card Details"
+ title = ADYLocalizedString("creditCard.title")
cardNumberLogoImageView.image = UIImage.bundleImage("credit_card_icon")
lockImageView.image = UIImage.bundleImage("lock")
storeDetailsButton.setImage(UIImage.bundleImage("checkbox_inactive"), for: .normal)
storeDetailsButton.setImage(UIImage.bundleImage("checkbox_active"), for: .selected)
+ storeDetailsButton.tintColor = appearanceConfiguration.tintColor
payButton.isEnabled = false
- payButton.layer.cornerRadius = 4
- payButton.setTitle("Pay \(formattedAmount ?? "")", for: .normal)
+ payButton.title = ADYLocalizedString("payButton.title.formatted", formattedAmount ?? "")
+ payButton.appearanceConfiguration = appearanceConfiguration
if shouldHideStoreDetails {
hideStoreDetails()
@@ -83,7 +120,7 @@ class CardFormViewController: UIViewController {
formHeightConstraint.constant -= 40
}
- fileprivate func updateFieldsPresentationWith(field: UITextField) {
+ private func updateFieldsPresentationWith(field: UITextField) {
cardNumberUnderlineView.backgroundColor = inactiveColor
expiryDateUnderlineView.backgroundColor = inactiveColor
cvcUnderlineView.backgroundColor = inactiveColor
@@ -125,14 +162,14 @@ class CardFormViewController: UIViewController {
}
}
- fileprivate func updateCardLogoWith(type: CardType) {
- if detectedCardType == type {
+ private func updateCardLogoWith(type: CardType?) {
+ guard detectedCardType != type else {
return
}
detectedCardType = type
- if detectedCardType == .unknown {
+ guard detectedCardType != nil else {
cardNumberLogoImageView.image = UIImage.bundleImage("credit_card_icon")
return
}
@@ -141,7 +178,7 @@ class CardFormViewController: UIViewController {
return
}
- for member in members where member.type == detectedCardType.rawValue {
+ for member in members where member.type == detectedCardType!.rawValue {
if let url = member.logoURL {
cardNumberLogoImageView.downloadedFrom(url: url)
cardNumberLogoImageView.contentMode = .scaleAspectFit
@@ -157,10 +194,12 @@ class CardFormViewController: UIViewController {
// change to unknown if couldn't find anything
cardNumberLogoImageView.image = UIImage.bundleImage("credit_card_icon")
}
-}
-
-extension CardFormViewController {
- @IBAction func pay(_ sender: Any) {
+
+ private func updateCvcRequirementWith(type: CardType?) {
+ // TODO: update
+ }
+
+ @IBAction private func pay(_ sender: Any) {
// start animation
guard
let number = cardNumberTextField.text,
@@ -186,31 +225,19 @@ extension CardFormViewController {
"storeDetails": storeDetailsButton.isSelected
]
+ resignFirstResponder()
+
cardNumberTextField.resignFirstResponder()
expiryDateTextField.resignFirstResponder()
cvcTextField.resignFirstResponder()
- payButton.startLoading()
+ payButton.isLoading = true
cardDetailsHandler?(info) { success in }
}
- @IBAction func storeDetailsToggle(_ sender: Any) {
+ @IBAction private func storeDetailsToggle(_ sender: Any) {
storeDetailsButton.isSelected = !storeDetailsButton.isSelected
}
-}
-
-extension CardFormViewController: CheckoutPaymentFieldDelegate {
- func paymentFieldChangedValidity(_ valid: Bool) {
- payButton.isEnabled = valid
- }
-
- func paymentFieldDidDetectCard(type: CardType) {
- updateCardLogoWith(type: type)
- }
-
- func paymentFieldDidUpdateActive(field: UITextField) {
- updateFieldsPresentationWith(field: field)
- }
}
diff --git a/Adyen/Plugins/Cards/CardFormViewController.xib b/Adyen/Plugins/Cards/CardFormViewController.xib
index f20e218486..4b8b37c525 100644
--- a/Adyen/Plugins/Cards/CardFormViewController.xib
+++ b/Adyen/Plugins/Cards/CardFormViewController.xib
@@ -1,10 +1,11 @@
-
+
-
+
+
@@ -20,10 +21,9 @@
-
-
+
@@ -39,13 +39,13 @@
-
+
-
+
-
+
@@ -60,9 +60,15 @@
+
+
+
+
+
+
@@ -73,9 +79,14 @@
+
+
+
+
+
@@ -98,15 +109,26 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -135,22 +157,33 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -175,14 +208,25 @@
-
-
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
@@ -206,14 +250,14 @@
+
-
+
-
@@ -221,29 +265,28 @@
-
-
-
+
+
+
-
+
-
-
-
-
+
+
+
-
+
-
+
-
-
-
+
+
-
+
+
@@ -256,7 +299,7 @@
-
+
diff --git a/Adyen/Plugins/Cards/CardPaymentFieldManager.swift b/Adyen/Plugins/Cards/CardPaymentFieldManager.swift
index ebe78917fc..260e601165 100644
--- a/Adyen/Plugins/Cards/CardPaymentFieldManager.swift
+++ b/Adyen/Plugins/Cards/CardPaymentFieldManager.swift
@@ -13,14 +13,9 @@ protocol CheckoutPaymentFieldDelegate: class {
func paymentFieldDidUpdateActive(field: UITextField)
}
-class CardPaymentFieldManager: NSObject {
- weak var delegate: CheckoutPaymentFieldDelegate?
- var valid = false
+class CardPaymentFieldManager: NSObject, UITextFieldDelegate {
- fileprivate var numberField: CardNumberField
- fileprivate var expirationField: CardExpirationField
- fileprivate var cvcField: CardCvcField
- fileprivate var acceptedCards: [CardType]
+ // MARK: - Object Lifecycle
init(numberField: CardNumberField, expirationField: CardExpirationField, cvcField: CardCvcField, acceptedCards: [CardType]) {
self.numberField = numberField
@@ -38,25 +33,30 @@ class CardPaymentFieldManager: NSObject {
self.delegate?.paymentFieldDidDetectCard(type: type)
}
}
-}
-
-extension CardPaymentFieldManager: UITextFieldDelegate {
+
+ // MARK: - UITextFieldDelegate
+
func textFieldDidBeginEditing(_ textField: UITextField) {
- if textField == numberField {
- textField.textColor = UIColor.darkText
- }
-
+ textField.textColor = UIColor.darkText
delegate?.paymentFieldDidUpdateActive(field: textField)
}
func textFieldDidEndEditing(_ textField: UITextField) {
- if textField == numberField && textField.text != nil {
- let (_, _, valid) = CardValidator.validate(card: textField.text!, acceptedCards: acceptedCards)
- textField.textColor = valid ? UIColor.darkText : UIColor.red
- } else if textField == expirationField && textField.text != nil {
- let (_, valid, _, _) = CardValidator.validate(expiryDate: textField.text!, split: true)
- textField.textColor = valid ? UIColor.darkText : UIColor.red
+ guard let text = textField.text, text.characters.count > 0 else {
+ return
+ }
+
+ var valid = false
+
+ if textField == numberField {
+ valid = CardValidator.validate(cardNumber: text, acceptedCardTypes: acceptedCards).isValid
+ } else if textField == expirationField {
+ valid = CardValidator.validate(expiryDate: text).isValid
+ } else if textField == cvcField {
+ valid = CardValidator.validate(cvc: text).isValid || !isCvcRequired
}
+
+ textField.textColor = valid ? validTextColor : invalidTextColor
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
@@ -69,24 +69,55 @@ extension CardPaymentFieldManager: UITextFieldDelegate {
} else if textField == expirationField {
didUpdateExpirationFieldCharacters(string: string, newString: newString, numbers: numberOnly, isDeleting: isDeleting)
} else if textField == cvcField {
- didUpdateCvcFieldCharacters(string: string, newString: newString, numbers: numberOnly)
+ didUpdateCvcFieldCharacters(string: string, numbers: numberOnly)
}
- valid = (numberField.valid && expirationField.valid && cvcField.valid)
- delegate?.paymentFieldChangedValidity(valid)
+ updateFieldValidity()
return false
}
+ // MARK: - Public
+
+ weak var delegate: CheckoutPaymentFieldDelegate?
+ var isCvcRequired = true {
+ didSet {
+ if isCvcRequired != oldValue {
+ let valid: Bool
+ if isCvcRequired {
+ if let text = cvcField.text {
+ valid = CardValidator.validate(cvc: text).isValid
+ } else {
+ valid = false
+ }
+ } else {
+ valid = true
+ }
+ cvcField.valid = valid
+ cvcField.textColor = valid ? validTextColor : invalidTextColor
+ updateFieldValidity()
+ }
+ }
+ }
+
+ // MARK: - Private
+
+ private var numberField: CardNumberField
+ private var expirationField: CardExpirationField
+ private var cvcField: CardCvcField
+ private var acceptedCards: [CardType]
+ private let validTextColor = UIColor.darkText
+ private let invalidTextColor = UIColor.red
+
private func didUpdateNumberFieldCharacters(string: String, numbers: String) {
// Since all cards in CardType Enum i.e Amex, Visa, MasterCard, Diners, Discover, JCB, Elo, Hipercard, UnionPay are not having numbers more than max length of 19 characters. 19 charachters + 4 spaces = 23 :)
if string.characters.count != 0 && numberField.text?.characters.count == 23 {
return
}
- let (type, formatted, valid) = CardValidator.validate(card: numbers, acceptedCards: acceptedCards)
+ let (valid, type, formatted) = CardValidator.validate(cardNumber: numbers, acceptedCardTypes: acceptedCards)
- numberField.valid = valid && type != .unknown
+ numberField.valid = valid && type != nil
numberField.card = type
numberField.text = formatted
}
@@ -97,7 +128,7 @@ extension CardPaymentFieldManager: UITextFieldDelegate {
return
}
- let (formatted, valid, _, _) = CardValidator.validate(expiryDate: newString, split: !isDeleting)
+ let (valid, formatted) = CardValidator.validate(expiryDate: newString, separator: isDeleting ? nil : "/")
expirationField.valid = valid
@@ -111,15 +142,21 @@ extension CardPaymentFieldManager: UITextFieldDelegate {
}
}
- private func didUpdateCvcFieldCharacters(string: String, newString: String, numbers: String) {
- cvcField.valid = (numbers.characters.count >= 3)
+ private func didUpdateCvcFieldCharacters(string: String, numbers: String) {
+ cvcField.valid = !isCvcRequired || CardValidator.validate(cvc: numbers).isValid
- if newString.characters.count <= 4 {
- cvcField.text = newString
+ if numbers.characters.count <= 4 {
+ cvcField.text = numbers
if string.characters.count != 0 && cvcField.text?.characters.count == 4 {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
}
+
+ private func updateFieldValidity() {
+ let valid = (numberField.valid && expirationField.valid && cvcField.valid)
+ delegate?.paymentFieldChangedValidity(valid)
+ }
+
}
diff --git a/Adyen/Plugins/Cards/CardType.swift b/Adyen/Plugins/Cards/CardType.swift
index 516cc5a914..6d96b62939 100644
--- a/Adyen/Plugins/Cards/CardType.swift
+++ b/Adyen/Plugins/Cards/CardType.swift
@@ -6,54 +6,104 @@
import Foundation
-/// Supported card types
-enum CardType: String {
+/// Enum containing most known types of credit and debit cards.
+public enum CardType: String {
- /// MasterCard card type
- case mc // swiftlint:disable:this identifier_name
+ /// Alpha Bank Bonus MasterCard
+ case alphaBankBonusMasterCard = "mcalphabankbonus"
- case unknown
- case amex
- case visa
+ /// Alpha Bank Bonus VISA
+ case alphaBankBonusVISA = "visaalphabankbonus"
+
+ /// American Express
+ case americanExpress = "amex"
+
+ /// BCMC
+ case bcmc
+
+ /// de Bijenkorf Card
+ case bijenkorfCard = "bijcard"
+
+ /// Carte Bancaire
+ case carteBancaire = "cartebancaire"
+
+ /// China UnionPay
+ case chinaUnionPay = "cup"
+
+ /// Codensa
+ case codensa
+
+ /// Dankort
+ case dankort
+
+ /// Dankort VISA
+ case dankortVISA = "visadankort"
+
+ /// Diners Club
case diners
+
+ /// Discover
case discover
- case jcb
+
+ /// Elo
case elo
+
+ /// Hiper
+ case hiper
+
+ /// Hipercard
case hipercard
- case unionPay
- case bijcard
- case maestrouk
+
+ /// JCB
+ case jcb
+
+ /// KarenMillen
+ case karenMillen = "karenmillen"
+
+ /// Maestro
+ case maestro
+
+ /// Maestro UK
+ case maestroUK = "maestrouk"
+
+ /// MasterCard
+ case masterCard = "mc"
+
+ /// Mir
+ case mir
+
+ /// Oasis
+ case oasis
+
+ /// Solo
case solo
- case bcmc
- case dankort
+
+ /// Universal Air Travel Plan
case uatp
- case cup
- case codensa
- case visaalphabankbonus
- case visadankort
- case mcalphabankbonus
- case hiper
- case oasis
- case karenmillen
+
+ /// UnionPay
+ case unionPay = "unionpay"
+
+ /// VISA
+ case visa
+
+ /// The Warehouse
case warehouse
- case mir
- case maestro
- case cartebancaire
- static let allCards = [mc, amex, visa, diners, discover, jcb, elo, hipercard, unionPay, bijcard, maestrouk, solo, bcmc, dankort, uatp, cup, codensa, visaalphabankbonus, visadankort, mcalphabankbonus, hiper, oasis, karenmillen, warehouse, mir, maestro, cartebancaire]
+ /// Array containing all card types in this enum.
+ public static let all = [masterCard, americanExpress, visa, diners, discover, jcb, elo, hipercard, unionPay, bijenkorfCard, maestroUK, solo, bcmc, dankort, uatp, chinaUnionPay, codensa, alphaBankBonusVISA, dankortVISA, alphaBankBonusMasterCard, hiper, oasis, karenMillen, warehouse, mir, maestro, carteBancaire]
- var imageName: String {
- let type = rawValue.lowercased()
- return "card_" + type
- }
+}
+
+internal extension CardType {
- public var regex: String {
+ internal var regex: String {
switch self {
- case .amex:
+ case .americanExpress:
return "^3[47][0-9]{0,13}$"
case .visa:
return "^4[0-9]{0,16}$"
- case .mc:
+ case .masterCard:
return "^(5[1-5][0-9]{0,14}|2[2-7][0-9]{0,14})$"
case .diners:
return "^(36)[0-9]{0,12}$"
@@ -69,9 +119,9 @@ enum CardType: String {
return "^((((506699)|(506770)|(506771)|(506772)|(506773)|(506774)|(506775)|(506776)|(506777)|(506778)"
+ "|(401178)|(438935)|(451416)|(457631)|(457632)|(504175)|(627780)|(636368)|(636297))[0-9]"
+ "{0,10})|((50676)|(50675)|(50674)|(50673)|(50672)|(50671)|(50670))[0-9]{0,11})$"
- case .bijcard:
+ case .bijenkorfCard:
return "^(5100081)[0-9]{0,9}$"
- case .maestrouk:
+ case .maestroUK:
return "^(6759)[0-9]{0,15}$"
case .solo:
return "^(6767)[0-9]{0,15}$"
@@ -81,21 +131,21 @@ enum CardType: String {
return "^(5019)[0-9]{0,12}$"
case .uatp:
return "^1[0-9]{0,14}$"
- case .cup:
+ case .chinaUnionPay:
return "^(62)[0-9]{0,17}$"
case .codensa:
return "^(590712)[0-9]{0,10}$"
- case .visaalphabankbonus:
+ case .alphaBankBonusVISA:
return "^(450903)[0-9]{0,10}$"
- case .visadankort:
+ case .dankortVISA:
return "^(4571)[0-9]{0,12}$"
- case .mcalphabankbonus:
+ case .alphaBankBonusMasterCard:
return "^(510099)[0-9]{0,10}$"
case .hiper:
return "^(637095|637599|637609|637612)[0-9]{0,10}$"
case .oasis:
return "^(982616)[0-9]{0,10}$"
- case .karenmillen:
+ case .karenMillen:
return "^(98261465)[0-9]{0,8}$"
case .warehouse:
return "^(982633)[0-9]{0,10}$"
@@ -103,11 +153,9 @@ enum CardType: String {
return "^(220)[0-9]{0,16}$"
case .maestro:
return "^(5[6-8][0-9]{0,17}|6[0-9]{0,18})$"
- case .cartebancaire:
+ case .carteBancaire:
return "^[4-6][0-9]{0,15}$"
-
- default:
- return ""
}
}
+
}
diff --git a/Adyen/Plugins/Cards/CardValidator.swift b/Adyen/Plugins/Cards/CardValidator.swift
index 78ecb3d066..5ce7766bc4 100644
--- a/Adyen/Plugins/Cards/CardValidator.swift
+++ b/Adyen/Plugins/Cards/CardValidator.swift
@@ -6,131 +6,152 @@
import Foundation
-class CardValidator {
- // Based on maestro card
- private static let minValidCardLength = 12
+/// The CardValidator class provides static methods to validate and format card numbers and expiry dates, and to detect card types.
+public final class CardValidator {
- private static func matchesRegex(_ regex: String!, text: String!) -> Bool {
- do {
- let regex = try NSRegularExpression(pattern: regex, options: [.caseInsensitive])
- let nsString = text as NSString
- let match = regex.firstMatch(in: text, options: [], range: NSRange(location: 0, length: nsString.length))
- return (match != nil)
- } catch {
- return false
- }
- }
+ // MARK: - Public
- private static func luhnCheck(_ number: String) -> Bool {
- var sum = 0
- let digitStrings = number.characters.reversed().map { String($0) }
+ /// Validates and formats the given card number, and detects its card type.
+ ///
+ /// - Parameters:
+ /// - cardNumber: The card number to validate and format. The card number is sanitized before validating and formatting, to filter out non-numerical characters.
+ /// - acceptedCardTypes: The card types to check against for detecting the card type.
+ /// - Returns: A tuple containing a boolean value indicating whether the card number is valid, the detected card type, and the formatted card number.
+ public static func validate(cardNumber: String, acceptedCardTypes: [CardType] = CardType.all) -> (isValid: Bool, type: CardType?, formattedNumber: String) {
+ let sanitizedCardNumber = sanitize(cardNumber)
- for tuple in digitStrings.enumerated() {
-
- guard let digit = Int(tuple.element) else { return false }
- let odd = tuple.offset % 2 == 1
-
- switch (odd, digit) {
- case (true, 9):
- sum += 9
- case (true, 0...8):
- sum += (digit * 2) % 9
- default:
- sum += digit
- }
- }
+ let cardType = acceptedCardTypes.first { $0.matches(cardNumber: sanitizedCardNumber) }
+ let formattedCardNumber = sanitizedCardNumber.grouped(length: 4)
+ let isValid = sanitizedCardNumber.characters.count >= minimumValidCardLength && luhnCheck(sanitizedCardNumber)
- return sum % 10 == 0
+ return (isValid, cardType, formattedCardNumber)
}
- static func validate(card: String, acceptedCards: [CardType]) -> (type: CardType, formatted: String, valid: Bool) {
- let numberOnly = card.numberOnly()
+ /// Validates and formats the given expiration date.
+ ///
+ /// - Parameters:
+ /// - expiryDate: The expiry date to validate and format. The expiry date is sanitized before validating and formatting, to filter out non-numerical characters.
+ /// - separator: The optional string to use to separate the month and year in the formatted date, default is `/`.
+ /// - Returns: A tuple containing a boolean value indicating whether the expiry date is valid, and a formatted expiry date.
+ public static func validate(expiryDate: String, separator: String? = "/") -> (isValid: Bool, formattedDate: String) {
+ let separator = separator ?? ""
- var type: CardType = .unknown
- var formatted = ""
- var valid = false
+ let sanitizedString = sanitize(expiryDate)
- for card in acceptedCards {
- if matchesRegex(card.regex, text: numberOnly) {
- type = card
- break
- }
- }
-
- valid = luhnCheck(numberOnly) && numberOnly.characters.count >= minValidCardLength
-
- var formatted4 = ""
- for character in numberOnly.characters {
- if formatted4.characters.count == 4 {
- formatted += formatted4 + " "
- formatted4 = ""
- }
- formatted4.append(character)
- }
-
- formatted += formatted4 // the rest
-
- return (type, formatted, valid)
- }
-
- static func validate(expiryDate: String, split: Bool = true) -> (formatted: String, valid: Bool, month: String, year: String) {
- let suffix = split ? " / " : ""
-
- let numberOnly = expiryDate.numberOnly()
- var formatted = numberOnly
- var valid = false
+ let yearPrefix = "20"
+ var formattedDate = sanitizedString
var month = 0
var year = 0
- let yearPrefix = "20"
-
- switch numberOnly.characters.count {
+ switch sanitizedString.characters.count {
case 0: break
case 1:
- month = Int(numberOnly)!
+ month = Int(sanitizedString)!
+
if month > 1 {
- formatted = "0" + numberOnly + suffix
+ formattedDate = "0" + sanitizedString + separator
}
-
case 2:
- month = Int(numberOnly)!
- formatted = numberOnly + suffix
+ month = Int(sanitizedString)!
+ formattedDate = sanitizedString + separator
case 3:
- month = Int(numberOnly[0...1])!
- formatted = numberOnly[0...1] + suffix + numberOnly[2]
+ month = Int(sanitizedString[0...1])!
+ formattedDate = sanitizedString[0...1] + separator + sanitizedString[2]
case 4:
- month = Int(numberOnly[0...1])!
- year = Int(yearPrefix + numberOnly[2...3])!
- formatted = numberOnly[0...1] + suffix + numberOnly[2...3]
+ month = Int(sanitizedString[0...1])!
+ year = Int(yearPrefix + sanitizedString[2...3])!
+ formattedDate = sanitizedString[0...1] + separator + sanitizedString[2...3]
default:
break
}
- let validMonth = (month >= 1 && month <= 12) ? true : false
-
- if month > 12 {
- formatted = ""
+ let isMonthValid = (month >= 1 && month <= 12)
+ if !isMonthValid {
+ formattedDate = ""
}
+ var isValid = false
if year > 0 {
let date = Date()
let calendar = Calendar.current
- let components = (calendar as NSCalendar).components([.month, .year], from: date)
- let currentYear = components.year
- let currentMonth = components.month
+ let components = calendar.dateComponents([.month, .year], from: date)
+ let currentMonth = components.month!
+ let currentYear = components.year!
// year already has "20"+ here
- if year == currentYear! && month < currentMonth! {
- valid = false
- } else if year == currentYear! && validMonth && month >= currentMonth! {
- valid = true
- } else if year > currentYear! && validMonth {
- valid = true
+ if year == currentYear && month < currentMonth {
+ isValid = false
+ } else if year == currentYear && isMonthValid && month >= currentMonth {
+ isValid = true
+ } else if year > currentYear && isMonthValid {
+ isValid = true
} else {
- valid = false
+ isValid = false
}
}
- return (formatted, valid, String(month), String(year))
+ return (isValid, formattedDate)
}
+
+ /// Validates and formats the given cvc.
+ ///
+ /// - Parameters:
+ /// - cvc: The cvc value to validate and format. The cvc is sanitized before validating and formatting, to filter out non-numerical characters.
+ /// - Returns: A tuple containing a boolean value indicating whether the cvc is valid, and the formatted cvc string.
+ public static func validate(cvc: String) -> (isValid: Bool, formattedCvc: String) {
+ let sanitizedCvc = sanitize(cvc)
+ let isValid = sanitizedCvc.characters.count >= 3
+ return (isValid, sanitizedCvc)
+ }
+
+ // MARK: - Private
+
+ private static let minimumValidCardLength = 12
+
+ private static func sanitize(_ string: String) -> String {
+ let allowedCharacters = CharacterSet.decimalDigits
+ let filteredUnicodeScalars = string.unicodeScalars.filter(allowedCharacters.contains(_:))
+
+ let sanitizedString = filteredUnicodeScalars.reduce("") { (string, unicodeScalar) -> String in
+ return string + String(unicodeScalar)
+ }
+
+ return sanitizedString
+ }
+
+ private static func luhnCheck(_ cardNumber: String) -> Bool {
+ let reversedCardNumberDigits = cardNumber.characters.reversed().flatMap { Int(String($0)) }
+
+ var sum = 0
+ for (index, digit) in reversedCardNumberDigits.enumerated() {
+ let isOdd = index % 2 == 1
+
+ switch (isOdd, digit) {
+ case (true, 9):
+ sum += 9
+ case (true, 0...8):
+ sum += (digit * 2) % 9
+ default:
+ sum += digit
+ }
+ }
+
+ return sum % 10 == 0
+ }
+
+}
+
+fileprivate extension CardType {
+
+ fileprivate func matches(cardNumber: String) -> Bool {
+ do {
+ let regularExpression = try NSRegularExpression(pattern: regex, options: [])
+ let range = NSRange(location: 0, length: cardNumber.characters.count)
+
+ return regularExpression.firstMatch(in: cardNumber, options: [], range: range) != nil
+ } catch {
+ return false
+ }
+ }
+
}
diff --git a/Adyen/Plugins/Cards/CardsDetailsPresenter.swift b/Adyen/Plugins/Cards/CardsDetailsPresenter.swift
index 2d30d5312a..5ed5c4891b 100644
--- a/Adyen/Plugins/Cards/CardsDetailsPresenter.swift
+++ b/Adyen/Plugins/Cards/CardsDetailsPresenter.swift
@@ -15,14 +15,16 @@ class CardsDetailsPresenter: PaymentMethodDetailsPresenter {
var finalCompletion: ((PaymentDetails) -> Void)?
var requiredPaymentDetails: PaymentDetails?
var paymentRequest: PaymentRequest?
+ var appearanceConfiguration: AppearanceConfiguration!
- func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, completion: @escaping (PaymentDetails) -> Void) {
+ func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, appearanceConfiguration: AppearanceConfiguration, completion: @escaping (PaymentDetails) -> Void) {
self.hostViewController = hostViewController
self.paymentRequest = paymentRequest
requiredPaymentDetails = paymentDetails
finalCompletion = completion
+ self.appearanceConfiguration = appearanceConfiguration
- if let oneClick = paymentRequest.paymentMethod?.oneClick {
+ if let oneClick = paymentRequest.paymentMethod?.isOneClick {
oneClick ? setupOneClickFlow() : setupCardFormFlow(paymentDetails: paymentDetails)
}
}
@@ -36,21 +38,24 @@ class CardsDetailsPresenter: PaymentMethodDetailsPresenter {
private lazy var oneClickAlertController: UIAlertController = {
let paymentRequest = self.paymentRequest!
- let title = "Verify your card"
- let message = "Please enter the CVC code for \(paymentRequest.paymentMethod!.name)"
+ let title = ADYLocalizedString("creditCard.oneClickVerification.title")
+ let message = ADYLocalizedString("creditCard.oneClickVerification.message", paymentRequest.paymentMethod!.name)
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
alertController.addTextField(configurationHandler: { textField in
- textField.placeholder = "123"
textField.textAlignment = .center
textField.keyboardType = .numberPad
+ textField.placeholder = ADYLocalizedString("creditCard.cvcField.placeholder")
+ textField.accessibilityLabel = ADYLocalizedString("creditCard.cvcField.title")
})
- let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
+ let cancelActionTitle = ADYLocalizedString("cancelButton.title")
+ let cancelAction = UIAlertAction(title: cancelActionTitle, style: .cancel, handler: nil)
alertController.addAction(cancelAction)
let formattedAmount = Currency.formatted(amount: paymentRequest.amount!, currency: paymentRequest.currency!) ?? ""
- let confirmAction = UIAlertAction(title: "Pay \(formattedAmount)", style: .default) { [unowned self] _ in
+ let confirmActionTitle = ADYLocalizedString("payButton.title.formatted", formattedAmount)
+ let confirmAction = UIAlertAction(title: confirmActionTitle, style: .default) { [unowned self] _ in
self.didSelectOneClickAlertControllerConfirmAction()
}
alertController.addAction(confirmAction)
@@ -74,9 +79,12 @@ class CardsDetailsPresenter: PaymentMethodDetailsPresenter {
}
private func presentInvalidCVCAlertController() {
- let alertController = UIAlertController(title: "Invalid CVC", message: "Please enter a valid CVC to continue.", preferredStyle: .alert)
+ let alertController = UIAlertController(title: ADYLocalizedString("creditCard.oneClickVerification.invalidInput.title"),
+ message: ADYLocalizedString("creditCard.oneClickVerification.invalidInput.message"),
+ preferredStyle: .alert)
- let dismissAction = UIAlertAction(title: "OK", style: .default) { [unowned self] _ in
+ let dismissActionTitle = ADYLocalizedString("dismissButton.title")
+ let dismissAction = UIAlertAction(title: dismissActionTitle, style: .default) { [unowned self] _ in
self.present() // Restart the flow.
}
alertController.addAction(dismissAction)
@@ -89,7 +97,7 @@ class CardsDetailsPresenter: PaymentMethodDetailsPresenter {
private func setupCardFormFlow(paymentDetails: PaymentDetails) {
if let request = paymentRequest {
- let cardsFormController = CardFormViewController(nibName: "CardFormViewController", bundle: Bundle(for: CardsDetailsPresenter.self))
+ let cardsFormController = CardFormViewController(appearanceConfiguration: appearanceConfiguration)
cardsFormController.formattedAmount = Currency.formatted(amount: request.amount!, currency: request.currency!)
cardsFormController.paymentMethod = request.paymentMethod
@@ -133,7 +141,7 @@ class CardsDetailsPresenter: PaymentMethodDetailsPresenter {
return
}
- if method.oneClick {
+ if method.isOneClick {
hostViewController?.present(rootViewController, animated: true, completion: nil)
} else {
if let navController = hostViewController as? UINavigationController {
@@ -148,7 +156,7 @@ class CardsDetailsPresenter: PaymentMethodDetailsPresenter {
return
}
- if method.oneClick {
+ if method.isOneClick {
rootViewController?.dismiss(animated: true, completion: nil)
} else {
rootViewController?.navigationController?.popViewController(animated: true)
diff --git a/Adyen/Plugins/Cards/CardsPlugin.swift b/Adyen/Plugins/Cards/CardsPlugin.swift
index 321b19f16d..6378af7ef5 100644
--- a/Adyen/Plugins/Cards/CardsPlugin.swift
+++ b/Adyen/Plugins/Cards/CardsPlugin.swift
@@ -10,17 +10,6 @@ import AdyenCSE
class CardsPlugin: BasePlugin {
- override func linnearFlow() -> Bool {
- guard let method = self.method else {
- return super.linnearFlow()
- }
-
- if method.oneClick {
- return false
- }
-
- return true
- }
}
extension CardsPlugin: UIPresentable {
diff --git a/Adyen/Plugins/Cards/CheckoutTextField.swift b/Adyen/Plugins/Cards/CheckoutTextField.swift
index 24465db32b..b06fa8facd 100644
--- a/Adyen/Plugins/Cards/CheckoutTextField.swift
+++ b/Adyen/Plugins/Cards/CheckoutTextField.swift
@@ -14,9 +14,11 @@ class CardNumberField: CheckoutTextField {
var cardTypeDetected: ((CardType) -> Void)?
- var card = CardType.unknown {
+ var card: CardType? {
didSet {
- self.cardTypeDetected?(card)
+ if let card = card {
+ self.cardTypeDetected?(card)
+ }
}
}
diff --git a/Adyen/Plugins/Ideal/IdealDetailsPresenter.swift b/Adyen/Plugins/Ideal/IdealDetailsPresenter.swift
index cf2c71f1a2..f0870aaeb5 100644
--- a/Adyen/Plugins/Ideal/IdealDetailsPresenter.swift
+++ b/Adyen/Plugins/Ideal/IdealDetailsPresenter.swift
@@ -16,13 +16,14 @@ class IdealDetailsPresenter: PaymentMethodDetailsPresenter {
self.items = items
}
- func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, completion: @escaping (PaymentDetails) -> Void) {
+ func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, appearanceConfiguration: AppearanceConfiguration, completion: @escaping (PaymentDetails) -> Void) {
self.hostViewController = hostViewController as? UINavigationController
issuerPickerViewController = IdealIssuerPickerViewController(items: items) { item in
paymentDetails.fillIdeal(issuerIdentifier: item.identifier)
completion(paymentDetails)
}
+ issuerPickerViewController?.title = paymentRequest.paymentMethod?.name
}
func present() {
diff --git a/Adyen/Plugins/Ideal/IdealIssuerPickerViewController.swift b/Adyen/Plugins/Ideal/IdealIssuerPickerViewController.swift
index d96f9ba50b..332a925bc5 100644
--- a/Adyen/Plugins/Ideal/IdealIssuerPickerViewController.swift
+++ b/Adyen/Plugins/Ideal/IdealIssuerPickerViewController.swift
@@ -20,9 +20,8 @@ class IdealIssuerPickerViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
- title = NSLocalizedString("iDEAL", comment: "")
- tableView.backgroundColor = UIColor.checkoutBackground()
+ tableView.backgroundColor = UIColor.checkoutBackground
tableView.cellLayoutMarginsFollowReadableWidth = false
tableView.separatorInset = UIEdgeInsets.zero
tableView.layoutMargins = UIEdgeInsets.zero
diff --git a/Adyen/Plugins/Ideal/IdealPlugin.swift b/Adyen/Plugins/Ideal/IdealPlugin.swift
index c357b61ef3..918a4b8814 100644
--- a/Adyen/Plugins/Ideal/IdealPlugin.swift
+++ b/Adyen/Plugins/Ideal/IdealPlugin.swift
@@ -9,10 +9,6 @@ import Foundation
class IdealPlugin: BasePlugin {
var presenter: IdealDetailsPresenter?
- override func linnearFlow() -> Bool {
- return true
- }
-
override func reset() {
super.reset()
presenter?.issuerPickerViewController?.reset()
diff --git a/Adyen/Plugins/SEPADirectDebit/IBAN/IBANSpecification.swift b/Adyen/Plugins/SEPADirectDebit/IBAN/IBANSpecification.swift
new file mode 100644
index 0000000000..8035160ed5
--- /dev/null
+++ b/Adyen/Plugins/SEPADirectDebit/IBAN/IBANSpecification.swift
@@ -0,0 +1,136 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+/// Contains the country-specific specifications for countries that adopt the IBAN standard.
+public struct IBANSpecification {
+
+ /// The code of the country to which the specifications apply.
+ public let countryCode: String
+
+ /// The length of a valid IBAN.
+ public let length: Int
+
+ /// The structure of the underlying BBAN.
+ public let structure: String
+
+ /// An example of a valid IBAN.
+ public let example: String
+
+ /// Returns the IBAN specification for the country with the given code, or `nil` if none could be found.
+ ///
+ /// - Parameter countryCode: The code of the country to retrieve the IBAN specification for.
+ public init?(forCountryCode countryCode: String) {
+ guard let specification = IBANSpecification.specifications[countryCode] else {
+ return nil
+ }
+
+ self = specification
+ }
+
+ /// Initializes the IBAN specification structure.
+ ///
+ /// - Parameters:
+ /// - countryCode: The code of the country to which the specifications apply.
+ /// - length: The length of a valid IBAN.
+ /// - structure: The structure of the underlying BBAN.
+ /// - example: An example of a valid IBAN.
+ private init(countryCode: String, length: Int, structure: String, example: String) {
+ self.countryCode = countryCode
+ self.length = length
+ self.structure = structure
+ self.example = example
+ }
+
+ private static let specifications = [
+ "AD": IBANSpecification(countryCode: "AD", length: 24, structure: "F04F04A12", example: "AD1200012030200359100100"),
+ "AE": IBANSpecification(countryCode: "AE", length: 23, structure: "F03F16", example: "AE070331234567890123456"),
+ "AL": IBANSpecification(countryCode: "AL", length: 28, structure: "F08A16", example: "AL47212110090000000235698741"),
+ "AO": IBANSpecification(countryCode: "AO", length: 25, structure: "F21", example: "AO69123456789012345678901"),
+ "AT": IBANSpecification(countryCode: "AT", length: 20, structure: "F05F11", example: "AT611904300234573201"),
+ "AZ": IBANSpecification(countryCode: "AZ", length: 28, structure: "U04A20", example: "AZ21NABZ00000000137010001944"),
+ "BA": IBANSpecification(countryCode: "BA", length: 20, structure: "F03F03F08F02", example: "BA391290079401028494"),
+ "BE": IBANSpecification(countryCode: "BE", length: 16, structure: "F03F07F02", example: "BE68539007547034"),
+ "BF": IBANSpecification(countryCode: "BF", length: 27, structure: "F23", example: "BF2312345678901234567890123"),
+ "BG": IBANSpecification(countryCode: "BG", length: 22, structure: "U04F04F02A08", example: "BG80BNBG96611020345678"),
+ "BH": IBANSpecification(countryCode: "BH", length: 22, structure: "U04A14", example: "BH67BMAG00001299123456"),
+ "BI": IBANSpecification(countryCode: "BI", length: 16, structure: "F12", example: "BI41123456789012"),
+ "BJ": IBANSpecification(countryCode: "BJ", length: 28, structure: "F24", example: "BJ39123456789012345678901234"),
+ "BR": IBANSpecification(countryCode: "BR", length: 29, structure: "F08F05F10U01A01", example: "BR9700360305000010009795493P1"),
+ "CH": IBANSpecification(countryCode: "CH", length: 21, structure: "F05A12", example: "CH9300762011623852957"),
+ "CI": IBANSpecification(countryCode: "CI", length: 28, structure: "U01F23", example: "CI17A12345678901234567890123"),
+ "CM": IBANSpecification(countryCode: "CM", length: 27, structure: "F23", example: "CM9012345678901234567890123"),
+ "CR": IBANSpecification(countryCode: "CR", length: 22, structure: "F04F14", example: "CR72012300000171549015"),
+ "CV": IBANSpecification(countryCode: "CV", length: 25, structure: "F21", example: "CV30123456789012345678901"),
+ "CY": IBANSpecification(countryCode: "CY", length: 28, structure: "F03F05A16", example: "CY17002001280000001200527600"),
+ "CZ": IBANSpecification(countryCode: "CZ", length: 24, structure: "F04F06F10", example: "CZ6508000000192000145399"),
+ "DE": IBANSpecification(countryCode: "DE", length: 22, structure: "F08F10", example: "DE89370400440532013000"),
+ "DK": IBANSpecification(countryCode: "DK", length: 18, structure: "F04F09F01", example: "DK5000400440116243"),
+ "DO": IBANSpecification(countryCode: "DO", length: 28, structure: "U04F20", example: "DO28BAGR00000001212453611324"),
+ "DZ": IBANSpecification(countryCode: "DZ", length: 24, structure: "F20", example: "DZ8612345678901234567890"),
+ "EE": IBANSpecification(countryCode: "EE", length: 20, structure: "F02F02F11F01", example: "EE382200221020145685"),
+ "ES": IBANSpecification(countryCode: "ES", length: 24, structure: "F04F04F01F01F10", example: "ES9121000418450200051332"),
+ "FI": IBANSpecification(countryCode: "FI", length: 18, structure: "F06F07F01", example: "FI2112345600000785"),
+ "FO": IBANSpecification(countryCode: "FO", length: 18, structure: "F04F09F01", example: "FO6264600001631634"),
+ "FR": IBANSpecification(countryCode: "FR", length: 27, structure: "F05F05A11F02", example: "FR1420041010050500013M02606"),
+ "GB": IBANSpecification(countryCode: "GB", length: 22, structure: "U04F06F08", example: "GB29NWBK60161331926819"),
+ "GE": IBANSpecification(countryCode: "GE", length: 22, structure: "U02F16", example: "GE29NB0000000101904917"),
+ "GI": IBANSpecification(countryCode: "GI", length: 23, structure: "U04A15", example: "GI75NWBK000000007099453"),
+ "GL": IBANSpecification(countryCode: "GL", length: 18, structure: "F04F09F01", example: "GL8964710001000206"),
+ "GR": IBANSpecification(countryCode: "GR", length: 27, structure: "F03F04A16", example: "GR1601101250000000012300695"),
+ "GT": IBANSpecification(countryCode: "GT", length: 28, structure: "A04A20", example: "GT82TRAJ01020000001210029690"),
+ "HR": IBANSpecification(countryCode: "HR", length: 21, structure: "F07F10", example: "HR1210010051863000160"),
+ "HU": IBANSpecification(countryCode: "HU", length: 28, structure: "F03F04F01F15F01", example: "HU42117730161111101800000000"),
+ "IE": IBANSpecification(countryCode: "IE", length: 22, structure: "U04F06F08", example: "IE29AIBK93115212345678"),
+ "IL": IBANSpecification(countryCode: "IL", length: 23, structure: "F03F03F13", example: "IL620108000000099999999"),
+ "IR": IBANSpecification(countryCode: "IR", length: 26, structure: "F22", example: "IR861234568790123456789012"),
+ "IS": IBANSpecification(countryCode: "IS", length: 26, structure: "F04F02F06F10", example: "IS140159260076545510730339"),
+ "IT": IBANSpecification(countryCode: "IT", length: 27, structure: "U01F05F05A12", example: "IT60X0542811101000000123456"),
+ "JO": IBANSpecification(countryCode: "JO", length: 30, structure: "A04F22", example: "JO15AAAA1234567890123456789012"),
+ "KW": IBANSpecification(countryCode: "KW", length: 30, structure: "U04A22", example: "KW81CBKU0000000000001234560101"),
+ "KZ": IBANSpecification(countryCode: "KZ", length: 20, structure: "F03A13", example: "KZ86125KZT5004100100"),
+ "LB": IBANSpecification(countryCode: "LB", length: 28, structure: "F04A20", example: "LB62099900000001001901229114"),
+ "LC": IBANSpecification(countryCode: "LC", length: 32, structure: "U04F24", example: "LC07HEMM000100010012001200013015"),
+ "LI": IBANSpecification(countryCode: "LI", length: 21, structure: "F05A12", example: "LI21088100002324013AA"),
+ "LT": IBANSpecification(countryCode: "LT", length: 20, structure: "F05F11", example: "LT121000011101001000"),
+ "LU": IBANSpecification(countryCode: "LU", length: 20, structure: "F03A13", example: "LU280019400644750000"),
+ "LV": IBANSpecification(countryCode: "LV", length: 21, structure: "U04A13", example: "LV80BANK0000435195001"),
+ "MC": IBANSpecification(countryCode: "MC", length: 27, structure: "F05F05A11F02", example: "MC5811222000010123456789030"),
+ "MD": IBANSpecification(countryCode: "MD", length: 24, structure: "U02A18", example: "MD24AG000225100013104168"),
+ "ME": IBANSpecification(countryCode: "ME", length: 22, structure: "F03F13F02", example: "ME25505000012345678951"),
+ "MG": IBANSpecification(countryCode: "MG", length: 27, structure: "F23", example: "MG1812345678901234567890123"),
+ "MK": IBANSpecification(countryCode: "MK", length: 19, structure: "F03A10F02", example: "MK07250120000058984"),
+ "ML": IBANSpecification(countryCode: "ML", length: 28, structure: "U01F23", example: "ML15A12345678901234567890123"),
+ "MR": IBANSpecification(countryCode: "MR", length: 27, structure: "F05F05F11F02", example: "MR1300020001010000123456753"),
+ "MT": IBANSpecification(countryCode: "MT", length: 31, structure: "U04F05A18", example: "MT84MALT011000012345MTLCAST001S"),
+ "MU": IBANSpecification(countryCode: "MU", length: 30, structure: "U04F02F02F12F03U03", example: "MU17BOMM0101101030300200000MUR"),
+ "MZ": IBANSpecification(countryCode: "MZ", length: 25, structure: "F21", example: "MZ25123456789012345678901"),
+ "NL": IBANSpecification(countryCode: "NL", length: 18, structure: "U04F10", example: "NL91ABNA0417164300"),
+ "NO": IBANSpecification(countryCode: "NO", length: 15, structure: "F04F06F01", example: "NO9386011117947"),
+ "PK": IBANSpecification(countryCode: "PK", length: 24, structure: "U04A16", example: "PK36SCBL0000001123456702"),
+ "PL": IBANSpecification(countryCode: "PL", length: 28, structure: "F08F16", example: "PL61109010140000071219812874"),
+ "PS": IBANSpecification(countryCode: "PS", length: 29, structure: "U04A21", example: "PS92PALS000000000400123456702"),
+ "PT": IBANSpecification(countryCode: "PT", length: 25, structure: "F04F04F11F02", example: "PT50000201231234567890154"),
+ "QA": IBANSpecification(countryCode: "QA", length: 29, structure: "U04A21", example: "QA30AAAA123456789012345678901"),
+ "RO": IBANSpecification(countryCode: "RO", length: 24, structure: "U04A16", example: "RO49AAAA1B31007593840000"),
+ "RS": IBANSpecification(countryCode: "RS", length: 22, structure: "F03F13F02", example: "RS35260005601001611379"),
+ "SA": IBANSpecification(countryCode: "SA", length: 24, structure: "F02A18", example: "SA0380000000608010167519"),
+ "SE": IBANSpecification(countryCode: "SE", length: 24, structure: "F03F16F01", example: "SE4550000000058398257466"),
+ "SI": IBANSpecification(countryCode: "SI", length: 19, structure: "F05F08F02", example: "SI56263300012039086"),
+ "SK": IBANSpecification(countryCode: "SK", length: 24, structure: "F04F06F10", example: "SK3112000000198742637541"),
+ "SM": IBANSpecification(countryCode: "SM", length: 27, structure: "U01F05F05A12", example: "SM86U0322509800000000270100"),
+ "SN": IBANSpecification(countryCode: "SN", length: 28, structure: "U01F23", example: "SN52A12345678901234567890123"),
+ "ST": IBANSpecification(countryCode: "ST", length: 25, structure: "F08F11F02", example: "ST68000100010051845310112"),
+ "TL": IBANSpecification(countryCode: "TL", length: 23, structure: "F03F14F02", example: "TL380080012345678910157"),
+ "TN": IBANSpecification(countryCode: "TN", length: 24, structure: "F02F03F13F02", example: "TN5910006035183598478831"),
+ "TR": IBANSpecification(countryCode: "TR", length: 26, structure: "F05F01A16", example: "TR330006100519786457841326"),
+ "UA": IBANSpecification(countryCode: "UA", length: 29, structure: "F25", example: "UA511234567890123456789012345"),
+ "VG": IBANSpecification(countryCode: "VG", length: 24, structure: "U04F16", example: "VG96VPVG0000012345678901"),
+ "XK": IBANSpecification(countryCode: "XK", length: 20, structure: "F04F10F02", example: "XK051212012345678906")
+ ]
+
+}
diff --git a/Adyen/Plugins/SEPADirectDebit/IBAN/IBANTextField.swift b/Adyen/Plugins/SEPADirectDebit/IBAN/IBANTextField.swift
new file mode 100644
index 0000000000..f8a56dba66
--- /dev/null
+++ b/Adyen/Plugins/SEPADirectDebit/IBAN/IBANTextField.swift
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+/// Provides a text field designed for the entry of an IBAN value. This field formats and validates the IBAN in real time.
+public class IBANTextField: UITextField {
+
+ /// :nodoc:
+ public override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ configure()
+ }
+
+ /// :nodoc:
+ public required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+
+ configure()
+ }
+
+ /// The IBAN entered in the text field, or `nil` if no valid IBAN has been entered.
+ public var iban: String? {
+ guard let text = text else {
+ return nil
+ }
+
+ guard IBANValidator.isValid(text) else {
+ return nil
+ }
+
+ return text
+ }
+
+ // MARK: Configuration
+
+ private func configure() {
+ autocapitalizationType = .allCharacters
+ autocorrectionType = .no
+
+ addTarget(self, action: #selector(editingDidBegin), for: .editingDidBegin)
+ addTarget(self, action: #selector(editingDidEnd), for: .editingDidEnd)
+ addTarget(self, action: #selector(textDidChange), for: .editingChanged)
+
+ configurePlaceholder()
+ }
+
+ private func configurePlaceholder() {
+ var exampleIBAN: String!
+
+ if let countryCode = Locale.current.regionCode, let specification = IBANSpecification(forCountryCode: countryCode) {
+ exampleIBAN = specification.example
+ } else {
+ exampleIBAN = IBANSpecification(forCountryCode: "NL")!.example
+ }
+
+ placeholder = exampleIBAN.grouped(length: 4)
+ }
+
+ // MARK: Events
+
+ @objc private func editingDidBegin() {
+ updateTextColor()
+ }
+
+ @objc private func editingDidEnd() {
+ updateTextColor()
+ }
+
+ @objc private func textDidChange() {
+ formatText()
+ }
+
+ // MARK: Formatting
+
+ private func formatText() {
+ let text = IBANValidator.canonicalize(self.text ?? "")
+ self.text = text.grouped(length: 4)
+ }
+
+ // MARK: Text Color
+
+ private func updateTextColor() {
+ if isEditing {
+ textColor = UIColor.black
+ } else {
+ textColor = (iban != nil) ? UIColor.black : UIColor.red
+ }
+ }
+
+}
diff --git a/Adyen/Plugins/SEPADirectDebit/IBAN/IBANValidator.swift b/Adyen/Plugins/SEPADirectDebit/IBAN/IBANValidator.swift
new file mode 100644
index 0000000000..0096111c58
--- /dev/null
+++ b/Adyen/Plugins/SEPADirectDebit/IBAN/IBANValidator.swift
@@ -0,0 +1,162 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+/// Provides a static method to validate an IBAN value.
+public class IBANValidator {
+
+ /// Checks if the given string is a valid IBAN value.
+ ///
+ /// - Parameter string: The string to check.
+ /// - Returns: A Boolean value indicating whether the given string is a valid IBAN.
+ public static func isValid(_ string: String) -> Bool {
+ // Canonicalize the string for processing.
+ let canonicalizedString = canonicalize(string)
+
+ // Retrieve the country code from the IBAN.
+ guard let countryCode = countryCode(in: canonicalizedString) else {
+ return false
+ }
+
+ // Retrieve the IBAN specification for the country.
+ guard let specification = IBANSpecification(forCountryCode: countryCode) else {
+ return false
+ }
+
+ // Check if the string matches the length of a valid IBAN according to the country's specification.
+ guard canonicalizedString.characters.count == specification.length else {
+ return false
+ }
+
+ // Rearrange the string.
+ let rearrangedString = rearrange(canonicalizedString)
+
+ // Convert the string to numbers.
+ let numerifiedString = numerify(rearrangedString)
+
+ // Calculate the modulus of the numerified string.
+ guard let modulus = mod97(numerifiedString) else {
+ return false
+ }
+
+ // The IBAN is valid of the mod97 operation returns 1.
+ return modulus == 1
+ }
+
+ /// Prepares the given string for IBAN validation. Removes all invalid characters and converts lowercase letters to uppercase letters.
+ ///
+ /// - Parameter string: The string to canonicalize.
+ /// - Returns: A canonicalized string.
+ internal static func canonicalize(_ string: String) -> String {
+ let alphanumerics = CharacterSet.alphanumerics
+ let lowercaseLetters = CharacterSet.lowercaseLetters
+
+ let components = string.unicodeScalars.flatMap { unicodeScalar -> String? in
+ guard alphanumerics.contains(unicodeScalar) else {
+ return nil
+ }
+
+ if lowercaseLetters.contains(unicodeScalar) {
+ return String(unicodeScalar).uppercased()
+ }
+
+ return String(unicodeScalar)
+
+ }
+
+ return components.joined()
+ }
+
+ /// Retrieves the country code (the first two letters of an IBAN) from a given string.
+ ///
+ /// - Parameter string: The string to retrieve the country code from.
+ /// - Returns: The country code in the string, or `nil` if the country code couldn't be found.
+ internal static func countryCode(in string: String) -> String? {
+ guard string.characters.count >= 2 else {
+ return nil
+ }
+
+ let lowerBound = string.startIndex
+ let upperBound = string.index(lowerBound, offsetBy: 2)
+ let range = lowerBound.. String {
+ let index = string.index(string.startIndex, offsetBy: 4)
+ let lowerSubstring = string.substring(to: index)
+ let upperSubstring = string.substring(from: index)
+
+ return upperSubstring + lowerSubstring
+ }
+
+ /// Converts every letter in a string to a number, where A is 10, B is 11, Z is 35.
+ /// All letters should be uppercased.
+ ///
+ /// - Parameter string: The string to convert to numbers.
+ /// - Returns: A numbers-only string.
+ internal static func numerify(_ string: String) -> String {
+ let startIndex = ("A" as UnicodeScalar).value
+ let endIndex = ("Z" as UnicodeScalar).value
+ let range = startIndex...endIndex
+
+ let components = string.unicodeScalars.map { unicodeScalar -> String in
+ guard range.contains(unicodeScalar.value) else {
+ return String(unicodeScalar)
+ }
+
+ let numericalValue = 10 + unicodeScalar.value - startIndex
+
+ return String(numericalValue)
+ }
+
+ return components.joined()
+ }
+
+ /// Performs a mod-97 operation on a given string. The string can be of infinite length, but should contain numbers only.
+ ///
+ /// - Parameter string: A numbers-only string on which to perform the mod-97 operation.
+ /// - Returns: The remainder of the string divided by 97, or `nil` if the operation failed.
+ internal static func mod97(_ string: String) -> Int? {
+ func modulo(_ string: String) -> Int? {
+ guard let integer = Int(string) else {
+ return nil
+ }
+
+ return integer % 97
+ }
+
+ guard string.characters.count < 9 else {
+ let splitIndex = string.index(string.startIndex, offsetBy: 9)
+ let lowerSubstring = string.substring(to: splitIndex)
+ let upperSubstring = string.substring(from: splitIndex)
+
+ guard let lowerSubstringModulus = modulo(lowerSubstring) else {
+ return nil
+ }
+
+ return mod97(String(lowerSubstringModulus) + upperSubstring)
+ }
+
+ return modulo(string)
+ }
+
+}
diff --git a/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitDetailsPresenter.swift b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitDetailsPresenter.swift
new file mode 100644
index 0000000000..f5ed8fa40f
--- /dev/null
+++ b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitDetailsPresenter.swift
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+class SEPADirectDebitDetailsPresenter: PaymentMethodDetailsPresenter {
+
+ private var hostViewController: UIViewController!
+
+ private var paymentRequest: PaymentRequest!
+
+ private var paymentDetails: PaymentDetails!
+
+ private var paymentDetailsCompletion: PaymentDetailsCompletion!
+
+ private var appearanceConfiguration: AppearanceConfiguration!
+
+ func setup(with hostViewController: UIViewController, paymentRequest: PaymentRequest, paymentDetails: PaymentDetails, appearanceConfiguration: AppearanceConfiguration, completion: @escaping (PaymentDetails) -> Void) {
+ self.hostViewController = hostViewController
+ self.paymentRequest = paymentRequest
+ self.paymentDetails = paymentDetails
+ paymentDetailsCompletion = completion
+ self.appearanceConfiguration = appearanceConfiguration
+ }
+
+ func present() {
+ let formattedAmount = Currency.formatted(amount: paymentRequest.amount!, currency: paymentRequest.currency!)!
+
+ let formViewController = SEPADirectDebitFormViewController(appearanceConfiguration: appearanceConfiguration)
+ formViewController.title = paymentRequest.paymentMethod?.name
+ formViewController.delegate = self
+ formViewController.formattedAmount = formattedAmount
+
+ let navigationController = hostViewController as? UINavigationController
+ navigationController?.pushViewController(formViewController, animated: true)
+ }
+
+ func dismiss(animated: Bool, completion: @escaping () -> Void) {
+ let navigationController = hostViewController as? UINavigationController
+ navigationController?.popViewController(animated: true)
+ }
+
+ fileprivate func finish(withIBAN iban: String, name: String) {
+ paymentDetails.fillSepa(name: name, iban: iban)
+ paymentDetailsCompletion(paymentDetails)
+ }
+
+}
+
+extension SEPADirectDebitDetailsPresenter: SEPADirectDebitFormViewControllerDelegate {
+
+ func formViewController(_ formViewController: SEPADirectDebitFormViewController, didSubmitWithIBAN iban: String, name: String) {
+ formViewController.isLoading = true
+
+ finish(withIBAN: iban, name: name)
+ }
+
+}
diff --git a/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitFormViewController.swift b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitFormViewController.swift
new file mode 100644
index 0000000000..60bdf45f69
--- /dev/null
+++ b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitFormViewController.swift
@@ -0,0 +1,158 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import UIKit
+
+class SEPADirectDebitFormViewController: UIViewController {
+
+ internal init(appearanceConfiguration: AppearanceConfiguration) {
+ self.appearanceConfiguration = appearanceConfiguration
+
+ super.init(nibName: "SEPADirectDebitFormViewController", bundle: Bundle(for: SEPADirectDebitFormViewController.self))
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ internal weak var delegate: SEPADirectDebitFormViewControllerDelegate?
+
+ internal var formattedAmount = ""
+
+ private let appearanceConfiguration: AppearanceConfiguration
+
+ // MARK: View
+
+ @IBOutlet private weak var scrollView: UIScrollView!
+
+ @IBOutlet private weak var lockView: UIImageView!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ lockView.image = UIImage.bundleImage("lock")
+ checkmarkButton.setImage(UIImage.bundleImage("checkbox_inactive"), for: .normal)
+ checkmarkButton.setImage(UIImage.bundleImage("checkbox_active"), for: .selected)
+ checkmarkButton.tintColor = appearanceConfiguration.tintColor
+
+ payButton.title = ADYLocalizedString("payButton.title.formatted", formattedAmount)
+ payButton.appearanceConfiguration = appearanceConfiguration
+ payButton.isEnabled = false
+
+ let notificationCenter = NotificationCenter.default
+ notificationCenter.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: .UIKeyboardWillChangeFrame, object: nil)
+ }
+
+ override func viewWillAppear(_ animated: Bool) {
+ super.viewWillAppear(animated)
+
+ if isEditing == false {
+ ibanField.becomeFirstResponder()
+ }
+ }
+
+ // MARK: Text Fields
+
+ @IBOutlet private weak var ibanField: IBANTextField!
+
+ @IBOutlet private weak var ibanUnderlineView: UIView!
+
+ private var name: String {
+ return nameField.text ?? ""
+ }
+
+ @IBOutlet private weak var nameField: UITextField!
+
+ @IBOutlet private weak var nameUnderlineView: UIView!
+
+ @IBAction private func textFieldDidChange() {
+ revalidate()
+ }
+
+ @IBAction private func textFieldDidBeginEditing(_ textField: UITextField) {
+ underlineView(for: textField)?.backgroundColor = #colorLiteral(red: 0.4588235294, green: 0.4588235294, blue: 0.4588235294, alpha: 1)
+ }
+
+ @IBAction private func textFieldDidEndEditing(_ textField: UITextField) {
+ underlineView(for: textField)?.backgroundColor = #colorLiteral(red: 0.8470588235, green: 0.8470588235, blue: 0.8470588235, alpha: 1)
+ }
+
+ @objc private func keyboardWillChangeFrame(_ notification: NSNotification) {
+ guard let bounds = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect else {
+ return
+ }
+
+ scrollView.contentInset.bottom = bounds.height
+ scrollView.scrollIndicatorInsets.bottom = bounds.height
+ }
+
+ private func underlineView(for textField: UITextField) -> UIView? {
+ if textField === ibanField {
+ return ibanUnderlineView
+ } else if textField === nameField {
+ return nameUnderlineView
+ }
+
+ return nil
+ }
+
+ // MARK: Checkmark Button
+
+ @IBOutlet private weak var checkmarkButton: UIButton!
+
+ @IBAction private func didSelect(checkmarkButton: UIButton) {
+ checkmarkButton.isSelected = !checkmarkButton.isSelected
+
+ revalidate()
+ }
+
+ // MARK: Pay Button
+
+ @IBOutlet private weak var payButton: CheckoutButton!
+
+ @IBAction private func didSelect(payButton: CheckoutButton) {
+ guard let iban = ibanField.iban else {
+ return
+ }
+
+ delegate?.formViewController(self, didSubmitWithIBAN: iban, name: name)
+ }
+
+ // MARK: Validation
+
+ private var isValid: Bool {
+ guard checkmarkButton.isSelected else {
+ return false
+ }
+
+ guard ibanField.iban != nil else {
+ return false
+ }
+
+ guard name.characters.count > 0 else {
+ return false
+ }
+
+ return true
+ }
+
+ fileprivate func revalidate() {
+ payButton.isEnabled = isValid
+ }
+
+ // MARK: Loading
+
+ internal var isLoading = false {
+ didSet {
+ if isLoading {
+ setEditing(false, animated: true)
+ }
+
+ payButton.isLoading = isLoading
+ }
+ }
+
+}
diff --git a/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitFormViewController.xib b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitFormViewController.xib
new file mode 100644
index 0000000000..c8aad8086f
--- /dev/null
+++ b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitFormViewController.xib
@@ -0,0 +1,227 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitFormViewControllerDelegate.swift b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitFormViewControllerDelegate.swift
new file mode 100644
index 0000000000..9b8e702786
--- /dev/null
+++ b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitFormViewControllerDelegate.swift
@@ -0,0 +1,19 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+protocol SEPADirectDebitFormViewControllerDelegate: class {
+
+ /// Invoked when the form is submitted.
+ ///
+ /// - Parameters:
+ /// - formViewController: The form view controller which has been submitted.
+ /// - iban: A validated IBAN that has been filled in.
+ /// - name: A validated name that has been filled in.
+ func formViewController(_ formViewController: SEPADirectDebitFormViewController, didSubmitWithIBAN iban: String, name: String)
+
+}
diff --git a/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitPlugin.swift b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitPlugin.swift
new file mode 100644
index 0000000000..5246776763
--- /dev/null
+++ b/Adyen/Plugins/SEPADirectDebit/SEPADirectDebitPlugin.swift
@@ -0,0 +1,19 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+class SEPADirectDebitPlugin: BasePlugin {
+
+}
+
+extension SEPADirectDebitPlugin: UIPresentable {
+
+ func detailsPresenter() -> PaymentMethodDetailsPresenter? {
+ return SEPADirectDebitDetailsPresenter()
+ }
+
+}
diff --git a/Adyen/UI/CheckoutHeaderView.swift b/Adyen/UI/CheckoutHeaderView.swift
index af6570ce66..4ecabe39cc 100644
--- a/Adyen/UI/CheckoutHeaderView.swift
+++ b/Adyen/UI/CheckoutHeaderView.swift
@@ -38,7 +38,7 @@ extension CheckoutHeaderView {
func applyStyling() {
titleLabel.font = UIFont.systemFont(ofSize: 13)
- titleLabel.textColor = UIColor.checkoutLightDark()
+ titleLabel.textColor = UIColor.checkoutGray
textLabel?.isHidden = true
}
diff --git a/Adyen/UI/CheckoutViewController.swift b/Adyen/UI/CheckoutViewController.swift
index 7af42b0eed..e3262ef968 100644
--- a/Adyen/UI/CheckoutViewController.swift
+++ b/Adyen/UI/CheckoutViewController.swift
@@ -7,67 +7,108 @@
import UIKit
import SafariServices
-/// Starting point for [Quick integration](https://docs.adyen.com/developers/payments/accepting-payments/in-app-integration). Intialize with `CheckoutViewContollerDelegate` and present this ViewController in your app to start the payment flow.
+/// The starting point for [Quick integration](https://docs.adyen.com/developers/payments/accepting-payments/in-app-integration). Initialize with `CheckoutViewContollerDelegate` and present this view controller in your app to start the payment flow. If you don't embed the `CheckoutViewController` in an existing `UINavigationController`, a new one will be created automatically.
public final class CheckoutViewController: UIViewController {
- /// Delegate for Quick integration.
- internal(set) public weak var delegate: CheckoutViewControllerDelegate?
+ /// The delegate for Quick integration.
+ public internal(set) weak var delegate: CheckoutViewControllerDelegate?
- var paymentRequest: PaymentRequest?
- var methodCompletion: MethodCompletion?
- var currentPresenter: PaymentMethodDetailsPresenter?
+ /// The appearance configuration that was used to initialize the view controller.
+ fileprivate let appearanceConfiguration: AppearanceConfiguration
- /// Initialise the ViewController with `CheckoutViewControllerDelegate`.
- public init(delegate: CheckoutViewControllerDelegate) {
- self.init()
-
+ /// Initializes the checkout view controller.
+ ///
+ /// - Parameters:
+ /// - delegate: The delegate to receive the checkout view controller's events.
+ /// - appearanceConfiguration: The configuration to use for customizing the checkout view controller's appearance.
+ public init(delegate: CheckoutViewControllerDelegate, appearanceConfiguration: AppearanceConfiguration = .default) {
self.delegate = delegate
+ self.appearanceConfiguration = appearanceConfiguration.copied
- addChildViewController(rootViewController)
+ super.init(nibName: nil, bundle: nil)
modalPresentationStyle = .formSheet
}
- /// :nodoc:
- override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
- super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
- }
-
/// :nodoc:
public required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
+ fatalError("init(coder:) has not been implemented")
}
// MARK: Child View Controllers
- fileprivate lazy var rootViewController: UIViewController = {
- UINavigationController(rootViewController: self.paymentPickerViewController)
- }()
+ fileprivate var rootViewController: UIViewController? {
+ willSet {
+ rootViewController?.removeFromParentViewController()
+ rootViewController?.viewIfLoaded?.removeFromSuperview()
+ }
+
+ didSet {
+ guard let rootViewController = rootViewController else { return }
+
+ addChildViewController(rootViewController)
+ viewIfLoaded?.addSubview(rootViewController.view)
+ }
+ }
- fileprivate lazy var paymentPickerViewController: PaymentPickerViewController = {
- PaymentPickerViewController(delegate: self)
+ fileprivate lazy var paymentMethodPickerViewController: PaymentMethodPickerViewController = {
+ PaymentMethodPickerViewController(delegate: self, appearanceConfiguration: self.appearanceConfiguration)
}()
+ /// :nodoc:
+ public override var navigationItem: UINavigationItem {
+ return paymentMethodPickerViewController.navigationItem
+ }
+
// MARK: View
/// :nodoc:
public override func viewDidLoad() {
super.viewDidLoad()
- view.addSubview(rootViewController.view)
+ if let rootView = rootViewController?.view {
+ view.addSubview(rootView)
+ }
- startPaymentRequest()
+ paymentRequest.start()
}
-}
-
-// MARK: Payment Request
-
-extension CheckoutViewController {
- func startPaymentRequest() {
- paymentRequest = PaymentRequest(delegate: self)
- paymentRequest?.start()
+ /// :nodoc:
+ public override func viewWillAppear(_ animated: Bool) {
+ super.viewWillAppear(animated)
+
+ // If we're being presented inside a UINavigationController, skip the use of our own navigation controller.
+ if parent is UINavigationController {
+ rootViewController = paymentMethodPickerViewController
+ } else {
+ rootViewController = NavigationController(rootViewController: paymentMethodPickerViewController, appearanceConfiguration: appearanceConfiguration)
+ }
+ }
+
+ /// :nodoc:
+ public override func viewWillLayoutSubviews() {
+ super.viewWillLayoutSubviews()
+
+ rootViewController?.view.frame = view.bounds
+ }
+
+ // MARK: Status Bar
+
+ /// :nodoc:
+ public override var preferredStatusBarStyle: UIStatusBarStyle {
+ return appearanceConfiguration.preferredStatusBarStyle
}
+
+ // MARK: Payment Request
+
+ fileprivate lazy var paymentRequest: PaymentRequest = {
+ PaymentRequest(delegate: self)
+ }()
+
+ fileprivate var paymentMethodCompletion: MethodCompletion?
+
+ fileprivate var currentPaymentDetailsPresenter: PaymentMethodDetailsPresenter?
+
}
// MARK: PaymentRequestDelegate
@@ -81,9 +122,9 @@ extension CheckoutViewController: PaymentRequestDelegate {
/// :nodoc:
public func paymentRequest(_ request: PaymentRequest, requiresPaymentMethodFrom preferredMethods: [PaymentMethod]?, available availableMethods: [PaymentMethod], completion: @escaping MethodCompletion) {
- methodCompletion = completion
+ paymentMethodCompletion = completion
- paymentPickerViewController.displayMethods(preferred: preferredMethods, available: availableMethods)
+ paymentMethodPickerViewController.displayMethods(preferred: preferredMethods, available: availableMethods)
}
/// :nodoc:
@@ -99,17 +140,19 @@ extension CheckoutViewController: PaymentRequestDelegate {
/// :nodoc:
public func paymentRequest(_ request: PaymentRequest, requiresPaymentDetails details: PaymentDetails, completion: @escaping PaymentDetailsCompletion) {
- guard let method = request.paymentMethod,
+ guard
+ let method = request.paymentMethod,
let plugin = method.plugin as? UIPresentable,
let presenter = plugin.detailsPresenter() else {
completion(details)
return
}
- currentPresenter = presenter
+ currentPaymentDetailsPresenter = presenter
- presenter.setup(with: rootViewController, paymentRequest: request, paymentDetails: details) { completeDetails in
- self.paymentPickerViewController.displayPaymentMethodActivityIndicator()
+ let rootViewController = paymentMethodPickerViewController.navigationController ?? paymentMethodPickerViewController
+ presenter.setup(with: rootViewController, paymentRequest: request, paymentDetails: details, appearanceConfiguration: appearanceConfiguration) { completeDetails in
+ self.paymentMethodPickerViewController.displayPaymentMethodActivityIndicator()
completion(details)
}
@@ -119,33 +162,38 @@ extension CheckoutViewController: PaymentRequestDelegate {
/// :nodoc:
public func paymentRequest(_ request: PaymentRequest, didFinishWith result: PaymentRequestResult) {
- paymentPickerViewController.reset()
+ paymentMethodPickerViewController.reset()
delegate?.checkoutViewController(self, didFinishWith: result)
}
+
}
-// MARK: PaymentPickerViewControllerDelegate
+// MARK: PaymentMethodPickerViewControllerDelegate
-extension CheckoutViewController: PaymentPickerViewControllerDelegate {
+extension CheckoutViewController: PaymentMethodPickerViewControllerDelegate {
- func paymentPickerViewController(_ paymentPickerViewController: PaymentPickerViewController, didSelectPaymentMethod paymentMethod: PaymentMethod) {
- methodCompletion?(paymentMethod)
+ /// :nodoc:
+ func paymentMethodPickerViewController(_ paymentMethodPickerViewController: PaymentMethodPickerViewController, didSelectPaymentMethod paymentMethod: PaymentMethod) {
+ paymentMethodCompletion?(paymentMethod)
- if paymentMethod.inputDetails.isEmpty {
- paymentPickerViewController.displayPaymentMethodActivityIndicator()
+ if paymentMethod.inputDetails.isNilOrEmpty {
+ paymentMethodPickerViewController.displayPaymentMethodActivityIndicator()
}
}
- func paymentPickerViewController(_ paymentPickerViewController: PaymentPickerViewController, didSelectDeletePaymentMethod paymentMethod: PaymentMethod) {
- paymentRequest?.deletePreferred(paymentMethod: paymentMethod) { _ in
+ /// :nodoc:
+ func paymentMethodPickerViewController(_ paymentMethodPickerViewController: PaymentMethodPickerViewController, didSelectDeletePaymentMethod paymentMethod: PaymentMethod) {
+ paymentRequest.deletePreferred(paymentMethod: paymentMethod) { _ in
}
}
- func paymentPickerViewControllerDidCancel(_ paymentPickerViewController: PaymentPickerViewController) {
+ /// :nodoc:
+ func paymentMethodPickerViewControllerDidCancel(_ paymentMethodPickerViewController: PaymentMethodPickerViewController) {
delegate?.checkoutViewController(self, didFinishWith: .error(.canceled))
}
+
}
// MARK: SFSafariViewControllerDelegate
@@ -154,8 +202,9 @@ extension CheckoutViewController: SFSafariViewControllerDelegate {
/// :nodoc:
public func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
- paymentPickerViewController.reset()
+ paymentMethodPickerViewController.reset()
- paymentRequest?.paymentMethod?.plugin?.reset()
+ paymentRequest.paymentMethod?.plugin?.reset()
}
+
}
diff --git a/Adyen/UI/CheckoutViewControllerDelegate.swift b/Adyen/UI/CheckoutViewControllerDelegate.swift
index 0d3ff155c8..2f3dfe0932 100644
--- a/Adyen/UI/CheckoutViewControllerDelegate.swift
+++ b/Adyen/UI/CheckoutViewControllerDelegate.swift
@@ -4,15 +4,29 @@
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
-/// Protocol used for Quick integration comunication. All delegate methods are invoked on the main thread.
+/// The `CheckoutViewControllerDelegate` protocol defines the methods that a delegate of `CheckoutViewController` should implement to provide payment data and be informed of the payment flow progress.
public protocol CheckoutViewControllerDelegate: class {
- /// Given the controller that started the payment flow and `token`, waits for data from merchant server to be passed via `completion`.
+ /// Invoked when the payment flow has started and payment data is requested from the merchant server.
+ ///
+ /// - Parameters:
+ /// - controller: The checkout view controller that has started the payment flow.
+ /// - token: The token assigned to the payment flow.
+ /// - completion: The completion handler to invoke when the payment data is retrieved from the merchant server.
func checkoutViewController(_ controller: CheckoutViewController, requiresPaymentDataForToken token: String, completion: @escaping DataCompletion)
- /// This method is called when a URL redirection was made. When the browser process is completed, the `completion` for the given URL must be called.
+ /// Invoked when the redirection to a URL has been made. The given completion handler should be invoked when the user returns to the application through a URL.
+ ///
+ /// - Parameters:
+ /// - controller: The checkout view controller which requested the return from a URL redirection.
+ /// - completion: The completion handler to invoke when the user returns to the application through a URL.
func checkoutViewController(_ controller: CheckoutViewController, requiresReturnURL completion: @escaping URLCompletion)
- /// This method is called when the payment flow is finished.
+ /// Invoked when the payment flow has finished.
+ ///
+ /// - Parameters:
+ /// - controller: The checkout view controller that finished the payment flow.
+ /// - result: The payment result.
func checkoutViewController(_ controller: CheckoutViewController, didFinishWith result: PaymentRequestResult)
+
}
diff --git a/Adyen/UI/LoadingTableViewController.swift b/Adyen/UI/LoadingTableViewController.swift
deleted file mode 100644
index 9ed9d4e3af..0000000000
--- a/Adyen/UI/LoadingTableViewController.swift
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// Copyright (c) 2017 Adyen B.V.
-//
-// This file is open source and available under the MIT license. See the LICENSE file for more info.
-//
-
-import UIKit
-
-class LoadingTableViewController: UITableViewController {
- private let loadingView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
-
- fileprivate var _loading = false
-
- var loading: Bool {
- get {
- return _loading
- }
-
- set {
- _loading = newValue
- self.updateUI()
- }
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- loadingView.isHidden = true
- loadingView.stopAnimating()
- loadingView.translatesAutoresizingMaskIntoConstraints = false
- applyLoadingViewConstraints()
- }
-
- func applyLoadingViewConstraints() {
- view.addSubview(loadingView)
- view.addConstraint(
- NSLayoutConstraint(
- item: loadingView,
- attribute: .centerX,
- relatedBy: .equal,
- toItem: view,
- attribute: .centerX,
- multiplier: 1,
- constant: 0
- )
- )
- view.addConstraint(
- NSLayoutConstraint(
- item: loadingView,
- attribute: .centerY,
- relatedBy: .equal,
- toItem: view,
- attribute: .centerY,
- multiplier: 1,
- constant: 0
- )
- )
- }
-
- func updateUI() {
- DispatchQueue.main.async {
- self.loadingView.isHidden = !self.loading
- self.loading ? self.loadingView.startAnimating() : self.loadingView.stopAnimating()
- }
- }
-}
diff --git a/Adyen/UI/NavigationController.swift b/Adyen/UI/NavigationController.swift
new file mode 100644
index 0000000000..b0ef2c6b43
--- /dev/null
+++ b/Adyen/UI/NavigationController.swift
@@ -0,0 +1,63 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+/// The NavigationController class is an internally used subclass of UINavigationController.
+/// It customizes its appearance based on the given appearance configuration on initialization.
+internal class NavigationController: UINavigationController {
+
+ /// The appearance configuration used to customize the navigation controller's appearance.
+ private let appearanceConfiguration: AppearanceConfiguration
+
+ /// Initializes the navigation controller.
+ ///
+ /// - Parameters:
+ /// - rootViewController: The view controller that resides at the bottom of the navigation stack.
+ /// - appearanceConfiguration: The appearance configuration used to customize the navigation controller's appearance.
+ internal init(rootViewController: UIViewController, appearanceConfiguration: AppearanceConfiguration) {
+ self.appearanceConfiguration = appearanceConfiguration
+
+ super.init(nibName: nil, bundle: nil)
+
+ delegate = self
+ viewControllers = [rootViewController]
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ // MARK: View
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureNavigationBar()
+ }
+
+ private func configureNavigationBar() {
+ navigationBar.titleTextAttributes = appearanceConfiguration.navigationBarTitleTextAttributes
+ navigationBar.tintColor = appearanceConfiguration.navigationBarTintColor
+ navigationBar.barTintColor = appearanceConfiguration.navigationBarBackgroundColor
+ navigationBar.isTranslucent = appearanceConfiguration.isNavigationBarTranslucent
+ }
+
+}
+
+// MARK: Delegate
+
+extension NavigationController: UINavigationControllerDelegate {
+
+ func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
+ // Hide the back button title for all view controllers in the navigation stack.
+ viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "",
+ style: .plain,
+ target: nil,
+ action: nil)
+ }
+
+}
diff --git a/Adyen/UI/PaymentPickerViewController.swift b/Adyen/UI/PaymentMethodPickerViewController.swift
similarity index 53%
rename from Adyen/UI/PaymentPickerViewController.swift
rename to Adyen/UI/PaymentMethodPickerViewController.swift
index 39944f2b81..8440d929ab 100644
--- a/Adyen/UI/PaymentPickerViewController.swift
+++ b/Adyen/UI/PaymentMethodPickerViewController.swift
@@ -6,106 +6,92 @@
import UIKit
-class PaymentPickerViewController: LoadingTableViewController {
- fileprivate var preferredMethods = [PaymentMethod]()
- fileprivate var availableMethods = [PaymentMethod]()
+/// The PaymentMethodPickerViewController displays a list from which a user can pick a payment method to use to complete the payment.
+internal class PaymentMethodPickerViewController: UITableViewController {
- weak var delegate: PaymentPickerViewControllerDelegate?
+ /// The delegate of the payment method picker view controller.
+ internal private(set) weak var delegate: PaymentMethodPickerViewControllerDelegate?
- init(delegate: PaymentPickerViewControllerDelegate) {
+ /// The appearance configuration used to customize the payment method picker's appearance.
+ private let appearanceConfiguration: AppearanceConfiguration
+
+ /// Initializes the payment method picker view controller.
+ ///
+ /// - Parameters:
+ /// - delegate: The delegate to inform when a payment method has been selected.
+ /// - appearanceConfiguration: The appearance configuration to use for customizing the payment method picker's appearance.
+ internal init(delegate: PaymentMethodPickerViewControllerDelegate, appearanceConfiguration: AppearanceConfiguration = .default) {
self.delegate = delegate
+ self.appearanceConfiguration = appearanceConfiguration.copied
super.init(style: .grouped)
+
+ navigationItem.title = ADYLocalizedString("paymentMethods.title")
+ navigationItem.leftBarButtonItem = appearanceConfiguration.cancelButtonItem(target: self, selector: #selector(didSelect(cancelButtonItem:)))
}
- required init?(coder aDecoder: NSCoder) {
+ /// :nodoc:
+ internal required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
- override func viewDidLoad() {
- super.viewDidLoad()
- title = "Payment Methods"
- loading = true
-
- applyNavigationBarStyle()
- setupNavigationItem()
- setupTableView()
- }
+ // MARK: View
- private func applyNavigationBarStyle() {
- guard let navigationBar = self.navigationController?.navigationBar else {
- return
- }
-
- navigationBar.titleTextAttributes = [
- NSFontAttributeName: UIFont.systemFont(ofSize: 18),
- NSForegroundColorAttributeName: UIColor.checkoutDark()
- ]
+ /// :nodoc:
+ internal override func viewDidLoad() {
+ super.viewDidLoad()
- navigationBar.tintColor = UIColor.checkoutDark()
- navigationBar.backgroundColor = UIColor.white
- navigationBar.isTranslucent = false
- }
-
- private func setupNavigationItem() {
- navigationItem.leftBarButtonItem = UIBarButtonItem(
- image: UIImage.bundleImage("close"),
- style: .plain,
- target: self,
- action: #selector(didSelect(cancelButtonItem:))
- )
+ showsActivityIndicatorView = true
- navigationItem.backBarButtonItem = UIBarButtonItem(
- title: "",
- style: .plain,
- target: nil,
- action: nil)
- }
-
- private func setupTableView() {
- tableView.backgroundColor = UIColor.checkoutBackground()
- tableView.cellLayoutMarginsFollowReadableWidth = false
+ tableView.backgroundColor = UIColor.checkoutBackground
tableView.separatorInset = UIEdgeInsets.zero
- tableView.layoutMargins = UIEdgeInsets.zero
tableView.sectionHeaderHeight = 30
tableView.allowsMultipleSelectionDuringEditing = false
tableView.register(PaymentMethodTableViewCell.classForCoder(), forCellReuseIdentifier: "cell")
tableView.register(CheckoutHeaderView.classForCoder(), forHeaderFooterViewReuseIdentifier: "header")
- tableView.reloadData()
}
- override var preferredStatusBarStyle: UIStatusBarStyle {
- return .default
+ @objc private func didSelect(cancelButtonItem: Any) {
+ delegate?.paymentMethodPickerViewControllerDidCancel(self)
}
- func reset() {
- selectedCell?.stopLoadingAnimation()
- selectedIndexPath = nil
-
- view.isUserInteractionEnabled = true
- }
+ // MARK: Payment Methods
- func didSelect(cancelButtonItem: Any) {
- delegate?.paymentPickerViewControllerDidCancel(self)
- }
+ fileprivate var preferredMethods = [PaymentMethod]()
+ fileprivate var availableMethods = [PaymentMethod]()
- func displayMethods(preferred: [PaymentMethod]?, available: [PaymentMethod]) {
+ /// Displays the given payment methods in the list.
+ ///
+ /// - Parameters:
+ /// - preferred: The preferred payment methods, which will be displayed at the top of the list.
+ /// - available: All other payment methods.
+ internal func displayMethods(preferred: [PaymentMethod]?, available: [PaymentMethod]) {
preferredMethods = preferred ?? [PaymentMethod]()
availableMethods = available
- loading = false
+ showsActivityIndicatorView = false
+
+ reset()
tableView.reloadData()
}
/// Displays an activity indicator next to the selected payment method, and disable user interaction.
/// To hide the activity indicator and reenable user interaction, call reset().
- func displayPaymentMethodActivityIndicator() {
+ internal func displayPaymentMethodActivityIndicator() {
selectedCell?.startLoadingAnimation()
view.isUserInteractionEnabled = false
}
+ /// Resets the payment method picker's cell selection and loading state.
+ internal func reset() {
+ selectedCell?.stopLoadingAnimation()
+ selectedIndexPath = nil
+
+ view.isUserInteractionEnabled = true
+ }
+
// MARK: Cell Selection
fileprivate var selectedIndexPath: IndexPath?
@@ -119,7 +105,7 @@ class PaymentPickerViewController: LoadingTableViewController {
}
}
-extension PaymentPickerViewController {
+extension PaymentMethodPickerViewController {
private func isPreferredMethodsSection(_ section: Int) -> Bool {
return preferredMethods.count > 0 && section == 0
}
@@ -129,29 +115,37 @@ extension PaymentPickerViewController {
}
private func titleFor(section: Int) -> String {
- let title = isPreferredMethodsSection(section) ? "Your payment methods" : "Select other method"
- return NSLocalizedString(title, comment: "")
+ if isPreferredMethodsSection(section) {
+ return ADYLocalizedString("paymentMethods.storedMethods.title")
+ } else {
+ return ADYLocalizedString("paymentMethods.otherMethods.title")
+ }
}
- override func numberOfSections(in tableView: UITableView) -> Int {
+ /// :nodoc:
+ public override func numberOfSections(in tableView: UITableView) -> Int {
var count = preferredMethods.isEmpty ? 0 : 1
count += availableMethods.isEmpty ? 0 : 1
return count
}
- override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return tableView.numberOfSections > 1 ? 50 : 30
}
- override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return section == tableView.numberOfSections - 1 ? 30 : 1
}
- override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return titleFor(section: section)
}
- override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") as? CheckoutHeaderView
if preferredMethods.count > 0 {
@@ -161,11 +155,13 @@ extension PaymentPickerViewController {
return headerView
}
- override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 56
}
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch (section, tableView.numberOfSections) {
case (0, 2):
return preferredMethods.count
@@ -176,7 +172,8 @@ extension PaymentPickerViewController {
}
}
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let reusableCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if let cell = reusableCell as? PaymentMethodTableViewCell {
@@ -186,15 +183,17 @@ extension PaymentPickerViewController {
return reusableCell
}
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
selectedIndexPath = indexPath
- delegate?.paymentPickerViewController(self, didSelectPaymentMethod: paymentMethod(at: indexPath))
+ delegate?.paymentMethodPickerViewController(self, didSelectPaymentMethod: paymentMethod(at: indexPath))
}
- override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Allow editing in the `Preferred` section only.
if tableView.numberOfSections == 2 && indexPath.section == 0 {
return true
@@ -203,7 +202,8 @@ extension PaymentPickerViewController {
return false
}
- override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
+ /// :nodoc:
+ public override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Deletion is allowed only for preferred methods (section == 0).
if indexPath.section != 0 {
@@ -217,7 +217,7 @@ extension PaymentPickerViewController {
// Request to delete selected payment method.
let method = preferredMethods[methodIndex]
- delegate?.paymentPickerViewController(self, didSelectDeletePaymentMethod: method)
+ delegate?.paymentMethodPickerViewController(self, didSelectDeletePaymentMethod: method)
preferredMethods.remove(at: methodIndex)
diff --git a/Adyen/UI/PaymentMethodPickerViewControllerDelegate.swift b/Adyen/UI/PaymentMethodPickerViewControllerDelegate.swift
new file mode 100644
index 0000000000..7ff37cf61a
--- /dev/null
+++ b/Adyen/UI/PaymentMethodPickerViewControllerDelegate.swift
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+/// Instances conforming to the PaymentMethodPickerViewControllerDelegate can be informed of the selection or deletion of displayed payment methods.
+/// All delegate methods are invoked on the main thread.
+internal protocol PaymentMethodPickerViewControllerDelegate: class {
+
+ /// Called when a payment method has been selected.
+ func paymentMethodPickerViewController(_ paymentMethodPickerViewController: PaymentMethodPickerViewController, didSelectPaymentMethod paymentMethod: PaymentMethod)
+
+ /// Called when a payment method has been picked to delete.
+ func paymentMethodPickerViewController(_ paymentMethodPickerViewController: PaymentMethodPickerViewController, didSelectDeletePaymentMethod paymentMethod: PaymentMethod)
+
+ /// Called when the payment method selection was cancelled by the user.
+ func paymentMethodPickerViewControllerDidCancel(_ paymentMethodPickerViewController: PaymentMethodPickerViewController)
+}
diff --git a/Adyen/UI/PaymentPickerViewControllerDelegate.swift b/Adyen/UI/PaymentPickerViewControllerDelegate.swift
deleted file mode 100644
index 548522109b..0000000000
--- a/Adyen/UI/PaymentPickerViewControllerDelegate.swift
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Copyright (c) 2017 Adyen B.V.
-//
-// This file is open source and available under the MIT license. See the LICENSE file for more info.
-//
-
-import Foundation
-
-internal protocol PaymentPickerViewControllerDelegate: class {
-
- /// Called when a payment method has been selected.
- func paymentPickerViewController(_ paymentPickerViewController: PaymentPickerViewController, didSelectPaymentMethod paymentMethod: PaymentMethod)
-
- /// Called when a payment method has been picked to delete.
- func paymentPickerViewController(_ paymentPickerViewController: PaymentPickerViewController, didSelectDeletePaymentMethod paymentMethod: PaymentMethod)
-
- /// Called when the payment method selection was cancelled by the user.
- func paymentPickerViewControllerDidCancel(_ paymentPickerViewController: PaymentPickerViewController)
-}
diff --git a/Adyen/UI/UITableViewControllerExtensions.swift b/Adyen/UI/UITableViewControllerExtensions.swift
new file mode 100644
index 0000000000..74ba5134b4
--- /dev/null
+++ b/Adyen/UI/UITableViewControllerExtensions.swift
@@ -0,0 +1,59 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+internal extension UITableViewController {
+
+ /// Boolean value indicating whether an activity indicator should be shown.
+ internal var showsActivityIndicatorView: Bool {
+ get {
+ return activityIndicatorView.superview != nil
+ }
+
+ set {
+ if showsActivityIndicatorView {
+ view.addSubview(activityIndicatorView)
+
+ configureActivityIndicatorViewConstraints()
+
+ activityIndicatorView.startAnimating()
+ } else {
+ activityIndicatorView.removeFromSuperview()
+ activityIndicatorView.stopAnimating()
+ }
+ }
+ }
+
+ private var activityIndicatorView: UIActivityIndicatorView {
+ if let activityIndicatorView = objc_getAssociatedObject(self, &AssociatedObjectKeys.activityIndicatorView) as? UIActivityIndicatorView {
+ return activityIndicatorView
+ }
+
+ let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
+ activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
+ objc_setAssociatedObject(self, &AssociatedObjectKeys.activityIndicatorView, activityIndicatorView, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+
+ return activityIndicatorView
+ }
+
+ private func configureActivityIndicatorViewConstraints() {
+ guard activityIndicatorView.constraints.isEmpty else {
+ return
+ }
+
+ let constraints = [
+ activityIndicatorView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
+ activityIndicatorView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
+ ]
+ NSLayoutConstraint.activate(constraints)
+ }
+
+ private struct AssociatedObjectKeys {
+ static var activityIndicatorView = "checkout_activityIndicatorView"
+ }
+
+}
diff --git a/UnitTests/Cards/CardValidatorTests.swift b/AdyenTests/Cards/CardValidatorTests.swift
similarity index 78%
rename from UnitTests/Cards/CardValidatorTests.swift
rename to AdyenTests/Cards/CardValidatorTests.swift
index 05a41e1054..e176bf8510 100644
--- a/UnitTests/Cards/CardValidatorTests.swift
+++ b/AdyenTests/Cards/CardValidatorTests.swift
@@ -10,74 +10,74 @@ import XCTest
class CardValidatorTests: XCTestCase {
func testValidateWithMasterCardAgainstAllCards() {
- expect(cards: CardNumbers.masterCard, beEqualTo: .mc, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.masterCard, beEqualTo: .masterCard, acceptedCards: CardType.all)
}
func testValidateWithVisaAgainstAllCards() {
- expect(cards: CardNumbers.visa, beEqualTo: .visa, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.visa, beEqualTo: .visa, acceptedCards: CardType.all)
}
func testValidateWithJcbAgainstAllCards() {
- expect(cards: CardNumbers.jcb, beEqualTo: .jcb, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.jcb, beEqualTo: .jcb, acceptedCards: CardType.all)
}
func testValidateWithCartebancaireAgainstAllCards() {
//Credit bancaire will return visa
- expect(cards: CardNumbers.cartebancaire, beEqualTo: .visa, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.cartebancaire, beEqualTo: .visa, acceptedCards: CardType.all)
}
func testValidateWithAmericanExpressAgainstAllCards() {
- expect(cards: CardNumbers.americanExpress, beEqualTo: .amex, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.americanExpress, beEqualTo: .americanExpress, acceptedCards: CardType.all)
}
func testValidateWithDinersAgainstAllCards() {
- expect(cards: CardNumbers.diners, beEqualTo: .diners, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.diners, beEqualTo: .diners, acceptedCards: CardType.all)
}
func testValidateWithDiscoverAgainstAllCards() {
- expect(cards: CardNumbers.discover, beEqualTo: .discover, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.discover, beEqualTo: .discover, acceptedCards: CardType.all)
}
func testValidateWithBancontactAgainstAllCards() {
- expect(cards: CardNumbers.bancontact, beEqualTo: .bcmc, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.bancontact, beEqualTo: .bcmc, acceptedCards: CardType.all)
}
func testValidateWithHipercardAgainstAllCards() {
- expect(cards: CardNumbers.hipercard, beEqualTo: .hipercard, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.hipercard, beEqualTo: .hipercard, acceptedCards: CardType.all)
}
func testValidateWithEloAgainstAllCards() {
- expect(cards: CardNumbers.elo, beEqualTo: .elo, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.elo, beEqualTo: .elo, acceptedCards: CardType.all)
}
func testValidateWithDankortAgainstAllCards() {
- expect(cards: CardNumbers.dankort, beEqualTo: .dankort, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.dankort, beEqualTo: .dankort, acceptedCards: CardType.all)
}
func testValidateWithUnionPayAgainstAllCards() {
- expect(cards: CardNumbers.unionPay, beEqualTo: .unionPay, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.unionPay, beEqualTo: .unionPay, acceptedCards: CardType.all)
}
func testValidateWithUatpAgainstAllCards() {
- expect(cards: CardNumbers.uatp, beEqualTo: .uatp, acceptedCards: CardType.allCards)
+ expect(cards: CardNumbers.uatp, beEqualTo: .uatp, acceptedCards: CardType.all)
}
func testValidateWithRestrictedAcceptedCards() {
let acceptedCards = [CardType.visa, CardType.diners]
- let (visaType, _, _) = CardValidator.validate(card: CardNumbers.visa.first!, acceptedCards: acceptedCards)
- let (dinersType, _, _) = CardValidator.validate(card: CardNumbers.diners.first!, acceptedCards: acceptedCards)
- let (mcType, _, _) = CardValidator.validate(card: CardNumbers.americanExpress.first!, acceptedCards: acceptedCards)
- let (amexType, _, _) = CardValidator.validate(card: CardNumbers.masterCard.first!, acceptedCards: acceptedCards)
+ let (_, visaType, _) = CardValidator.validate(cardNumber: CardNumbers.visa.first!, acceptedCardTypes: acceptedCards)
+ let (_, dinersType, _) = CardValidator.validate(cardNumber: CardNumbers.diners.first!, acceptedCardTypes: acceptedCards)
+ let (_, mcType, _) = CardValidator.validate(cardNumber: CardNumbers.americanExpress.first!, acceptedCardTypes: acceptedCards)
+ let (_, amexType, _) = CardValidator.validate(cardNumber: CardNumbers.masterCard.first!, acceptedCardTypes: acceptedCards)
XCTAssertEqual(visaType, .visa)
XCTAssertEqual(dinersType, .diners)
- XCTAssertEqual(mcType, .unknown)
- XCTAssertEqual(amexType, .unknown)
+ XCTAssertNil(mcType)
+ XCTAssertNil(amexType)
}
func testValidateWithPartialCard() {
- let (type, _, valid) = CardValidator.validate(card: "4111 1", acceptedCards: CardType.allCards)
+ let (valid, type, _) = CardValidator.validate(cardNumber: "4111 1", acceptedCardTypes: CardType.all)
XCTAssertEqual(type, .visa)
XCTAssertFalse(valid)
@@ -85,7 +85,7 @@ class CardValidatorTests: XCTestCase {
func expect(cards: [String], beEqualTo expectedType: CardType, acceptedCards: [CardType]) {
for card in cards {
- let (type, _, _) = CardValidator.validate(card: card, acceptedCards: acceptedCards)
+ let (_, type, _) = CardValidator.validate(cardNumber: card, acceptedCardTypes: acceptedCards)
XCTAssertEqual(type, expectedType)
}
diff --git a/UnitTests/Core/ArrayExtensionTests.swift b/AdyenTests/Core/ArrayExtensionTests.swift
similarity index 100%
rename from UnitTests/Core/ArrayExtensionTests.swift
rename to AdyenTests/Core/ArrayExtensionTests.swift
diff --git a/UnitTests/Core/BoolExtensionsTests.swift b/AdyenTests/Core/BoolExtensionsTests.swift
similarity index 100%
rename from UnitTests/Core/BoolExtensionsTests.swift
rename to AdyenTests/Core/BoolExtensionsTests.swift
diff --git a/UnitTests/Core/CurrencyTests.swift b/AdyenTests/Core/CurrencyTests.swift
similarity index 100%
rename from UnitTests/Core/CurrencyTests.swift
rename to AdyenTests/Core/CurrencyTests.swift
diff --git a/UnitTests/Core/DictionaryExtensionTests.swift b/AdyenTests/Core/DictionaryExtensionTests.swift
similarity index 100%
rename from UnitTests/Core/DictionaryExtensionTests.swift
rename to AdyenTests/Core/DictionaryExtensionTests.swift
diff --git a/UnitTests/Core/InputDetailsTests.swift b/AdyenTests/Core/InputDetailsTests.swift
similarity index 100%
rename from UnitTests/Core/InputDetailsTests.swift
rename to AdyenTests/Core/InputDetailsTests.swift
diff --git a/UnitTests/Core/InputSelectItemTests.swift b/AdyenTests/Core/InputSelectItemTests.swift
similarity index 100%
rename from UnitTests/Core/InputSelectItemTests.swift
rename to AdyenTests/Core/InputSelectItemTests.swift
diff --git a/UnitTests/Core/PaymentDetailsTests.swift b/AdyenTests/Core/PaymentDetailsTests.swift
similarity index 100%
rename from UnitTests/Core/PaymentDetailsTests.swift
rename to AdyenTests/Core/PaymentDetailsTests.swift
diff --git a/UnitTests/Core/PaymentMethodTests.swift b/AdyenTests/Core/PaymentMethodTests.swift
similarity index 55%
rename from UnitTests/Core/PaymentMethodTests.swift
rename to AdyenTests/Core/PaymentMethodTests.swift
index edb6801ff9..6198b5ff5f 100644
--- a/UnitTests/Core/PaymentMethodTests.swift
+++ b/AdyenTests/Core/PaymentMethodTests.swift
@@ -11,38 +11,38 @@ class PaymentMethodTests: XCTestCase {
func testInitWithApplePayInfo() {
let info = JsonReader.read(file: "PaymentMethodApplePay")!
- let method = PaymentMethod(info: info, logoBaseURL: "")
+ let method = PaymentMethod(info: info, logoBaseURL: "", isOneClick: false)
XCTAssertEqual(method?.name, "Apple Pay")
XCTAssertEqual(method?.type, "applepay")
XCTAssertEqual(method?.txVariant, PaymentMethodType.applepay)
- XCTAssertEqual(method?.oneClick, false)
+ XCTAssertEqual(method?.isOneClick, false)
XCTAssertEqual(method?.paymentMethodData, "methodData")
XCTAssertEqual(method?.configuration?["merchantIdentifier"] as? String, "merchant.com.test")
- XCTAssertEqual(method?.inputDetails.count, 1)
- XCTAssertEqual(method?.inputDetails[0].optional, false)
- XCTAssertEqual(method?.inputDetails[0].key, "additionalData.applepay.token")
- XCTAssertEqual(method?.inputDetails[0].type, InputType.applePayToken)
+ XCTAssertEqual(method?.inputDetails?.count, 1)
+ XCTAssertEqual(method?.inputDetails?[0].optional, false)
+ XCTAssertEqual(method?.inputDetails?[0].key, "additionalData.applepay.token")
+ XCTAssertEqual(method?.inputDetails?[0].type, InputType.applePayToken)
}
func testInitWithCardInfo() {
let info = JsonReader.read(file: "PaymentMethodCard")!
- let method = PaymentMethod(info: info, logoBaseURL: "")
+ let method = PaymentMethod(info: info, logoBaseURL: "", isOneClick: false)
XCTAssertEqual(method?.name, "MasterCard")
XCTAssertEqual(method?.type, "mc")
XCTAssertEqual(method?.txVariant, PaymentMethodType.other)
- XCTAssertEqual(method?.oneClick, false)
+ XCTAssertEqual(method?.isOneClick, false)
XCTAssertEqual(method?.paymentMethodData, "methodData")
- XCTAssertEqual(method?.inputDetails.count, 2)
- XCTAssertEqual(method?.inputDetails[0].optional, false)
- XCTAssertEqual(method?.inputDetails[0].key, "additionalData.card.encrypted.json")
- XCTAssertEqual(method?.inputDetails[0].type, InputType.cardToken)
- XCTAssertEqual(method?.inputDetails[1].optional, true)
- XCTAssertEqual(method?.inputDetails[1].key, "storeDetails")
- XCTAssertEqual(method?.inputDetails[1].type, InputType.boolean)
+ XCTAssertEqual(method?.inputDetails?.count, 2)
+ XCTAssertEqual(method?.inputDetails?[0].optional, false)
+ XCTAssertEqual(method?.inputDetails?[0].key, "additionalData.card.encrypted.json")
+ XCTAssertEqual(method?.inputDetails?[0].type, InputType.cardToken)
+ XCTAssertEqual(method?.inputDetails?[1].optional, true)
+ XCTAssertEqual(method?.inputDetails?[1].key, "storeDetails")
+ XCTAssertEqual(method?.inputDetails?[1].type, InputType.boolean)
XCTAssertEqual(method?.group?.name, "Credit Card")
XCTAssertEqual(method?.group?.type, "card")
@@ -53,18 +53,18 @@ class PaymentMethodTests: XCTestCase {
func testInitWithCardCvcInfo() {
let info = JsonReader.read(file: "PaymentMethodCardCvc")!
- let method = PaymentMethod(info: info, logoBaseURL: "")
+ let method = PaymentMethod(info: info, logoBaseURL: "", isOneClick: false)
XCTAssertEqual(method?.name, "•••• 0000")
XCTAssertEqual(method?.type, "maestro")
XCTAssertEqual(method?.txVariant, PaymentMethodType.other)
- XCTAssertEqual(method?.oneClick, false)
+ XCTAssertEqual(method?.isOneClick, false)
XCTAssertEqual(method?.paymentMethodData, "methodData")
- XCTAssertEqual(method?.inputDetails.count, 1)
- XCTAssertEqual(method?.inputDetails[0].optional, false)
- XCTAssertEqual(method?.inputDetails[0].key, "cardDetails.cvc")
- XCTAssertEqual(method?.inputDetails[0].type, InputType.cvc)
+ XCTAssertEqual(method?.inputDetails?.count, 1)
+ XCTAssertEqual(method?.inputDetails?[0].optional, false)
+ XCTAssertEqual(method?.inputDetails?[0].key, "cardDetails.cvc")
+ XCTAssertEqual(method?.inputDetails?[0].type, InputType.cvc)
XCTAssertEqual(method?.group?.name, "Credit Card")
XCTAssertEqual(method?.group?.type, "card")
@@ -75,23 +75,23 @@ class PaymentMethodTests: XCTestCase {
func testInitWithIdealInfo() {
let info = JsonReader.read(file: "PaymentMethodIdeal")!
- let method = PaymentMethod(info: info, logoBaseURL: "")
+ let method = PaymentMethod(info: info, logoBaseURL: "", isOneClick: false)
XCTAssertEqual(method?.name, "iDEAL")
XCTAssertEqual(method?.type, "ideal")
XCTAssertEqual(method?.txVariant, PaymentMethodType.ideal)
- XCTAssertEqual(method?.oneClick, false)
+ XCTAssertEqual(method?.isOneClick, false)
XCTAssertEqual(method?.paymentMethodData, "methodData")
- XCTAssertEqual(method?.inputDetails.count, 1)
- XCTAssertEqual(method?.inputDetails[0].optional, false)
- XCTAssertEqual(method?.inputDetails[0].key, "idealIssuer")
- XCTAssertEqual(method?.inputDetails[0].type, InputType.select)
- XCTAssertEqual(method?.inputDetails[0].items?.count, 2)
- XCTAssertEqual(method?.inputDetails[0].items?[0].identifier, "1")
- XCTAssertEqual(method?.inputDetails[0].items?[0].name, "Issuer1")
- XCTAssertEqual(method?.inputDetails[0].items?[1].identifier, "2")
- XCTAssertEqual(method?.inputDetails[0].items?[1].name, "Issuer2")
+ XCTAssertEqual(method?.inputDetails?.count, 1)
+ XCTAssertEqual(method?.inputDetails?[0].optional, false)
+ XCTAssertEqual(method?.inputDetails?[0].key, "idealIssuer")
+ XCTAssertEqual(method?.inputDetails?[0].type, InputType.select)
+ XCTAssertEqual(method?.inputDetails?[0].items?.count, 2)
+ XCTAssertEqual(method?.inputDetails?[0].items?[0].identifier, "1")
+ XCTAssertEqual(method?.inputDetails?[0].items?[0].name, "Issuer1")
+ XCTAssertEqual(method?.inputDetails?[0].items?[1].identifier, "2")
+ XCTAssertEqual(method?.inputDetails?[0].items?[1].name, "Issuer2")
XCTAssertNil(method?.group)
XCTAssertNil(method?.configuration)
@@ -99,14 +99,14 @@ class PaymentMethodTests: XCTestCase {
func testInitWithKlarnaInfo() {
let info = JsonReader.read(file: "PaymentMethodKlarna")!
- let method = PaymentMethod(info: info, logoBaseURL: "")
+ let method = PaymentMethod(info: info, logoBaseURL: "", isOneClick: false)
XCTAssertEqual(method?.name, "Klarna Factuur")
XCTAssertEqual(method?.type, "klarna")
XCTAssertEqual(method?.txVariant, PaymentMethodType.other)
- XCTAssertEqual(method?.oneClick, false)
+ XCTAssertEqual(method?.isOneClick, false)
XCTAssertEqual(method?.paymentMethodData, "methodData")
- XCTAssertEqual(method?.inputDetails.count, 0)
+ XCTAssertNil(method?.inputDetails)
XCTAssertNil(method?.group)
XCTAssertNil(method?.configuration)
@@ -114,14 +114,14 @@ class PaymentMethodTests: XCTestCase {
func testInitWithPaypalInfo() {
let info = JsonReader.read(file: "PaymentMethodPaypal")!
- let method = PaymentMethod(info: info, logoBaseURL: "")
+ let method = PaymentMethod(info: info, logoBaseURL: "", isOneClick: false)
XCTAssertEqual(method?.name, "PayPal")
XCTAssertEqual(method?.type, "paypal")
XCTAssertEqual(method?.txVariant, PaymentMethodType.other)
- XCTAssertEqual(method?.oneClick, false)
+ XCTAssertEqual(method?.isOneClick, false)
XCTAssertEqual(method?.paymentMethodData, "methodData")
- XCTAssertEqual(method?.inputDetails.count, 0)
+ XCTAssertNil(method?.inputDetails)
XCTAssertNil(method?.group)
XCTAssertNil(method?.configuration)
@@ -129,14 +129,14 @@ class PaymentMethodTests: XCTestCase {
func testInitWithRecurringPaypalInfo() {
let info = JsonReader.read(file: "PaymentMethodPaypalRecurring")!
- let method = PaymentMethod(info: info, logoBaseURL: "")
+ let method = PaymentMethod(info: info, logoBaseURL: "", isOneClick: false)
XCTAssertEqual(method?.name, "email@email.com")
XCTAssertEqual(method?.type, "paypal")
XCTAssertEqual(method?.txVariant, PaymentMethodType.other)
- XCTAssertEqual(method?.oneClick, false)
+ XCTAssertEqual(method?.isOneClick, false)
XCTAssertEqual(method?.paymentMethodData, "methodData")
- XCTAssertEqual(method?.inputDetails.count, 0)
+ XCTAssertNil(method?.inputDetails)
XCTAssertNil(method?.group)
XCTAssertNil(method?.configuration)
@@ -144,21 +144,21 @@ class PaymentMethodTests: XCTestCase {
func testInitWithSepaInfo() {
let info = JsonReader.read(file: "PaymentMethodSepa")!
- let method = PaymentMethod(info: info, logoBaseURL: "")
+ let method = PaymentMethod(info: info, logoBaseURL: "", isOneClick: false)
XCTAssertEqual(method?.name, "SEPA Direct Debit")
XCTAssertEqual(method?.type, "sepadirectdebit")
XCTAssertEqual(method?.txVariant, PaymentMethodType.sepadirectdebit)
- XCTAssertEqual(method?.oneClick, false)
+ XCTAssertEqual(method?.isOneClick, false)
XCTAssertEqual(method?.paymentMethodData, "methodData")
- XCTAssertEqual(method?.inputDetails.count, 2)
- XCTAssertEqual(method?.inputDetails[0].optional, false)
- XCTAssertEqual(method?.inputDetails[0].key, "sepa.ownerName")
- XCTAssertEqual(method?.inputDetails[0].type, InputType.text)
- XCTAssertEqual(method?.inputDetails[1].optional, false)
- XCTAssertEqual(method?.inputDetails[1].key, "sepa.ibanNumber")
- XCTAssertEqual(method?.inputDetails[1].type, InputType.text)
+ XCTAssertEqual(method?.inputDetails?.count, 2)
+ XCTAssertEqual(method?.inputDetails?[0].optional, false)
+ XCTAssertEqual(method?.inputDetails?[0].key, "sepa.ownerName")
+ XCTAssertEqual(method?.inputDetails?[0].type, InputType.text)
+ XCTAssertEqual(method?.inputDetails?[1].optional, false)
+ XCTAssertEqual(method?.inputDetails?[1].key, "sepa.ibanNumber")
+ XCTAssertEqual(method?.inputDetails?[1].type, InputType.text)
XCTAssertNil(method?.group)
XCTAssertNil(method?.configuration)
diff --git a/AdyenTests/Core/PaymentStatusTests.swift b/AdyenTests/Core/PaymentStatusTests.swift
new file mode 100644
index 0000000000..bd5b7be102
--- /dev/null
+++ b/AdyenTests/Core/PaymentStatusTests.swift
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import XCTest
+@testable import Adyen
+
+class PaymentStatusTests: XCTestCase {
+
+ func testInitialization() {
+ XCTAssertEqual(PaymentStatus(rawValue: "received"), .received)
+ XCTAssertEqual(PaymentStatus(rawValue: "authorised"), .authorised)
+ XCTAssertEqual(PaymentStatus(rawValue: "error"), .error)
+ XCTAssertEqual(PaymentStatus(rawValue: "refused"), .refused)
+ XCTAssertEqual(PaymentStatus(rawValue: "cancelled"), .cancelled)
+ }
+
+}
diff --git a/UnitTests/Core/StringExtensionsTests.swift b/AdyenTests/Core/StringExtensionsTests.swift
similarity index 88%
rename from UnitTests/Core/StringExtensionsTests.swift
rename to AdyenTests/Core/StringExtensionsTests.swift
index bdcb0611e3..b36042a4b8 100644
--- a/UnitTests/Core/StringExtensionsTests.swift
+++ b/AdyenTests/Core/StringExtensionsTests.swift
@@ -29,7 +29,7 @@ class StringExtensionsTests: XCTestCase {
func testSubscriptWithInvalidPosition() {
let string = "abcdef"
- XCTAssertEqual(string[ -1], "")
+ XCTAssertEqual(string[-1], "")
XCTAssertEqual(string[6], "")
}
@@ -44,8 +44,8 @@ class StringExtensionsTests: XCTestCase {
func testSubscriptWithInvalidRange() {
let string = "abcdef"
- XCTAssertEqual(string[ -2..<0], "")
- XCTAssertEqual(string[ -2..<2], "ab")
+ XCTAssertEqual(string[-2..<0], "")
+ XCTAssertEqual(string[-2..<2], "ab")
XCTAssertEqual(string[3..<7], "def")
}
@@ -60,8 +60,8 @@ class StringExtensionsTests: XCTestCase {
func testSubscriptWithInvalidClosedRange() {
let string = "abcdef"
- XCTAssertEqual(string[ -2...(-1)], "")
- XCTAssertEqual(string[ -2...1], "ab")
+ XCTAssertEqual(string[-2...(-1)], "")
+ XCTAssertEqual(string[-2...1], "ab")
XCTAssertEqual(string[3...7], "def")
}
diff --git a/UnitTests/Core/URLExtensionsTests.swift b/AdyenTests/Core/URLExtensionsTests.swift
similarity index 100%
rename from UnitTests/Core/URLExtensionsTests.swift
rename to AdyenTests/Core/URLExtensionsTests.swift
diff --git a/UnitTests/JsonReader.swift b/AdyenTests/Helpers/JsonReader.swift
similarity index 100%
rename from UnitTests/JsonReader.swift
rename to AdyenTests/Helpers/JsonReader.swift
diff --git a/UnitTests/Info.plist b/AdyenTests/Info.plist
similarity index 100%
rename from UnitTests/Info.plist
rename to AdyenTests/Info.plist
diff --git a/AdyenTests/Plugins/SEPADirectDebit/IBANValidatorTests.swift b/AdyenTests/Plugins/SEPADirectDebit/IBANValidatorTests.swift
new file mode 100644
index 0000000000..b7b20385e7
--- /dev/null
+++ b/AdyenTests/Plugins/SEPADirectDebit/IBANValidatorTests.swift
@@ -0,0 +1,129 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import XCTest
+@testable import Adyen
+
+class IBANValidatorTests: XCTestCase {
+
+ func testValidation() {
+ for iban in validIBANs {
+ XCTAssertTrue(IBANValidator.isValid(iban), "\(iban) is not valid.")
+ }
+ }
+
+ func testCanonicalization() {
+ XCTAssertEqual(IBANValidator.canonicalize("nl36test 0236169114"), "NL36TEST0236169114")
+ XCTAssertEqual(IBANValidator.canonicalize("NL 82 test 0836169255"), "NL82TEST0836169255")
+ XCTAssertEqual(IBANValidator.canonicalize(" DE94 8888 8888 9876 5432 10"), "DE94888888889876543210")
+ XCTAssertEqual(IBANValidator.canonicalize("it60 x054 2811 1010 0000 0123 456"), "IT60X0542811101000000123456")
+ XCTAssertEqual(IBANValidator.canonicalize("%FR1420041010050500013M02606%"), "FR1420041010050500013M02606")
+ XCTAssertEqual(IBANValidator.canonicalize("ES9121000418450200051332"), "ES9121000418450200051332")
+ XCTAssertEqual(IBANValidator.canonicalize("D K 8 6 1 2 3 4 1 2 3 4 5 6 7 8 9 0"), "DK8612341234567890")
+ }
+
+ func testExtractingCountryCode() {
+ XCTAssertEqual(IBANValidator.countryCode(in: "NL13TEST0123456789"), "NL")
+ XCTAssertEqual(IBANValidator.countryCode(in: "DE87123456781234567890"), "DE")
+ XCTAssertEqual(IBANValidator.countryCode(in: "GB"), "GB")
+ XCTAssertEqual(IBANValidator.countryCode(in: "MK87"), "MK")
+
+ XCTAssertEqual(IBANValidator.countryCode(in: "6789NL13TEST012345"), nil)
+ XCTAssertEqual(IBANValidator.countryCode(in: "678913012345"), nil)
+ XCTAssertEqual(IBANValidator.countryCode(in: "6NL78913012345"), nil)
+ XCTAssertEqual(IBANValidator.countryCode(in: "D"), nil)
+ }
+
+ func testRearranging() {
+ XCTAssertEqual(IBANValidator.rearrange("NL13TEST0123456789"), "TEST0123456789NL13")
+ XCTAssertEqual(IBANValidator.rearrange("DE87123456781234567890"), "123456781234567890DE87")
+ XCTAssertEqual(IBANValidator.rearrange("MK63"), "MK63")
+ XCTAssertEqual(IBANValidator.rearrange("NL05TEST0236169114"), "TEST0236169114NL05")
+ XCTAssertEqual(IBANValidator.rearrange("IT60X0542811101000000123456"), "X0542811101000000123456IT60")
+ }
+
+ func testNumerification() {
+ XCTAssertEqual(IBANValidator.numerify("WEST12345698765432GB82"), "3214282912345698765432161182")
+ XCTAssertEqual(IBANValidator.numerify("TEST0236169114NL05"), "291428290236169114232105")
+ XCTAssertEqual(IBANValidator.numerify("123456781234567890DE87"), "123456781234567890131487")
+ }
+
+ func testMod97() {
+ XCTAssertEqual(IBANValidator.mod97("3214282912345698765432161182"), 1)
+ }
+
+ // MARK: Constants
+
+ private let validIBANs = [
+ "AD1200012030200359100100",
+ "AE070331234567890123456",
+ "AL47212110090000000235698741",
+ "AT611904300234573201",
+ "AZ21NABZ00000000137010001944",
+ "BA391290079401028494",
+ "BE68539007547034",
+ "BG80BNBG96611020345678",
+ "BH67BMAG00001299123456",
+ "BR7724891749412660603618210F3",
+ "CH9300762011623852957",
+ "CY17002001280000001200527600",
+ "CZ6508000000192000145399",
+ "DE89370400440532013000",
+ "DK5000400440116243",
+ "DO28BAGR00000001212453611324",
+ "EE382200221020145685",
+ "ES9121000418450200051332",
+ "FI2112345600000785",
+ "FO7630004440960235",
+ "FR1420041010050500013M02606",
+ "GB29NWBK60161331926819",
+ "GE29NB0000000101904917",
+ "GI75NWBK000000007099453",
+ "GL4330003330229543",
+ "GR1601101250000000012300695",
+ "GT82TRAJ01020000001210029690",
+ "HR1210010051863000160",
+ "HU42117730161111101800000000",
+ "IE29AIBK93115212345678",
+ "IL620108000000099999999",
+ "IS140159260076545510730339",
+ "IT60X0542811101000000123456",
+ "KW81CBKU0000000000001234560101",
+ "KZ86125KZT5004100100",
+ "LB62099900000001001901229114",
+ "LI21088100002324013AA",
+ "LT121000011101001000",
+ "LU280019400644750000",
+ "LV80BANK0000435195001",
+ "MC1112739000700011111000h79",
+ "MD24AG000225100013104168",
+ "ME25505000012345678951",
+ "MK07300000000042425",
+ "MR1300020001010000123456753",
+ "MT84MALT011000012345MTLCAST001S",
+ "MU17BOMM0101101030300200000MUR",
+ "NL91ABNA0417164300",
+ "NO9386011117947",
+ "PK36SCBL0000001123456702",
+ "PL27114020040000300201355387",
+ "PS92PALS000000000400123456702",
+ "PT50000201231234567890154",
+ "QA58DOHB00001234567890ABCDEFG",
+ "RO49AAAA1B31007593840000",
+ "RS35260005601001611379",
+ "SA0380000000608010167519",
+ "SE3550000000054910000003",
+ "SI56191000000123438",
+ "SK3112000000198742637541",
+ "SM86U0322509800000000270100",
+ "TL380080012345678910157",
+ "TN5914207207100707129648",
+ "TR330006100519786457841326",
+ "VG96VPVG0000012345678901",
+ "XK051212012345678906"
+ ]
+
+}
diff --git a/UnitTests/Resources/Json/PaymentMethodApplePay.json b/AdyenTests/Resources/Json/PaymentMethodApplePay.json
similarity index 100%
rename from UnitTests/Resources/Json/PaymentMethodApplePay.json
rename to AdyenTests/Resources/Json/PaymentMethodApplePay.json
diff --git a/UnitTests/Resources/Json/PaymentMethodCard.json b/AdyenTests/Resources/Json/PaymentMethodCard.json
similarity index 100%
rename from UnitTests/Resources/Json/PaymentMethodCard.json
rename to AdyenTests/Resources/Json/PaymentMethodCard.json
diff --git a/UnitTests/Resources/Json/PaymentMethodCardCvc.json b/AdyenTests/Resources/Json/PaymentMethodCardCvc.json
similarity index 100%
rename from UnitTests/Resources/Json/PaymentMethodCardCvc.json
rename to AdyenTests/Resources/Json/PaymentMethodCardCvc.json
diff --git a/UnitTests/Resources/Json/PaymentMethodIdeal.json b/AdyenTests/Resources/Json/PaymentMethodIdeal.json
similarity index 100%
rename from UnitTests/Resources/Json/PaymentMethodIdeal.json
rename to AdyenTests/Resources/Json/PaymentMethodIdeal.json
diff --git a/UnitTests/Resources/Json/PaymentMethodKlarna.json b/AdyenTests/Resources/Json/PaymentMethodKlarna.json
similarity index 100%
rename from UnitTests/Resources/Json/PaymentMethodKlarna.json
rename to AdyenTests/Resources/Json/PaymentMethodKlarna.json
diff --git a/UnitTests/Resources/Json/PaymentMethodPaypal.json b/AdyenTests/Resources/Json/PaymentMethodPaypal.json
similarity index 100%
rename from UnitTests/Resources/Json/PaymentMethodPaypal.json
rename to AdyenTests/Resources/Json/PaymentMethodPaypal.json
diff --git a/UnitTests/Resources/Json/PaymentMethodPaypalRecurring.json b/AdyenTests/Resources/Json/PaymentMethodPaypalRecurring.json
similarity index 100%
rename from UnitTests/Resources/Json/PaymentMethodPaypalRecurring.json
rename to AdyenTests/Resources/Json/PaymentMethodPaypalRecurring.json
diff --git a/UnitTests/Resources/Json/PaymentMethodSepa.json b/AdyenTests/Resources/Json/PaymentMethodSepa.json
similarity index 100%
rename from UnitTests/Resources/Json/PaymentMethodSepa.json
rename to AdyenTests/Resources/Json/PaymentMethodSepa.json
diff --git a/AdyenUIHost/AppDelegate.swift b/AdyenUIHost/AppDelegate.swift
new file mode 100644
index 0000000000..61b152e47d
--- /dev/null
+++ b/AdyenUIHost/AppDelegate.swift
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import UIKit
+
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+ func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
+ let navigationController = window?.rootViewController as? UINavigationController
+ let viewController = navigationController?.viewControllers.first as? ViewController
+ viewController?.didReceive(url)
+
+ return true
+ }
+}
diff --git a/Example/2-custom-integration-example/Advanced/Assets.xcassets/AppIcon.appiconset/Contents.json b/AdyenUIHost/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from Example/2-custom-integration-example/Advanced/Assets.xcassets/AppIcon.appiconset/Contents.json
rename to AdyenUIHost/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/AdyenUIHost/Configuration.swift b/AdyenUIHost/Configuration.swift
new file mode 100644
index 0000000000..1f1752b89c
--- /dev/null
+++ b/AdyenUIHost/Configuration.swift
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+// Fill in your app identifier and secret key here.
+struct Configuration {
+ static let appIdentifier = ""
+ static let appSecretKey = ""
+
+ static var isFilledIn: Bool {
+ guard
+ appIdentifier.characters.isEmpty == false,
+ appSecretKey.characters.isEmpty == false
+ else {
+ return false
+ }
+
+ return true
+ }
+}
diff --git a/AdyenUIHost/Info.plist b/AdyenUIHost/Info.plist
new file mode 100644
index 0000000000..f60a40887a
--- /dev/null
+++ b/AdyenUIHost/Info.plist
@@ -0,0 +1,56 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ CFBundleURLTypes
+
+
+ CFBundleURLName
+ com.adyen.AdyenUIHost
+ CFBundleURLSchemes
+
+ ui-host
+
+
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/AdyenUIHost/LaunchScreen.storyboard b/AdyenUIHost/LaunchScreen.storyboard
new file mode 100644
index 0000000000..d35ccf4310
--- /dev/null
+++ b/AdyenUIHost/LaunchScreen.storyboard
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AdyenUIHost/Main.storyboard b/AdyenUIHost/Main.storyboard
new file mode 100644
index 0000000000..2917746a9d
--- /dev/null
+++ b/AdyenUIHost/Main.storyboard
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AdyenUIHost/ViewController.swift b/AdyenUIHost/ViewController.swift
new file mode 100644
index 0000000000..16e4fe8179
--- /dev/null
+++ b/AdyenUIHost/ViewController.swift
@@ -0,0 +1,128 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import UIKit
+import Adyen
+
+class ViewController: UITableViewController {
+
+ // MARK: - UIViewController
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let isConfigured = !(Configuration.appIdentifier.characters.isEmpty || Configuration.appIdentifier.characters.isEmpty)
+ assert(isConfigured, "Fill in an app identifier and secret key in the Configuration.swift file.")
+ }
+
+ // MARK: - UITableViewController
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ if indexPath.section == 1 {
+ presentCheckoutViewController()
+ }
+ }
+
+ // MARK: - Private
+
+ @IBOutlet fileprivate var shopperReferenceField: UITextField!
+
+ private func presentCheckoutViewController() {
+ let checkoutViewController = CheckoutViewController(delegate: self)
+ present(checkoutViewController, animated: true)
+ }
+
+ fileprivate func presentSuccessAlertController() {
+ let alertController = UIAlertController(title: "Payment successful", message: nil, preferredStyle: .alert)
+
+ let dismissAction = UIAlertAction(title: "OK", style: .default, handler: nil)
+ alertController.addAction(dismissAction)
+
+ present(alertController, animated: true, completion: nil)
+ }
+
+ fileprivate func presentFailureAlertController() {
+ let alertController = UIAlertController(title: "Payment failed", message: nil, preferredStyle: .alert)
+
+ let dismissAction = UIAlertAction(title: "OK", style: .default, handler: nil)
+ alertController.addAction(dismissAction)
+
+ present(alertController, animated: true, completion: nil)
+ }
+
+ fileprivate var urlCompletion: URLCompletion?
+
+ internal func didReceive(_ url: URL) {
+ urlCompletion?(url)
+ urlCompletion = nil
+ }
+
+}
+
+extension ViewController: CheckoutViewControllerDelegate {
+
+ func checkoutViewController(_ controller: CheckoutViewController, requiresPaymentDataForToken token: String, completion: @escaping DataCompletion) {
+ let url = URL(string: "https://checkoutshopper-test.adyen.com/checkoutshopper/demo/easy-integration/merchantserver/setup")!
+
+ let paymentDetails: [String: Any] = [
+ "quantity": 17408,
+ "currency": "EUR",
+ "basketId": "iOS & M+M Black dress & accessories",
+ "customerCountry": "NL",
+ "customerId": shopperReferenceField.text!,
+ "platform": "ios",
+ "appUrlScheme": "ui-host://",
+ "sdkToken": token
+ ]
+
+ var request = URLRequest(url: url)
+ request.httpMethod = "POST"
+ request.httpBody = try? JSONSerialization.data(withJSONObject: paymentDetails, options: [])
+ request.allHTTPHeaderFields = [
+ "Content-Type": "application/json",
+ "X-MerchantServer-App-Id": Configuration.appIdentifier,
+ "X-MerchantServer-App-SecretKey": Configuration.appSecretKey
+ ]
+
+ let session = URLSession(configuration: .default)
+ session.dataTask(with: request) { data, response, error in
+ if let data = data {
+ completion(data)
+ }
+ }.resume()
+ }
+
+ func checkoutViewController(_ controller: CheckoutViewController, requiresReturnURL completion: @escaping URLCompletion) {
+ urlCompletion = completion
+ }
+
+ func checkoutViewController(_ controller: CheckoutViewController, didFinishWith result: PaymentRequestResult) {
+ var isSuccess = false
+ var isCancelled = false
+
+ switch result {
+ case let .payment(payment):
+ isSuccess = (payment.status == .received || payment.status == .authorised)
+ case let .error(error):
+ switch error {
+ case .canceled:
+ isCancelled = true
+ default:
+ break
+ }
+ }
+
+ dismiss(animated: true) {
+ if isSuccess {
+ self.presentSuccessAlertController()
+ } else if !isCancelled {
+ self.presentFailureAlertController()
+ }
+ }
+
+ }
+
+}
diff --git a/AdyenUITests/Base/TestCase.swift b/AdyenUITests/Base/TestCase.swift
new file mode 100644
index 0000000000..f15877c4de
--- /dev/null
+++ b/AdyenUITests/Base/TestCase.swift
@@ -0,0 +1,49 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import XCTest
+
+internal class TestCase: XCTestCase {
+
+ internal let app = XCUIApplication()
+
+ override func setUp() {
+ super.setUp()
+
+ continueAfterFailure = false
+
+ app.launch()
+
+ let table = app.tables.first
+
+ let shopperReferenceField = table.textFields["shopper-reference-field"]
+ shopperReferenceField.tap()
+ shopperReferenceField.typeText("uitests@uitests.ui")
+
+ table.buttons["start-button"].tap()
+ }
+
+ internal func dismissSuccessAlert() {
+ let alert = app.alerts["Payment successful"]
+ alert.buttons.first.tap()
+ }
+
+ internal func dismissFailureAlert() {
+ let alert = app.alerts["Payment failed"]
+ alert.buttons.first.tap()
+ }
+
+ internal func waitForElementToAppear(_ element: XCUIElement) {
+ guard element.exists == false else {
+ return
+ }
+
+ let predicate = NSPredicate(format: "exists == true")
+ expectation(for: predicate, evaluatedWith: element, handler: nil)
+ waitForExpectations(timeout: 10.0, handler: nil)
+ }
+
+}
diff --git a/AdyenUITests/Base/XCUIElementQueryExtensions.swift b/AdyenUITests/Base/XCUIElementQueryExtensions.swift
new file mode 100644
index 0000000000..d018bc94ac
--- /dev/null
+++ b/AdyenUITests/Base/XCUIElementQueryExtensions.swift
@@ -0,0 +1,19 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import XCTest
+
+internal extension XCUIElementQuery {
+
+ internal var first: XCUIElement {
+ return element(boundBy: 0)
+ }
+
+ internal var last: XCUIElement {
+ return element(boundBy: count - 1)
+ }
+
+}
diff --git a/AdyenUITests/CardsTests.swift b/AdyenUITests/CardsTests.swift
new file mode 100644
index 0000000000..eba46b9037
--- /dev/null
+++ b/AdyenUITests/CardsTests.swift
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import XCTest
+
+class CardsTests: TestCase {
+
+ func testSuccessfulPayment() {
+ let table = app.tables.first
+ table.buttons["Credit Card"].tap()
+
+ // Find the checkout button and ensure it's disabled.
+ XCTAssertFalse(checkoutButton.isEnabled)
+
+ // Enter the credit card number.
+ numberField.typeText("5555444433331111")
+
+ // The checkout button should be disabled while waiting for the user to complete input.
+ XCTAssertFalse(checkoutButton.isEnabled)
+
+ // Enter the expiration date.
+ expiryField.tap()
+ expiryField.typeText("0818")
+
+ // The checkout button should still be disabled while waiting for the user to complete input.
+ XCTAssertFalse(checkoutButton.isEnabled)
+
+ // Enter the CVC.
+ cvcField.tap()
+ cvcField.typeText("737")
+
+ // After selecting the agree button, the checkout button should be enabled.
+ XCTAssertTrue(checkoutButton.isEnabled)
+
+ // Tap the checkout button.
+ checkoutButton.tap()
+
+ dismissSuccessAlert()
+ }
+
+ func testSuccessfulOneClickPayment() {
+ app.cells.first.tap()
+
+ // Enter a valid CVC and submit.
+ oneClickVerificationAlert.textFields.first.typeText("737")
+ oneClickVerificationAlert.buttons.last.tap()
+
+ dismissSuccessAlert()
+ }
+
+ func testOneClickPaymentWithInvalidCVC() {
+ app.cells.first.tap()
+
+ // Enter an invalid CVC and submit.
+ oneClickVerificationAlert.textFields.first.typeText("123")
+ oneClickVerificationAlert.buttons.last.tap()
+
+ dismissFailureAlert()
+ }
+
+ // MARK: Elements
+
+ private var contentView: XCUIElement {
+ return app.scrollViews.first
+ }
+
+ private var numberField: XCUIElement {
+ return contentView.textFields["number-field"]
+ }
+
+ private var expiryField: XCUIElement {
+ return contentView.textFields["expiry-field"]
+ }
+
+ private var cvcField: XCUIElement {
+ return contentView.textFields["cvc-field"]
+ }
+
+ private var checkoutButton: XCUIElement {
+ return contentView.buttons["checkout-button"]
+ }
+
+ private var oneClickVerificationAlert: XCUIElement {
+ return app.alerts["Verify your card"]
+ }
+
+}
diff --git a/AdyenUITests/IdealTests.swift b/AdyenUITests/IdealTests.swift
new file mode 100644
index 0000000000..d761a28d84
--- /dev/null
+++ b/AdyenUITests/IdealTests.swift
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import XCTest
+
+class IdealTests: TestCase {
+
+ func testSuccessfulPayment() {
+ testPayment(withIssuer: "Test Issuer")
+
+ dismissSuccessAlert()
+ }
+
+ func testCancelledPayment() {
+ testPayment(withIssuer: "Test Issuer Cancelled")
+
+ dismissFailureAlert()
+ }
+
+ func testPendingPayment() {
+ testPayment(withIssuer: "Test Issuer Pending")
+
+ dismissSuccessAlert()
+ }
+
+ func testRefusedPayment() {
+ testPayment(withIssuer: "Test Issuer Refused")
+
+ dismissFailureAlert()
+ }
+
+ private func testPayment(withIssuer issuer: String) {
+ let table = app.tables.first
+ table.buttons["iDEAL"].tap()
+
+ // Select the issuer.
+ table.buttons[issuer].tap()
+
+ // Wait for the continue button to appear in the web view, then select it.
+ let continueButton = app.webViews.buttons["Continue"]
+ waitForElementToAppear(continueButton)
+ continueButton.tap()
+ }
+
+}
diff --git a/AdyenUITests/Info.plist b/AdyenUITests/Info.plist
new file mode 100644
index 0000000000..6c6c23c43a
--- /dev/null
+++ b/AdyenUITests/Info.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+
+
diff --git a/AdyenUITests/SEPADirectDebitTests.swift b/AdyenUITests/SEPADirectDebitTests.swift
new file mode 100644
index 0000000000..01338ad579
--- /dev/null
+++ b/AdyenUITests/SEPADirectDebitTests.swift
@@ -0,0 +1,65 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import XCTest
+
+class SEPADirectDebitTests: TestCase {
+
+ func testSuccessfulPayment() {
+ let table = app.tables.first
+ table.buttons["SEPA Direct Debit"].tap()
+
+ // Find the checkout button and ensure it's disabled.
+ XCTAssertFalse(checkoutButton.isEnabled)
+
+ // Enter the IBAN.
+ ibanField.typeText("nl13test0123456789")
+
+ // The checkout button should be disabled while waiting for the user to complete input.
+ XCTAssertFalse(checkoutButton.isEnabled)
+
+ // Enter the name.
+ nameField.tap()
+ nameField.typeText("A. Klaassen")
+
+ // The checkout button should still be disabled while waiting for the user to complete input.
+ XCTAssertFalse(checkoutButton.isEnabled)
+
+ // Agree to the direct debit.
+ agreeButton.tap()
+
+ // After selecting the agree button, the checkout button should be enabled.
+ XCTAssertTrue(checkoutButton.isEnabled)
+
+ // Tap the checkout button.
+ checkoutButton.tap()
+
+ dismissSuccessAlert()
+ }
+
+ // MARK: Elements
+
+ private var contentView: XCUIElement {
+ return app.scrollViews.first
+ }
+
+ private var ibanField: XCUIElement {
+ return contentView.textFields["iban-field"]
+ }
+
+ private var nameField: XCUIElement {
+ return contentView.textFields["name-field"]
+ }
+
+ private var agreeButton: XCUIElement {
+ return contentView.buttons["agree-button"]
+ }
+
+ private var checkoutButton: XCUIElement {
+ return contentView.buttons["checkout-button"]
+ }
+
+}
diff --git a/Docs/Classes/AppearanceConfiguration.html b/Docs/Classes/AppearanceConfiguration.html
new file mode 100644
index 0000000000..7a13e1d69c
--- /dev/null
+++ b/Docs/Classes/AppearanceConfiguration.html
@@ -0,0 +1,550 @@
+
+
+
+ AppearanceConfiguration Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ AppearanceConfiguration Class Reference
+
+
+
+
+
+
+
+
+
+
+
AppearanceConfiguration
+
+
+
public final class AppearanceConfiguration
+
+
+
+
Provides properties to customize the appearance of the UI components provided by this library.
+Note that AppearanceConfiguration
is only used when the CheckoutViewController
is first initialized. Changes to this object after it has been created are ignored.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Initializes the appearance configuration.
+
+
+
+
Declaration
+
+
Swift
+
public init ()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The preferred status bar style.
+
+
+
+
Declaration
+
+
Swift
+
public var preferredStatusBarStyle = UIStatusBarStyle . default
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The attributes used for the navigation bar’s title.
+
+
+
+
Declaration
+
+
Swift
+
public var navigationBarTitleTextAttributes : [ String : Any ]?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The navigation bar’s tint color.
+
+
+
+
Declaration
+
+
Swift
+
public var navigationBarTintColor : UIColor ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The navigation bar’s background color.
+
+
+
+
Declaration
+
+
Swift
+
public var navigationBarBackgroundColor : UIColor ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A Boolean value indicating whether the navigation bar is translucent.
+
+
+
+
Declaration
+
+
Swift
+
public var isNavigationBarTranslucent = true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The image of the cancel button in the navigation bar, or nil
if a title should be used instead.
+
+
+
+
Declaration
+
+
Swift
+
public var navigationBarCancelButtonImage : UIImage ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The attributes used for the checkout button’s title.
+
+
+
+
Declaration
+
+
Swift
+
public var checkoutButtonTitleTextAttributes : [ String : Any ]?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The insets from the edges of the checkout button to the title.
+
+
+
+
Declaration
+
+
Swift
+
public var checkoutButtonTitleEdgeInsets : UIEdgeInsets ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The corner radius of the checkout button.
+
+
+
+
Declaration
+
+
Swift
+
public var checkoutButtonCornerRadius : CGFloat = 0.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The tint color of most buttons and actionable elements.
+
+
+
+
Declaration
+
+
Swift
+
public var tintColor : UIColor ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The default appearance configuration.
+
+
+
+
Declaration
+
+
Swift
+
public static var ` default ` : AppearanceConfiguration =
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/CardValidator.html b/Docs/Classes/CardValidator.html
new file mode 100644
index 0000000000..f4b5663ab6
--- /dev/null
+++ b/Docs/Classes/CardValidator.html
@@ -0,0 +1,351 @@
+
+
+
+ CardValidator Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ CardValidator Class Reference
+
+
+
+
+
+
+
+
+
+
+
CardValidator
+
+
+
public final class CardValidator
+
+
+
+
The CardValidator class provides static methods to validate and format card numbers and expiry dates, and to detect card types.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Validates and formats the given card number, and detects its card type.
+
+
+
+
Declaration
+
+
Swift
+
public static func validate ( cardNumber : String , acceptedCardTypes : [ CardType ] = CardType . all ) -> ( isValid : Bool , type : CardType ?, formattedNumber : String )
+
+
+
+
+
Parameters
+
+
+
+
+
+ cardNumber
+
+
+
+
+
The card number to validate and format. The card number is sanitized before validating and formatting, to filter out non-numerical characters.
+
+
+
+
+
+
+ acceptedCardTypes
+
+
+
+
+
The card types to check against for detecting the card type.
+
+
+
+
+
+
+
+
Return Value
+
A tuple containing a boolean value indicating whether the card number is valid, the detected card type, and the formatted card number.
+
+
+
+
+
+
+
+
+
+
+
+
Validates and formats the given expiration date.
+
+
+
+
Declaration
+
+
Swift
+
public static func validate ( expiryDate : String , separator : String ? = "/" ) -> ( isValid : Bool , formattedDate : String )
+
+
+
+
+
Parameters
+
+
+
+
+
+ expiryDate
+
+
+
+
+
The expiry date to validate and format. The expiry date is sanitized before validating and formatting, to filter out non-numerical characters.
+
+
+
+
+
+
+ separator
+
+
+
+
+
The optional string to use to separate the month and year in the formatted date, default is /
.
+
+
+
+
+
+
+
+
Return Value
+
A tuple containing a boolean value indicating whether the expiry date is valid, and a formatted expiry date.
+
+
+
+
+
+
+
+
+
+
+
+
Validates and formats the given cvc.
+
+
+
+
Declaration
+
+
Swift
+
public static func validate ( cvc : String ) -> ( isValid : Bool , formattedCvc : String )
+
+
+
+
+
Parameters
+
+
+
+
+
+ cvc
+
+
+
+
+
The cvc value to validate and format. The cvc is sanitized before validating and formatting, to filter out non-numerical characters.
+
+
+
+
+
+
+
+
Return Value
+
A tuple containing a boolean value indicating whether the cvc is valid, and the formatted cvc string.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/CheckoutViewController.html b/Docs/Classes/CheckoutViewController.html
new file mode 100644
index 0000000000..74f58f587f
--- /dev/null
+++ b/Docs/Classes/CheckoutViewController.html
@@ -0,0 +1,255 @@
+
+
+
+ CheckoutViewController Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ CheckoutViewController Class Reference
+
+
+
+
+
+
+
+
+
+
+
CheckoutViewController
+
+
+
public final class CheckoutViewController : UIViewController
+
+
+
+
The starting point for Quick integration . Initialize with CheckoutViewContollerDelegate
and present this view controller in your app to start the payment flow. If you don’t embed the CheckoutViewController
in an existing UINavigationController
, a new one will be created automatically.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The delegate for Quick integration.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Initializes the checkout view controller.
+
+
+
+
+
Parameters
+
+
+
+
+
+ delegate
+
+
+
+
+
The delegate to receive the checkout view controller’s events.
+
+
+
+
+
+
+ appearanceConfiguration
+
+
+
+
+
The configuration to use for customizing the checkout view controller’s appearance.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/IBANTextField.html b/Docs/Classes/IBANTextField.html
new file mode 100644
index 0000000000..de9f490d0b
--- /dev/null
+++ b/Docs/Classes/IBANTextField.html
@@ -0,0 +1,197 @@
+
+
+
+ IBANTextField Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ IBANTextField Class Reference
+
+
+
+
+
+
+
+
+
+
+
IBANTextField
+
+
+
public class IBANTextField : UITextField
+
+
+
+
Provides a text field designed for the entry of an IBAN value. This field formats and validates the IBAN in real time.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The IBAN entered in the text field, or nil
if no valid IBAN has been entered.
+
+
+
+
Declaration
+
+
Swift
+
public var iban : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/IBANValidator.html b/Docs/Classes/IBANValidator.html
new file mode 100644
index 0000000000..29b612f4c9
--- /dev/null
+++ b/Docs/Classes/IBANValidator.html
@@ -0,0 +1,220 @@
+
+
+
+ IBANValidator Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ IBANValidator Class Reference
+
+
+
+
+
+
+
+
+
+
+
IBANValidator
+
+
+
public class IBANValidator
+
+
+
+
Provides a static method to validate an IBAN value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Checks if the given string is a valid IBAN value.
+
+
+
+
Declaration
+
+
Swift
+
public static func isValid ( _ string : String ) -> Bool
+
+
+
+
+
Parameters
+
+
+
+
+
+ string
+
+
+
+
+
+
+
+
+
+
+
Return Value
+
A Boolean value indicating whether the given string is a valid IBAN.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/InputDetail.html b/Docs/Classes/InputDetail.html
new file mode 100644
index 0000000000..7fc362f7c0
--- /dev/null
+++ b/Docs/Classes/InputDetail.html
@@ -0,0 +1,308 @@
+
+
+
+ InputDetail Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ InputDetail Class Reference
+
+
+
+
+
+
+
+
+
+
+
InputDetail
+
+
+
public class InputDetail
+
+
+
+
The payment detail needed for the transaction.
+The detail has a type
(InputType
). If type
is .select
, a list of InputSelectItem
will be available for selection in the items
variable.
+The detail might be optional
.
+The detail value can be set as a string (stringValue
) or a bool value (boolValue
).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Whether the detail is optional.
+
+
+
+
Declaration
+
+
Swift
+
public let optional : Bool
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Detail string value.
+
+
+
+
Declaration
+
+
Swift
+
public var stringValue : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public var boolValue : Bool ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/InputSelectItem.html b/Docs/Classes/InputSelectItem.html
new file mode 100644
index 0000000000..a7e1e2127d
--- /dev/null
+++ b/Docs/Classes/InputSelectItem.html
@@ -0,0 +1,251 @@
+
+
+
+ InputSelectItem Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ InputSelectItem Class Reference
+
+
+
+
+
+
+
+
+
+
+
InputSelectItem
+
+
+
public final class InputSelectItem
+
+
+
+
Represents a selectable item used in InputDetail
with select
type.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Identifier of an item. Should be used to indicate selection of a particular item in InputDetail
object. Assign identifier
to the value
property of the InputDetail
object.
+
+
+
+
Declaration
+
+
Swift
+
public let identifier : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Display name of an item.
+
+
+
+
Declaration
+
+
Swift
+
public let name : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Contains a URL to image representation of an item, when applicable.
+
+
+
+
Declaration
+
+
Swift
+
public let imageURL : URL ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/Payment.html b/Docs/Classes/Payment.html
new file mode 100644
index 0000000000..cc9bb48fee
--- /dev/null
+++ b/Docs/Classes/Payment.html
@@ -0,0 +1,413 @@
+
+
+
+ Payment Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Payment Class Reference
+
+
+
+
+
+
+
+
+
+
+
Payment
+
+
+
public final class Payment
+
+
+
+
Represents a payment that has been completed by the user. The result of the payment can be retrieved via the status
property.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The status of the payment.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The method that was used to complete the payment.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The payload as returned from the server.
+
+
+
+
Declaration
+
+
Swift
+
public let payload : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The amount of the payment, in minor units.
+
+
+
+
Declaration
+
+
Swift
+
public let amount : Int
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The code of the currency for the payment amount.
+
+
+
+
Declaration
+
+
Swift
+
public let currencyCode : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The reference of the merchant.
+
+
+
+
Declaration
+
+
Swift
+
public let merchantReference : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The reference of the shopper.
+
+
+
+
Declaration
+
+
Swift
+
public let shopperReference : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The country code of the shopper.
+
+
+
+
Declaration
+
+
Swift
+
public let shopperCountryCode : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The locale identifier of the shopper.
+
+
+
+
Declaration
+
+
Swift
+
public let shopperLocaleIdentifier : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/PaymentDetails.html b/Docs/Classes/PaymentDetails.html
new file mode 100644
index 0000000000..87f3aaa067
--- /dev/null
+++ b/Docs/Classes/PaymentDetails.html
@@ -0,0 +1,402 @@
+
+
+
+ PaymentDetails Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentDetails Class Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentDetails
+
+
+
public class PaymentDetails
+
+
+
+
Holds the list of InputDetail
needed for the transaction.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Update the detail defined by a given key
with the string value
provided.
+
+
+
+
Declaration
+
+
Swift
+
public func setDetail ( value : String , forKey key : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Update the detail defined by a given key
with the bool value
provided.
+
+
+
+
Declaration
+
+
Swift
+
public func setDetail ( value : Bool ?, forKey key : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the Apple Pay transaction.
+
+
+
+
Declaration
+
+
Swift
+
public func fillApplePay ( token : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the Card transaction with a token.
+
+
+
+
Declaration
+
+
Swift
+
public func fillCard ( token : String , storeDetails : Bool ? = nil )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the Card transaction with CVC.
+
+
+
+
Declaration
+
+
Swift
+
public func fillCard ( cvc : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the iDEAL transaction.
+
+
+
+
Declaration
+
+
Swift
+
public func fillIdeal ( issuerIdentifier : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the SEPA transaction.
+
+
+
+
Declaration
+
+
Swift
+
public func fillSepa ( name : String , iban : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/PaymentMethod.html b/Docs/Classes/PaymentMethod.html
new file mode 100644
index 0000000000..f93d8dc812
--- /dev/null
+++ b/Docs/Classes/PaymentMethod.html
@@ -0,0 +1,363 @@
+
+
+
+ PaymentMethod Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentMethod Class Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentMethod
+
+
+
public final class PaymentMethod
+
+
+
+
Represents a locale payment method that can be used to complete a payment.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The name of the payment method.
+
+
+
+
Declaration
+
+
Swift
+
public let name : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The payment method type.
+
+
+
+
Declaration
+
+
Swift
+
public let type : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user.
+
+
+
+
Declaration
+
+
Swift
+
public let isOneClick : Bool
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A URL to the logo of the payment method.
+
+
+
+
Declaration
+
+
Swift
+
public let logoURL : URL ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The input details that should be filled in to complete the payment method.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Members of the payment method (only applicable when the receiver is a group).
+
+
+
+
Declaration
+
+
Swift
+
public let members : [ PaymentMethod ]?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user.
+
+
+
+
Declaration
+
+
Swift
+
public var oneClick : Bool
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Classes/PaymentRequest.html b/Docs/Classes/PaymentRequest.html
new file mode 100644
index 0000000000..5763f919a8
--- /dev/null
+++ b/Docs/Classes/PaymentRequest.html
@@ -0,0 +1,571 @@
+
+
+
+ PaymentRequest Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentRequest Class Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentRequest
+
+
+
public final class PaymentRequest
+
+
+
+
This class is the starting point for Custom Integration .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The selected payment method.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var paymentMethod : PaymentMethod ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Amount to be charged.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var amount : Int ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var currency : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var reference : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Payment country code.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var countryCode : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var shopperLocale : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var shopperReference : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Generation time. Used for generating a token for card payments.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var generationTime : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Public key. Used for generating a token for card payments.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var publicKey : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Creates a PaymentRequest
object and initialises it with a provided delegate.
+
+
+
+
+
Parameters
+
+
+
+
+
+ delegate
+
+
+
+
+
An object that implements PaymentRequestDelegate
.
+
+
+
+
+
+
+
+
Return Value
+
An initialised instance of the payment request.
+
+
+
+
+
+
+
+
+
+
+
+
Starts the payment request.
+
+
+
+
Declaration
+
+
Swift
+
public func start ()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Permanently deletes payment method from shopper’s preferred payment options.
+
+
+
+
Declaration
+
+
Swift
+
public func deletePreferred ( paymentMethod : PaymentMethod , completion : @escaping ( Bool , Error ?) -> Void )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Cancels the payment request.
+
+
+
+
Declaration
+
+
Swift
+
public func cancel ()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Enums/CardType.html b/Docs/Enums/CardType.html
new file mode 100644
index 0000000000..36d1e16613
--- /dev/null
+++ b/Docs/Enums/CardType.html
@@ -0,0 +1,1034 @@
+
+
+
+ CardType Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ CardType Enum Reference
+
+
+
+
+
+
+
+
+
+
+
CardType
+
+
+
public enum CardType : String
+
+
+
+
Enum containing most known types of credit and debit cards.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Alpha Bank Bonus MasterCard
+
+
+
+
Declaration
+
+
Swift
+
case alphaBankBonusMasterCard = "mcalphabankbonus"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Alpha Bank Bonus VISA
+
+
+
+
Declaration
+
+
Swift
+
case alphaBankBonusVISA = "visaalphabankbonus"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case americanExpress = "amex"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case bijenkorfCard = "bijcard"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case carteBancaire = "cartebancaire"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case chinaUnionPay = "cup"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case codensa
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case dankort
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case dankortVISA = "visadankort"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case diners
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case discover
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case hipercard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case karenMillen = "karenmillen"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case maestro
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case maestroUK = "maestrouk"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case masterCard = "mc"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Universal Air Travel Plan
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case unionPay = "unionpay"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case warehouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Array containing all card types in this enum.
+
+
+
+
Declaration
+
+
Swift
+
public static let all = [ masterCard , americanExpress , visa , diners , discover , jcb , elo , hipercard , unionPay , bijenkorfCard , maestroUK , solo , bcmc , dankort , uatp , chinaUnionPay , codensa , alphaBankBonusVISA , dankortVISA , alphaBankBonusMasterCard , hiper , oasis , karenMillen , warehouse , mir , maestro , carteBancaire ]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Enums/Error.html b/Docs/Enums/Error.html
new file mode 100644
index 0000000000..6c79568ebf
--- /dev/null
+++ b/Docs/Enums/Error.html
@@ -0,0 +1,382 @@
+
+
+
+ Error Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Error Enum Reference
+
+
+
+
+
+
+
+
+
+
+
Error
+
+
+
public enum Error : Swift . Error
+
+
+
+
Error type.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Error with a message. This enum case is deprecated. Please use serverError
instead.
+
+
+
+
Declaration
+
+
Swift
+
case message ( String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Error returned from server.
+
+
+
+
Declaration
+
+
Swift
+
case serverError ( String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case networkError ( Swift . Error )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Unexpected data or data format.
+
+
+
+
Declaration
+
+
Swift
+
case unexpectedData
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case unexpectedError
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Payment was canceled.
+
+
+
+
Declaration
+
+
Swift
+
case canceled
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public var errorDescription : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Enums/InputType.html b/Docs/Enums/InputType.html
new file mode 100644
index 0000000000..f8c48739fc
--- /dev/null
+++ b/Docs/Enums/InputType.html
@@ -0,0 +1,383 @@
+
+
+
+ InputType Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ InputType Enum Reference
+
+
+
+
+
+
+
+
+
+
+
InputType
+
+
+
public enum InputType : String
+
+
+
+
Defines types of payment details.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Boolean input type.
+
+
+
+
Declaration
+
+
Swift
+
case boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Input type should be selected from the given list.
+
+
+
+
Declaration
+
+
Swift
+
case select
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Card token input type.
+
+
+
+
Declaration
+
+
Swift
+
case cardToken
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Apple Pay token input type.
+
+
+
+
Declaration
+
+
Swift
+
case applePayToken
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Enums/PaymentRequestResult.html b/Docs/Enums/PaymentRequestResult.html
new file mode 100644
index 0000000000..472f9b1192
--- /dev/null
+++ b/Docs/Enums/PaymentRequestResult.html
@@ -0,0 +1,228 @@
+
+
+
+ PaymentRequestResult Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentRequestResult Enum Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentRequestResult
+
+
+
public enum PaymentRequestResult
+
+
+
+
Result of a payment request.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
In case of success a Payment
object will be returned.
+
+
+
+
Declaration
+
+
Swift
+
case payment ( Payment )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
In case of failure an Error
will be returned.
+
+
+
+
Declaration
+
+
Swift
+
case error ( Error )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Enums/PaymentStatus.html b/Docs/Enums/PaymentStatus.html
new file mode 100644
index 0000000000..62fdd52ea7
--- /dev/null
+++ b/Docs/Enums/PaymentStatus.html
@@ -0,0 +1,321 @@
+
+
+
+ PaymentStatus Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentStatus Enum Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentStatus
+
+
+
public enum PaymentStatus : String
+
+
+
+
Payment statuses.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case received
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Payment authorised.
+
+
+
+
Declaration
+
+
Swift
+
case authorised
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case refused
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case cancelled
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Payment Method.html b/Docs/Payment Method.html
new file mode 100644
index 0000000000..4dc7198b56
--- /dev/null
+++ b/Docs/Payment Method.html
@@ -0,0 +1,321 @@
+
+
+
+ Payment Method Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Payment Method Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Represents a locale payment method that can be used to complete a payment.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class PaymentMethod
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public class PaymentDetails
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The payment detail needed for the transaction.
+The detail has a type
(InputType
). If type
is .select
, a list of InputSelectItem
will be available for selection in the items
variable.
+The detail might be optional
.
+The detail value can be set as a string (stringValue
) or a bool value (boolValue
).
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public class InputDetail
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Defines types of payment details.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public enum InputType : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public final class InputSelectItem
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Payment Request.html b/Docs/Payment Request.html
new file mode 100644
index 0000000000..4d9da63fd8
--- /dev/null
+++ b/Docs/Payment Request.html
@@ -0,0 +1,286 @@
+
+
+
+ Payment Request Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Payment Request Reference
+
+
+
+
+
+
+
+
+
+
+
Payment Request
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public final class PaymentRequest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The payment request delegate. Used for Custom integration comunication. All delegate methods are invoked on the main thread.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public protocol PaymentRequestDelegate : class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Result of a payment request.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public enum PaymentRequestResult
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public enum Error : Swift . Error
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Payment.html b/Docs/Payment.html
new file mode 100644
index 0000000000..9d42acfdac
--- /dev/null
+++ b/Docs/Payment.html
@@ -0,0 +1,222 @@
+
+
+
+ Payment Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Payment Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Represents a payment that has been completed by the user. The result of the payment can be retrieved via the status
property.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class Payment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public enum PaymentStatus : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Protocols/CheckoutViewControllerDelegate.html b/Docs/Protocols/CheckoutViewControllerDelegate.html
new file mode 100644
index 0000000000..f810b4d4eb
--- /dev/null
+++ b/Docs/Protocols/CheckoutViewControllerDelegate.html
@@ -0,0 +1,356 @@
+
+
+
+ CheckoutViewControllerDelegate Protocol Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ CheckoutViewControllerDelegate Protocol Reference
+
+
+
+
+
+
+
+
+
+
+
CheckoutViewControllerDelegate
+
+
+
public protocol CheckoutViewControllerDelegate : class
+
+
+
+
The CheckoutViewControllerDelegate
protocol defines the methods that a delegate of CheckoutViewController
should implement to provide payment data and be informed of the payment flow progress.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Invoked when the payment flow has started and payment data is requested from the merchant server.
+
+
+
+
Declaration
+
+
Swift
+
func checkoutViewController ( _ controller : CheckoutViewController , requiresPaymentDataForToken token : String , completion : @escaping DataCompletion )
+
+
+
+
+
Parameters
+
+
+
+
+
+ controller
+
+
+
+
+
The checkout view controller that has started the payment flow.
+
+
+
+
+
+
+ token
+
+
+
+
+
The token assigned to the payment flow.
+
+
+
+
+
+
+ completion
+
+
+
+
+
The completion handler to invoke when the payment data is retrieved from the merchant server.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Invoked when the redirection to a URL has been made. The given completion handler should be invoked when the user returns to the application through a URL.
+
+
+
+
Declaration
+
+
Swift
+
func checkoutViewController ( _ controller : CheckoutViewController , requiresReturnURL completion : @escaping URLCompletion )
+
+
+
+
+
Parameters
+
+
+
+
+
+ controller
+
+
+
+
+
The checkout view controller which requested the return from a URL redirection.
+
+
+
+
+
+
+ completion
+
+
+
+
+
The completion handler to invoke when the user returns to the application through a URL.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Invoked when the payment flow has finished.
+
+
+
+
+
Parameters
+
+
+
+
+
+ controller
+
+
+
+
+
The checkout view controller that finished the payment flow.
+
+
+
+
+
+
+ result
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Protocols/PaymentRequestDelegate.html b/Docs/Protocols/PaymentRequestDelegate.html
new file mode 100644
index 0000000000..76d5cc82eb
--- /dev/null
+++ b/Docs/Protocols/PaymentRequestDelegate.html
@@ -0,0 +1,305 @@
+
+
+
+ PaymentRequestDelegate Protocol Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentRequestDelegate Protocol Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentRequestDelegate
+
+
+
public protocol PaymentRequestDelegate : class
+
+
+
+
The payment request delegate. Used for Custom integration comunication. All delegate methods are invoked on the main thread.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Given the PaymentRequest
that started the payment flow and token
, waits for data from merchant server to be passed via completion
.
+
+
+
+
Declaration
+
+
Swift
+
func paymentRequest ( _ request : PaymentRequest , requiresPaymentDataForToken token : String , completion : @escaping DataCompletion )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Given a list of PaymentMethod
(available and preferred) waits for the selection via completion
.
+
+
+
+
Declaration
+
+
Swift
+
func paymentRequest ( _ request : PaymentRequest , requiresPaymentMethodFrom preferredMethods : [ PaymentMethod ]?, available availableMethods : [ PaymentMethod ], completion : @escaping MethodCompletion )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This method is called when a URL redirection needs to be executed. Use the url
to continue payment flow in Safari or SFSafariViewController
. After the process is completed, the completion
for the given URL must be called.
+
+
+
+
Declaration
+
+
Swift
+
func paymentRequest ( _ request : PaymentRequest , requiresReturnURLFrom url : URL , completion : @escaping URLCompletion )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This method is called when input is needed for completing the transation. The filled PaymentDetails
should be sent via completion
.
+
+
+
+
Declaration
+
+
Swift
+
func paymentRequest ( _ request : PaymentRequest , requiresPaymentDetails details : PaymentDetails , completion : @escaping PaymentDetailsCompletion )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This method is called when the payment flow is finished.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Structs/IBANSpecification.html b/Docs/Structs/IBANSpecification.html
new file mode 100644
index 0000000000..5e893dc146
--- /dev/null
+++ b/Docs/Structs/IBANSpecification.html
@@ -0,0 +1,324 @@
+
+
+
+ IBANSpecification Struct Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ IBANSpecification Struct Reference
+
+
+
+
+
+
+
+
+
+
+
IBANSpecification
+
+
+
public struct IBANSpecification
+
+
+
+
Contains the country-specific specifications for countries that adopt the IBAN standard.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The code of the country to which the specifications apply.
+
+
+
+
Declaration
+
+
Swift
+
public let countryCode : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The length of a valid IBAN.
+
+
+
+
Declaration
+
+
Swift
+
public let length : Int
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The structure of the underlying BBAN.
+
+
+
+
Declaration
+
+
Swift
+
public let structure : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
An example of a valid IBAN.
+
+
+
+
Declaration
+
+
Swift
+
public let example : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Returns the IBAN specification for the country with the given code, or nil
if none could be found.
+
+
+
+
Declaration
+
+
Swift
+
public init ?( forCountryCode countryCode : String )
+
+
+
+
+
Parameters
+
+
+
+
+
+ countryCode
+
+
+
+
+
The code of the country to retrieve the IBAN specification for.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/UI.html b/Docs/UI.html
new file mode 100644
index 0000000000..2492967c11
--- /dev/null
+++ b/Docs/UI.html
@@ -0,0 +1,255 @@
+
+
+
+ UI Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ UI Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The starting point for Quick integration . Initialize with CheckoutViewContollerDelegate
and present this view controller in your app to start the payment flow. If you don’t embed the CheckoutViewController
in an existing UINavigationController
, a new one will be created automatically.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class CheckoutViewController : UIViewController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The CheckoutViewControllerDelegate
protocol defines the methods that a delegate of CheckoutViewController
should implement to provide payment data and be informed of the payment flow progress.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public protocol CheckoutViewControllerDelegate : class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Provides properties to customize the appearance of the UI components provided by this library.
+Note that AppearanceConfiguration
is only used when the CheckoutViewController
is first initialized. Changes to this object after it has been created are ignored.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class AppearanceConfiguration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/Utilities.html b/Docs/Utilities.html
new file mode 100644
index 0000000000..f6e25ff985
--- /dev/null
+++ b/Docs/Utilities.html
@@ -0,0 +1,318 @@
+
+
+
+ Utilities Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Utilities Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Enum containing most known types of credit and debit cards.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public enum CardType : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The CardValidator class provides static methods to validate and format card numbers and expiry dates, and to detect card types.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class CardValidator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Contains the country-specific specifications for countries that adopt the IBAN standard.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public struct IBANSpecification
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Provides a static method to validate an IBAN value.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public class IBANValidator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Provides a text field designed for the entry of an IBAN value. This field formats and validates the IBAN in real time.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public class IBANTextField : UITextField
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/css/highlight.css b/Docs/css/highlight.css
new file mode 100644
index 0000000000..d0db0e13b0
--- /dev/null
+++ b/Docs/css/highlight.css
@@ -0,0 +1,200 @@
+/* Credit to https://gist.github.com/wataru420/2048287 */
+.highlight {
+ /* Comment */
+ /* Error */
+ /* Keyword */
+ /* Operator */
+ /* Comment.Multiline */
+ /* Comment.Preproc */
+ /* Comment.Single */
+ /* Comment.Special */
+ /* Generic.Deleted */
+ /* Generic.Deleted.Specific */
+ /* Generic.Emph */
+ /* Generic.Error */
+ /* Generic.Heading */
+ /* Generic.Inserted */
+ /* Generic.Inserted.Specific */
+ /* Generic.Output */
+ /* Generic.Prompt */
+ /* Generic.Strong */
+ /* Generic.Subheading */
+ /* Generic.Traceback */
+ /* Keyword.Constant */
+ /* Keyword.Declaration */
+ /* Keyword.Pseudo */
+ /* Keyword.Reserved */
+ /* Keyword.Type */
+ /* Literal.Number */
+ /* Literal.String */
+ /* Name.Attribute */
+ /* Name.Builtin */
+ /* Name.Class */
+ /* Name.Constant */
+ /* Name.Entity */
+ /* Name.Exception */
+ /* Name.Function */
+ /* Name.Namespace */
+ /* Name.Tag */
+ /* Name.Variable */
+ /* Operator.Word */
+ /* Text.Whitespace */
+ /* Literal.Number.Float */
+ /* Literal.Number.Hex */
+ /* Literal.Number.Integer */
+ /* Literal.Number.Oct */
+ /* Literal.String.Backtick */
+ /* Literal.String.Char */
+ /* Literal.String.Doc */
+ /* Literal.String.Double */
+ /* Literal.String.Escape */
+ /* Literal.String.Heredoc */
+ /* Literal.String.Interpol */
+ /* Literal.String.Other */
+ /* Literal.String.Regex */
+ /* Literal.String.Single */
+ /* Literal.String.Symbol */
+ /* Name.Builtin.Pseudo */
+ /* Name.Variable.Class */
+ /* Name.Variable.Global */
+ /* Name.Variable.Instance */
+ /* Literal.Number.Integer.Long */ }
+ .highlight .c {
+ color: #999988;
+ font-style: italic; }
+ .highlight .err {
+ color: #a61717;
+ background-color: #e3d2d2; }
+ .highlight .k {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .o {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .cm {
+ color: #999988;
+ font-style: italic; }
+ .highlight .cp {
+ color: #999999;
+ font-weight: bold; }
+ .highlight .c1 {
+ color: #999988;
+ font-style: italic; }
+ .highlight .cs {
+ color: #999999;
+ font-weight: bold;
+ font-style: italic; }
+ .highlight .gd {
+ color: #000000;
+ background-color: #ffdddd; }
+ .highlight .gd .x {
+ color: #000000;
+ background-color: #ffaaaa; }
+ .highlight .ge {
+ color: #000000;
+ font-style: italic; }
+ .highlight .gr {
+ color: #aa0000; }
+ .highlight .gh {
+ color: #999999; }
+ .highlight .gi {
+ color: #000000;
+ background-color: #ddffdd; }
+ .highlight .gi .x {
+ color: #000000;
+ background-color: #aaffaa; }
+ .highlight .go {
+ color: #888888; }
+ .highlight .gp {
+ color: #555555; }
+ .highlight .gs {
+ font-weight: bold; }
+ .highlight .gu {
+ color: #aaaaaa; }
+ .highlight .gt {
+ color: #aa0000; }
+ .highlight .kc {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .kd {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .kp {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .kr {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .kt {
+ color: #445588; }
+ .highlight .m {
+ color: #009999; }
+ .highlight .s {
+ color: #d14; }
+ .highlight .na {
+ color: #008080; }
+ .highlight .nb {
+ color: #0086B3; }
+ .highlight .nc {
+ color: #445588;
+ font-weight: bold; }
+ .highlight .no {
+ color: #008080; }
+ .highlight .ni {
+ color: #800080; }
+ .highlight .ne {
+ color: #990000;
+ font-weight: bold; }
+ .highlight .nf {
+ color: #990000; }
+ .highlight .nn {
+ color: #555555; }
+ .highlight .nt {
+ color: #000080; }
+ .highlight .nv {
+ color: #008080; }
+ .highlight .ow {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .w {
+ color: #bbbbbb; }
+ .highlight .mf {
+ color: #009999; }
+ .highlight .mh {
+ color: #009999; }
+ .highlight .mi {
+ color: #009999; }
+ .highlight .mo {
+ color: #009999; }
+ .highlight .sb {
+ color: #d14; }
+ .highlight .sc {
+ color: #d14; }
+ .highlight .sd {
+ color: #d14; }
+ .highlight .s2 {
+ color: #d14; }
+ .highlight .se {
+ color: #d14; }
+ .highlight .sh {
+ color: #d14; }
+ .highlight .si {
+ color: #d14; }
+ .highlight .sx {
+ color: #d14; }
+ .highlight .sr {
+ color: #009926; }
+ .highlight .s1 {
+ color: #d14; }
+ .highlight .ss {
+ color: #990073; }
+ .highlight .bp {
+ color: #999999; }
+ .highlight .vc {
+ color: #008080; }
+ .highlight .vg {
+ color: #008080; }
+ .highlight .vi {
+ color: #008080; }
+ .highlight .il {
+ color: #009999; }
diff --git a/Docs/css/jazzy.css b/Docs/css/jazzy.css
new file mode 100644
index 0000000000..c83db5bfc5
--- /dev/null
+++ b/Docs/css/jazzy.css
@@ -0,0 +1,368 @@
+*, *:before, *:after {
+ box-sizing: inherit; }
+
+body {
+ margin: 0;
+ background: #fff;
+ color: #333;
+ font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
+ letter-spacing: .2px;
+ -webkit-font-smoothing: antialiased;
+ box-sizing: border-box; }
+
+h1 {
+ font-size: 2rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.6em; }
+
+h2 {
+ font-size: 1.75rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.3em; }
+
+h3 {
+ font-size: 1.5rem;
+ font-weight: 700;
+ margin: 1em 0 0.3em; }
+
+h4 {
+ font-size: 1.25rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.85em; }
+
+h5 {
+ font-size: 1rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.85em; }
+
+h6 {
+ font-size: 1rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.85em;
+ color: #777; }
+
+p {
+ margin: 0 0 1em; }
+
+ul, ol {
+ padding: 0 0 0 2em;
+ margin: 0 0 0.85em; }
+
+blockquote {
+ margin: 0 0 0.85em;
+ padding: 0 15px;
+ color: #858585;
+ border-left: 4px solid #e5e5e5; }
+
+img {
+ max-width: 100%; }
+
+a {
+ color: #4183c4;
+ text-decoration: none; }
+ a:hover, a:focus {
+ outline: 0;
+ text-decoration: underline; }
+
+table {
+ background: #fff;
+ width: 100%;
+ border-collapse: collapse;
+ border-spacing: 0;
+ overflow: auto;
+ margin: 0 0 0.85em; }
+
+tr:nth-child(2n) {
+ background-color: #fbfbfb; }
+
+th, td {
+ padding: 6px 13px;
+ border: 1px solid #ddd; }
+
+pre {
+ margin: 0 0 1.275em;
+ padding: .85em 1em;
+ overflow: auto;
+ background: #f7f7f7;
+ font-size: .85em;
+ font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
+
+code {
+ font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
+
+p > code, li > code {
+ background: #f7f7f7;
+ padding: .2em; }
+ p > code:before, p > code:after, li > code:before, li > code:after {
+ letter-spacing: -.2em;
+ content: "\00a0"; }
+
+pre code {
+ padding: 0;
+ white-space: pre; }
+
+.content-wrapper {
+ display: flex;
+ flex-direction: column; }
+ @media (min-width: 768px) {
+ .content-wrapper {
+ flex-direction: row; } }
+
+.header {
+ display: flex;
+ padding: 8px;
+ font-size: 0.875em;
+ background: #444;
+ color: #999; }
+
+.header-col {
+ margin: 0;
+ padding: 0 8px; }
+
+.header-col--primary {
+ flex: 1; }
+
+.header-link {
+ color: #fff; }
+
+.header-icon {
+ padding-right: 6px;
+ vertical-align: -4px;
+ height: 16px; }
+
+.breadcrumbs {
+ font-size: 0.875em;
+ padding: 8px 16px;
+ margin: 0;
+ background: #fbfbfb;
+ border-bottom: 1px solid #ddd; }
+
+.carat {
+ height: 10px;
+ margin: 0 5px; }
+
+.navigation {
+ order: 2; }
+ @media (min-width: 768px) {
+ .navigation {
+ order: 1;
+ width: 25%;
+ max-width: 300px;
+ padding-bottom: 64px;
+ overflow: hidden;
+ word-wrap: normal;
+ background: #fbfbfb;
+ border-right: 1px solid #ddd; } }
+
+.nav-groups {
+ list-style-type: none;
+ padding-left: 0; }
+
+.nav-group-name {
+ border-bottom: 1px solid #ddd;
+ padding: 8px 0 8px 16px; }
+
+.nav-group-name-link {
+ color: #333; }
+
+.nav-group-tasks {
+ margin: 8px 0;
+ padding: 0 0 0 8px; }
+
+.nav-group-task {
+ font-size: 1em;
+ list-style-type: none;
+ white-space: nowrap; }
+
+.nav-group-task-link {
+ color: #808080; }
+
+.main-content {
+ order: 1; }
+ @media (min-width: 768px) {
+ .main-content {
+ order: 2;
+ flex: 1;
+ padding-bottom: 60px; } }
+
+.section {
+ padding: 0 32px;
+ border-bottom: 1px solid #ddd; }
+
+.section-content {
+ max-width: 834px;
+ margin: 0 auto;
+ padding: 16px 0; }
+
+.section-name {
+ color: #666;
+ display: block; }
+
+.declaration .highlight {
+ overflow-x: initial;
+ padding: 8px 0;
+ margin: 0;
+ background-color: transparent;
+ border: none; }
+
+.task-group-section {
+ border-top: 1px solid #ddd; }
+
+.task-group {
+ padding-top: 0px; }
+
+.task-name-container a[name]:before {
+ content: "";
+ display: block; }
+
+.item-container {
+ padding: 0; }
+
+.item {
+ padding-top: 8px;
+ width: 100%;
+ list-style-type: none; }
+ .item a[name]:before {
+ content: "";
+ display: block; }
+ .item .token {
+ padding-left: 3px;
+ margin-left: 0px;
+ font-size: 1rem; }
+ .item .declaration-note {
+ font-size: .85em;
+ color: #808080;
+ font-style: italic; }
+
+.pointer-container {
+ border-bottom: 1px solid #ddd;
+ left: -23px;
+ padding-bottom: 13px;
+ position: relative;
+ width: 110%; }
+
+.pointer {
+ left: 21px;
+ top: 7px;
+ display: block;
+ position: absolute;
+ width: 12px;
+ height: 12px;
+ border-left: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+ background: #fff;
+ transform: rotate(45deg); }
+
+.height-container {
+ display: none;
+ position: relative;
+ width: 100%;
+ overflow: hidden; }
+ .height-container .section {
+ background: #fff;
+ border: 1px solid #ddd;
+ border-top-width: 0;
+ padding-top: 10px;
+ padding-bottom: 5px;
+ padding: 8px 16px; }
+
+.aside, .language {
+ padding: 6px 12px;
+ margin: 12px 0;
+ border-left: 5px solid #dddddd;
+ overflow-y: hidden; }
+ .aside .aside-title, .language .aside-title {
+ font-size: 9px;
+ letter-spacing: 2px;
+ text-transform: uppercase;
+ padding-bottom: 0;
+ margin: 0;
+ color: #aaa;
+ -webkit-user-select: none; }
+ .aside p:last-child, .language p:last-child {
+ margin-bottom: 0; }
+
+.language {
+ border-left: 5px solid #cde9f4; }
+ .language .aside-title {
+ color: #4183c4; }
+
+.aside-warning {
+ border-left: 5px solid #ff6666; }
+ .aside-warning .aside-title {
+ color: #ff0000; }
+
+.graybox {
+ border-collapse: collapse;
+ width: 100%; }
+ .graybox p {
+ margin: 0;
+ word-break: break-word;
+ min-width: 50px; }
+ .graybox td {
+ border: 1px solid #ddd;
+ padding: 5px 25px 5px 10px;
+ vertical-align: middle; }
+ .graybox tr td:first-of-type {
+ text-align: right;
+ padding: 7px;
+ vertical-align: top;
+ word-break: normal;
+ width: 40px; }
+
+.slightly-smaller {
+ font-size: 0.9em; }
+
+.footer {
+ padding: 8px 16px;
+ background: #444;
+ color: #ddd;
+ font-size: 0.8em; }
+ .footer p {
+ margin: 8px 0; }
+ .footer a {
+ color: #fff; }
+
+html.dash .header, html.dash .breadcrumbs, html.dash .navigation {
+ display: none; }
+html.dash .height-container {
+ display: block; }
+
+form[role=search] input {
+ font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 24px;
+ padding: 0 10px;
+ margin: 0;
+ border: none;
+ border-radius: 1em; }
+ .loading form[role=search] input {
+ background: white url(../img/spinner.gif) center right 4px no-repeat; }
+form[role=search] .tt-menu {
+ margin: 0;
+ min-width: 300px;
+ background: #fbfbfb;
+ color: #333;
+ border: 1px solid #ddd; }
+form[role=search] .tt-highlight {
+ font-weight: bold; }
+form[role=search] .tt-suggestion {
+ font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
+ padding: 0 8px; }
+ form[role=search] .tt-suggestion span {
+ display: table-cell;
+ white-space: nowrap; }
+ form[role=search] .tt-suggestion .doc-parent-name {
+ width: 100%;
+ text-align: right;
+ font-weight: normal;
+ font-size: 0.9em;
+ padding-left: 16px; }
+form[role=search] .tt-suggestion:hover,
+form[role=search] .tt-suggestion.tt-cursor {
+ cursor: pointer;
+ background-color: #4183c4;
+ color: #fff; }
+form[role=search] .tt-suggestion:hover .doc-parent-name,
+form[role=search] .tt-suggestion.tt-cursor .doc-parent-name {
+ color: #fff; }
diff --git a/Docs/docsets/Adyen.docset/Contents/Info.plist b/Docs/docsets/Adyen.docset/Contents/Info.plist
new file mode 100644
index 0000000000..1894f69e52
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Info.plist
@@ -0,0 +1,20 @@
+
+
+
+
+ CFBundleIdentifier
+ com.jazzy.adyen
+ CFBundleName
+ Adyen
+ DocSetPlatformFamily
+ adyen
+ isDashDocset
+
+ dashIndexFilePath
+ index.html
+ isJavaScriptEnabled
+
+ DashDocSetFamily
+ dashtoc
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/AppearanceConfiguration.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/AppearanceConfiguration.html
new file mode 100644
index 0000000000..7a13e1d69c
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/AppearanceConfiguration.html
@@ -0,0 +1,550 @@
+
+
+
+ AppearanceConfiguration Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ AppearanceConfiguration Class Reference
+
+
+
+
+
+
+
+
+
+
+
AppearanceConfiguration
+
+
+
public final class AppearanceConfiguration
+
+
+
+
Provides properties to customize the appearance of the UI components provided by this library.
+Note that AppearanceConfiguration
is only used when the CheckoutViewController
is first initialized. Changes to this object after it has been created are ignored.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Initializes the appearance configuration.
+
+
+
+
Declaration
+
+
Swift
+
public init ()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The preferred status bar style.
+
+
+
+
Declaration
+
+
Swift
+
public var preferredStatusBarStyle = UIStatusBarStyle . default
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The attributes used for the navigation bar’s title.
+
+
+
+
Declaration
+
+
Swift
+
public var navigationBarTitleTextAttributes : [ String : Any ]?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The navigation bar’s tint color.
+
+
+
+
Declaration
+
+
Swift
+
public var navigationBarTintColor : UIColor ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The navigation bar’s background color.
+
+
+
+
Declaration
+
+
Swift
+
public var navigationBarBackgroundColor : UIColor ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A Boolean value indicating whether the navigation bar is translucent.
+
+
+
+
Declaration
+
+
Swift
+
public var isNavigationBarTranslucent = true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The image of the cancel button in the navigation bar, or nil
if a title should be used instead.
+
+
+
+
Declaration
+
+
Swift
+
public var navigationBarCancelButtonImage : UIImage ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The attributes used for the checkout button’s title.
+
+
+
+
Declaration
+
+
Swift
+
public var checkoutButtonTitleTextAttributes : [ String : Any ]?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The insets from the edges of the checkout button to the title.
+
+
+
+
Declaration
+
+
Swift
+
public var checkoutButtonTitleEdgeInsets : UIEdgeInsets ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The corner radius of the checkout button.
+
+
+
+
Declaration
+
+
Swift
+
public var checkoutButtonCornerRadius : CGFloat = 0.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The tint color of most buttons and actionable elements.
+
+
+
+
Declaration
+
+
Swift
+
public var tintColor : UIColor ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The default appearance configuration.
+
+
+
+
Declaration
+
+
Swift
+
public static var ` default ` : AppearanceConfiguration =
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/CardValidator.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/CardValidator.html
new file mode 100644
index 0000000000..f4b5663ab6
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/CardValidator.html
@@ -0,0 +1,351 @@
+
+
+
+ CardValidator Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ CardValidator Class Reference
+
+
+
+
+
+
+
+
+
+
+
CardValidator
+
+
+
public final class CardValidator
+
+
+
+
The CardValidator class provides static methods to validate and format card numbers and expiry dates, and to detect card types.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Validates and formats the given card number, and detects its card type.
+
+
+
+
Declaration
+
+
Swift
+
public static func validate ( cardNumber : String , acceptedCardTypes : [ CardType ] = CardType . all ) -> ( isValid : Bool , type : CardType ?, formattedNumber : String )
+
+
+
+
+
Parameters
+
+
+
+
+
+ cardNumber
+
+
+
+
+
The card number to validate and format. The card number is sanitized before validating and formatting, to filter out non-numerical characters.
+
+
+
+
+
+
+ acceptedCardTypes
+
+
+
+
+
The card types to check against for detecting the card type.
+
+
+
+
+
+
+
+
Return Value
+
A tuple containing a boolean value indicating whether the card number is valid, the detected card type, and the formatted card number.
+
+
+
+
+
+
+
+
+
+
+
+
Validates and formats the given expiration date.
+
+
+
+
Declaration
+
+
Swift
+
public static func validate ( expiryDate : String , separator : String ? = "/" ) -> ( isValid : Bool , formattedDate : String )
+
+
+
+
+
Parameters
+
+
+
+
+
+ expiryDate
+
+
+
+
+
The expiry date to validate and format. The expiry date is sanitized before validating and formatting, to filter out non-numerical characters.
+
+
+
+
+
+
+ separator
+
+
+
+
+
The optional string to use to separate the month and year in the formatted date, default is /
.
+
+
+
+
+
+
+
+
Return Value
+
A tuple containing a boolean value indicating whether the expiry date is valid, and a formatted expiry date.
+
+
+
+
+
+
+
+
+
+
+
+
Validates and formats the given cvc.
+
+
+
+
Declaration
+
+
Swift
+
public static func validate ( cvc : String ) -> ( isValid : Bool , formattedCvc : String )
+
+
+
+
+
Parameters
+
+
+
+
+
+ cvc
+
+
+
+
+
The cvc value to validate and format. The cvc is sanitized before validating and formatting, to filter out non-numerical characters.
+
+
+
+
+
+
+
+
Return Value
+
A tuple containing a boolean value indicating whether the cvc is valid, and the formatted cvc string.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/CheckoutViewController.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/CheckoutViewController.html
new file mode 100644
index 0000000000..74f58f587f
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/CheckoutViewController.html
@@ -0,0 +1,255 @@
+
+
+
+ CheckoutViewController Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ CheckoutViewController Class Reference
+
+
+
+
+
+
+
+
+
+
+
CheckoutViewController
+
+
+
public final class CheckoutViewController : UIViewController
+
+
+
+
The starting point for Quick integration . Initialize with CheckoutViewContollerDelegate
and present this view controller in your app to start the payment flow. If you don’t embed the CheckoutViewController
in an existing UINavigationController
, a new one will be created automatically.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The delegate for Quick integration.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Initializes the checkout view controller.
+
+
+
+
+
Parameters
+
+
+
+
+
+ delegate
+
+
+
+
+
The delegate to receive the checkout view controller’s events.
+
+
+
+
+
+
+ appearanceConfiguration
+
+
+
+
+
The configuration to use for customizing the checkout view controller’s appearance.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/IBANTextField.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/IBANTextField.html
new file mode 100644
index 0000000000..de9f490d0b
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/IBANTextField.html
@@ -0,0 +1,197 @@
+
+
+
+ IBANTextField Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ IBANTextField Class Reference
+
+
+
+
+
+
+
+
+
+
+
IBANTextField
+
+
+
public class IBANTextField : UITextField
+
+
+
+
Provides a text field designed for the entry of an IBAN value. This field formats and validates the IBAN in real time.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The IBAN entered in the text field, or nil
if no valid IBAN has been entered.
+
+
+
+
Declaration
+
+
Swift
+
public var iban : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/IBANValidator.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/IBANValidator.html
new file mode 100644
index 0000000000..29b612f4c9
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/IBANValidator.html
@@ -0,0 +1,220 @@
+
+
+
+ IBANValidator Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ IBANValidator Class Reference
+
+
+
+
+
+
+
+
+
+
+
IBANValidator
+
+
+
public class IBANValidator
+
+
+
+
Provides a static method to validate an IBAN value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Checks if the given string is a valid IBAN value.
+
+
+
+
Declaration
+
+
Swift
+
public static func isValid ( _ string : String ) -> Bool
+
+
+
+
+
Parameters
+
+
+
+
+
+ string
+
+
+
+
+
+
+
+
+
+
+
Return Value
+
A Boolean value indicating whether the given string is a valid IBAN.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/InputDetail.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/InputDetail.html
new file mode 100644
index 0000000000..7fc362f7c0
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/InputDetail.html
@@ -0,0 +1,308 @@
+
+
+
+ InputDetail Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ InputDetail Class Reference
+
+
+
+
+
+
+
+
+
+
+
InputDetail
+
+
+
public class InputDetail
+
+
+
+
The payment detail needed for the transaction.
+The detail has a type
(InputType
). If type
is .select
, a list of InputSelectItem
will be available for selection in the items
variable.
+The detail might be optional
.
+The detail value can be set as a string (stringValue
) or a bool value (boolValue
).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Whether the detail is optional.
+
+
+
+
Declaration
+
+
Swift
+
public let optional : Bool
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Detail string value.
+
+
+
+
Declaration
+
+
Swift
+
public var stringValue : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public var boolValue : Bool ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/InputSelectItem.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/InputSelectItem.html
new file mode 100644
index 0000000000..a7e1e2127d
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/InputSelectItem.html
@@ -0,0 +1,251 @@
+
+
+
+ InputSelectItem Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ InputSelectItem Class Reference
+
+
+
+
+
+
+
+
+
+
+
InputSelectItem
+
+
+
public final class InputSelectItem
+
+
+
+
Represents a selectable item used in InputDetail
with select
type.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Identifier of an item. Should be used to indicate selection of a particular item in InputDetail
object. Assign identifier
to the value
property of the InputDetail
object.
+
+
+
+
Declaration
+
+
Swift
+
public let identifier : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Display name of an item.
+
+
+
+
Declaration
+
+
Swift
+
public let name : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Contains a URL to image representation of an item, when applicable.
+
+
+
+
Declaration
+
+
Swift
+
public let imageURL : URL ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/Payment.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/Payment.html
new file mode 100644
index 0000000000..cc9bb48fee
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/Payment.html
@@ -0,0 +1,413 @@
+
+
+
+ Payment Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Payment Class Reference
+
+
+
+
+
+
+
+
+
+
+
Payment
+
+
+
public final class Payment
+
+
+
+
Represents a payment that has been completed by the user. The result of the payment can be retrieved via the status
property.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The status of the payment.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The method that was used to complete the payment.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The payload as returned from the server.
+
+
+
+
Declaration
+
+
Swift
+
public let payload : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The amount of the payment, in minor units.
+
+
+
+
Declaration
+
+
Swift
+
public let amount : Int
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The code of the currency for the payment amount.
+
+
+
+
Declaration
+
+
Swift
+
public let currencyCode : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The reference of the merchant.
+
+
+
+
Declaration
+
+
Swift
+
public let merchantReference : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The reference of the shopper.
+
+
+
+
Declaration
+
+
Swift
+
public let shopperReference : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The country code of the shopper.
+
+
+
+
Declaration
+
+
Swift
+
public let shopperCountryCode : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The locale identifier of the shopper.
+
+
+
+
Declaration
+
+
Swift
+
public let shopperLocaleIdentifier : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/PaymentDetails.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/PaymentDetails.html
new file mode 100644
index 0000000000..87f3aaa067
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/PaymentDetails.html
@@ -0,0 +1,402 @@
+
+
+
+ PaymentDetails Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentDetails Class Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentDetails
+
+
+
public class PaymentDetails
+
+
+
+
Holds the list of InputDetail
needed for the transaction.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Update the detail defined by a given key
with the string value
provided.
+
+
+
+
Declaration
+
+
Swift
+
public func setDetail ( value : String , forKey key : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Update the detail defined by a given key
with the bool value
provided.
+
+
+
+
Declaration
+
+
Swift
+
public func setDetail ( value : Bool ?, forKey key : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the Apple Pay transaction.
+
+
+
+
Declaration
+
+
Swift
+
public func fillApplePay ( token : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the Card transaction with a token.
+
+
+
+
Declaration
+
+
Swift
+
public func fillCard ( token : String , storeDetails : Bool ? = nil )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the Card transaction with CVC.
+
+
+
+
Declaration
+
+
Swift
+
public func fillCard ( cvc : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the iDEAL transaction.
+
+
+
+
Declaration
+
+
Swift
+
public func fillIdeal ( issuerIdentifier : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fill details for the SEPA transaction.
+
+
+
+
Declaration
+
+
Swift
+
public func fillSepa ( name : String , iban : String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/PaymentMethod.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/PaymentMethod.html
new file mode 100644
index 0000000000..f93d8dc812
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/PaymentMethod.html
@@ -0,0 +1,363 @@
+
+
+
+ PaymentMethod Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentMethod Class Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentMethod
+
+
+
public final class PaymentMethod
+
+
+
+
Represents a locale payment method that can be used to complete a payment.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The name of the payment method.
+
+
+
+
Declaration
+
+
Swift
+
public let name : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The payment method type.
+
+
+
+
Declaration
+
+
Swift
+
public let type : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user.
+
+
+
+
Declaration
+
+
Swift
+
public let isOneClick : Bool
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A URL to the logo of the payment method.
+
+
+
+
Declaration
+
+
Swift
+
public let logoURL : URL ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The input details that should be filled in to complete the payment method.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Members of the payment method (only applicable when the receiver is a group).
+
+
+
+
Declaration
+
+
Swift
+
public let members : [ PaymentMethod ]?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user.
+
+
+
+
Declaration
+
+
Swift
+
public var oneClick : Bool
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/PaymentRequest.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/PaymentRequest.html
new file mode 100644
index 0000000000..5763f919a8
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Classes/PaymentRequest.html
@@ -0,0 +1,571 @@
+
+
+
+ PaymentRequest Class Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentRequest Class Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentRequest
+
+
+
public final class PaymentRequest
+
+
+
+
This class is the starting point for Custom Integration .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The selected payment method.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var paymentMethod : PaymentMethod ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Amount to be charged.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var amount : Int ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var currency : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var reference : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Payment country code.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var countryCode : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var shopperLocale : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var shopperReference : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Generation time. Used for generating a token for card payments.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var generationTime : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Public key. Used for generating a token for card payments.
+
+
+
+
Declaration
+
+
Swift
+
public private(set) var publicKey : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Creates a PaymentRequest
object and initialises it with a provided delegate.
+
+
+
+
+
Parameters
+
+
+
+
+
+ delegate
+
+
+
+
+
An object that implements PaymentRequestDelegate
.
+
+
+
+
+
+
+
+
Return Value
+
An initialised instance of the payment request.
+
+
+
+
+
+
+
+
+
+
+
+
Starts the payment request.
+
+
+
+
Declaration
+
+
Swift
+
public func start ()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Permanently deletes payment method from shopper’s preferred payment options.
+
+
+
+
Declaration
+
+
Swift
+
public func deletePreferred ( paymentMethod : PaymentMethod , completion : @escaping ( Bool , Error ?) -> Void )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Cancels the payment request.
+
+
+
+
Declaration
+
+
Swift
+
public func cancel ()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/CardType.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/CardType.html
new file mode 100644
index 0000000000..36d1e16613
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/CardType.html
@@ -0,0 +1,1034 @@
+
+
+
+ CardType Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ CardType Enum Reference
+
+
+
+
+
+
+
+
+
+
+
CardType
+
+
+
public enum CardType : String
+
+
+
+
Enum containing most known types of credit and debit cards.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Alpha Bank Bonus MasterCard
+
+
+
+
Declaration
+
+
Swift
+
case alphaBankBonusMasterCard = "mcalphabankbonus"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Alpha Bank Bonus VISA
+
+
+
+
Declaration
+
+
Swift
+
case alphaBankBonusVISA = "visaalphabankbonus"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case americanExpress = "amex"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case bijenkorfCard = "bijcard"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case carteBancaire = "cartebancaire"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case chinaUnionPay = "cup"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case codensa
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case dankort
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case dankortVISA = "visadankort"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case diners
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case discover
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case hipercard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case karenMillen = "karenmillen"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case maestro
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case maestroUK = "maestrouk"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case masterCard = "mc"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Universal Air Travel Plan
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case unionPay = "unionpay"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case warehouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Array containing all card types in this enum.
+
+
+
+
Declaration
+
+
Swift
+
public static let all = [ masterCard , americanExpress , visa , diners , discover , jcb , elo , hipercard , unionPay , bijenkorfCard , maestroUK , solo , bcmc , dankort , uatp , chinaUnionPay , codensa , alphaBankBonusVISA , dankortVISA , alphaBankBonusMasterCard , hiper , oasis , karenMillen , warehouse , mir , maestro , carteBancaire ]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/Error.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/Error.html
new file mode 100644
index 0000000000..6c79568ebf
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/Error.html
@@ -0,0 +1,382 @@
+
+
+
+ Error Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Error Enum Reference
+
+
+
+
+
+
+
+
+
+
+
Error
+
+
+
public enum Error : Swift . Error
+
+
+
+
Error type.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Error with a message. This enum case is deprecated. Please use serverError
instead.
+
+
+
+
Declaration
+
+
Swift
+
case message ( String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Error returned from server.
+
+
+
+
Declaration
+
+
Swift
+
case serverError ( String )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case networkError ( Swift . Error )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Unexpected data or data format.
+
+
+
+
Declaration
+
+
Swift
+
case unexpectedData
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case unexpectedError
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Payment was canceled.
+
+
+
+
Declaration
+
+
Swift
+
case canceled
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public var errorDescription : String ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/InputType.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/InputType.html
new file mode 100644
index 0000000000..f8c48739fc
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/InputType.html
@@ -0,0 +1,383 @@
+
+
+
+ InputType Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ InputType Enum Reference
+
+
+
+
+
+
+
+
+
+
+
InputType
+
+
+
public enum InputType : String
+
+
+
+
Defines types of payment details.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Boolean input type.
+
+
+
+
Declaration
+
+
Swift
+
case boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Input type should be selected from the given list.
+
+
+
+
Declaration
+
+
Swift
+
case select
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Card token input type.
+
+
+
+
Declaration
+
+
Swift
+
case cardToken
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Apple Pay token input type.
+
+
+
+
Declaration
+
+
Swift
+
case applePayToken
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/PaymentRequestResult.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/PaymentRequestResult.html
new file mode 100644
index 0000000000..472f9b1192
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/PaymentRequestResult.html
@@ -0,0 +1,228 @@
+
+
+
+ PaymentRequestResult Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentRequestResult Enum Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentRequestResult
+
+
+
public enum PaymentRequestResult
+
+
+
+
Result of a payment request.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
In case of success a Payment
object will be returned.
+
+
+
+
Declaration
+
+
Swift
+
case payment ( Payment )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
In case of failure an Error
will be returned.
+
+
+
+
Declaration
+
+
Swift
+
case error ( Error )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/PaymentStatus.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/PaymentStatus.html
new file mode 100644
index 0000000000..62fdd52ea7
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Enums/PaymentStatus.html
@@ -0,0 +1,321 @@
+
+
+
+ PaymentStatus Enum Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentStatus Enum Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentStatus
+
+
+
public enum PaymentStatus : String
+
+
+
+
Payment statuses.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case received
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Payment authorised.
+
+
+
+
Declaration
+
+
Swift
+
case authorised
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case refused
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
case cancelled
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Payment Method.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Payment Method.html
new file mode 100644
index 0000000000..4dc7198b56
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Payment Method.html
@@ -0,0 +1,321 @@
+
+
+
+ Payment Method Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Payment Method Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Represents a locale payment method that can be used to complete a payment.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class PaymentMethod
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public class PaymentDetails
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The payment detail needed for the transaction.
+The detail has a type
(InputType
). If type
is .select
, a list of InputSelectItem
will be available for selection in the items
variable.
+The detail might be optional
.
+The detail value can be set as a string (stringValue
) or a bool value (boolValue
).
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public class InputDetail
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Defines types of payment details.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public enum InputType : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public final class InputSelectItem
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Payment Request.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Payment Request.html
new file mode 100644
index 0000000000..4d9da63fd8
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Payment Request.html
@@ -0,0 +1,286 @@
+
+
+
+ Payment Request Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Payment Request Reference
+
+
+
+
+
+
+
+
+
+
+
Payment Request
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public final class PaymentRequest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The payment request delegate. Used for Custom integration comunication. All delegate methods are invoked on the main thread.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public protocol PaymentRequestDelegate : class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Result of a payment request.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public enum PaymentRequestResult
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public enum Error : Swift . Error
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Payment.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Payment.html
new file mode 100644
index 0000000000..9d42acfdac
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Payment.html
@@ -0,0 +1,222 @@
+
+
+
+ Payment Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Payment Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Represents a payment that has been completed by the user. The result of the payment can be retrieved via the status
property.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class Payment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Declaration
+
+
Swift
+
public enum PaymentStatus : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Protocols/CheckoutViewControllerDelegate.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Protocols/CheckoutViewControllerDelegate.html
new file mode 100644
index 0000000000..f810b4d4eb
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Protocols/CheckoutViewControllerDelegate.html
@@ -0,0 +1,356 @@
+
+
+
+ CheckoutViewControllerDelegate Protocol Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ CheckoutViewControllerDelegate Protocol Reference
+
+
+
+
+
+
+
+
+
+
+
CheckoutViewControllerDelegate
+
+
+
public protocol CheckoutViewControllerDelegate : class
+
+
+
+
The CheckoutViewControllerDelegate
protocol defines the methods that a delegate of CheckoutViewController
should implement to provide payment data and be informed of the payment flow progress.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Invoked when the payment flow has started and payment data is requested from the merchant server.
+
+
+
+
Declaration
+
+
Swift
+
func checkoutViewController ( _ controller : CheckoutViewController , requiresPaymentDataForToken token : String , completion : @escaping DataCompletion )
+
+
+
+
+
Parameters
+
+
+
+
+
+ controller
+
+
+
+
+
The checkout view controller that has started the payment flow.
+
+
+
+
+
+
+ token
+
+
+
+
+
The token assigned to the payment flow.
+
+
+
+
+
+
+ completion
+
+
+
+
+
The completion handler to invoke when the payment data is retrieved from the merchant server.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Invoked when the redirection to a URL has been made. The given completion handler should be invoked when the user returns to the application through a URL.
+
+
+
+
Declaration
+
+
Swift
+
func checkoutViewController ( _ controller : CheckoutViewController , requiresReturnURL completion : @escaping URLCompletion )
+
+
+
+
+
Parameters
+
+
+
+
+
+ controller
+
+
+
+
+
The checkout view controller which requested the return from a URL redirection.
+
+
+
+
+
+
+ completion
+
+
+
+
+
The completion handler to invoke when the user returns to the application through a URL.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Invoked when the payment flow has finished.
+
+
+
+
+
Parameters
+
+
+
+
+
+ controller
+
+
+
+
+
The checkout view controller that finished the payment flow.
+
+
+
+
+
+
+ result
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Protocols/PaymentRequestDelegate.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Protocols/PaymentRequestDelegate.html
new file mode 100644
index 0000000000..76d5cc82eb
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Protocols/PaymentRequestDelegate.html
@@ -0,0 +1,305 @@
+
+
+
+ PaymentRequestDelegate Protocol Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ PaymentRequestDelegate Protocol Reference
+
+
+
+
+
+
+
+
+
+
+
PaymentRequestDelegate
+
+
+
public protocol PaymentRequestDelegate : class
+
+
+
+
The payment request delegate. Used for Custom integration comunication. All delegate methods are invoked on the main thread.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Given the PaymentRequest
that started the payment flow and token
, waits for data from merchant server to be passed via completion
.
+
+
+
+
Declaration
+
+
Swift
+
func paymentRequest ( _ request : PaymentRequest , requiresPaymentDataForToken token : String , completion : @escaping DataCompletion )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Given a list of PaymentMethod
(available and preferred) waits for the selection via completion
.
+
+
+
+
Declaration
+
+
Swift
+
func paymentRequest ( _ request : PaymentRequest , requiresPaymentMethodFrom preferredMethods : [ PaymentMethod ]?, available availableMethods : [ PaymentMethod ], completion : @escaping MethodCompletion )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This method is called when a URL redirection needs to be executed. Use the url
to continue payment flow in Safari or SFSafariViewController
. After the process is completed, the completion
for the given URL must be called.
+
+
+
+
Declaration
+
+
Swift
+
func paymentRequest ( _ request : PaymentRequest , requiresReturnURLFrom url : URL , completion : @escaping URLCompletion )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This method is called when input is needed for completing the transation. The filled PaymentDetails
should be sent via completion
.
+
+
+
+
Declaration
+
+
Swift
+
func paymentRequest ( _ request : PaymentRequest , requiresPaymentDetails details : PaymentDetails , completion : @escaping PaymentDetailsCompletion )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This method is called when the payment flow is finished.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Structs/IBANSpecification.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Structs/IBANSpecification.html
new file mode 100644
index 0000000000..5e893dc146
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Structs/IBANSpecification.html
@@ -0,0 +1,324 @@
+
+
+
+ IBANSpecification Struct Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ IBANSpecification Struct Reference
+
+
+
+
+
+
+
+
+
+
+
IBANSpecification
+
+
+
public struct IBANSpecification
+
+
+
+
Contains the country-specific specifications for countries that adopt the IBAN standard.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The code of the country to which the specifications apply.
+
+
+
+
Declaration
+
+
Swift
+
public let countryCode : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The length of a valid IBAN.
+
+
+
+
Declaration
+
+
Swift
+
public let length : Int
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The structure of the underlying BBAN.
+
+
+
+
Declaration
+
+
Swift
+
public let structure : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
An example of a valid IBAN.
+
+
+
+
Declaration
+
+
Swift
+
public let example : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Returns the IBAN specification for the country with the given code, or nil
if none could be found.
+
+
+
+
Declaration
+
+
Swift
+
public init ?( forCountryCode countryCode : String )
+
+
+
+
+
Parameters
+
+
+
+
+
+ countryCode
+
+
+
+
+
The code of the country to retrieve the IBAN specification for.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/UI.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/UI.html
new file mode 100644
index 0000000000..2492967c11
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/UI.html
@@ -0,0 +1,255 @@
+
+
+
+ UI Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ UI Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The starting point for Quick integration . Initialize with CheckoutViewContollerDelegate
and present this view controller in your app to start the payment flow. If you don’t embed the CheckoutViewController
in an existing UINavigationController
, a new one will be created automatically.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class CheckoutViewController : UIViewController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The CheckoutViewControllerDelegate
protocol defines the methods that a delegate of CheckoutViewController
should implement to provide payment data and be informed of the payment flow progress.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public protocol CheckoutViewControllerDelegate : class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Provides properties to customize the appearance of the UI components provided by this library.
+Note that AppearanceConfiguration
is only used when the CheckoutViewController
is first initialized. Changes to this object after it has been created are ignored.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class AppearanceConfiguration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Utilities.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Utilities.html
new file mode 100644
index 0000000000..f6e25ff985
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/Utilities.html
@@ -0,0 +1,318 @@
+
+
+
+ Utilities Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Utilities Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Enum containing most known types of credit and debit cards.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public enum CardType : String
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The CardValidator class provides static methods to validate and format card numbers and expiry dates, and to detect card types.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public final class CardValidator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Contains the country-specific specifications for countries that adopt the IBAN standard.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public struct IBANSpecification
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Provides a static method to validate an IBAN value.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public class IBANValidator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Provides a text field designed for the entry of an IBAN value. This field formats and validates the IBAN in real time.
+
+
See more
+
+
+
Declaration
+
+
Swift
+
public class IBANTextField : UITextField
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/css/highlight.css b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/css/highlight.css
new file mode 100644
index 0000000000..d0db0e13b0
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/css/highlight.css
@@ -0,0 +1,200 @@
+/* Credit to https://gist.github.com/wataru420/2048287 */
+.highlight {
+ /* Comment */
+ /* Error */
+ /* Keyword */
+ /* Operator */
+ /* Comment.Multiline */
+ /* Comment.Preproc */
+ /* Comment.Single */
+ /* Comment.Special */
+ /* Generic.Deleted */
+ /* Generic.Deleted.Specific */
+ /* Generic.Emph */
+ /* Generic.Error */
+ /* Generic.Heading */
+ /* Generic.Inserted */
+ /* Generic.Inserted.Specific */
+ /* Generic.Output */
+ /* Generic.Prompt */
+ /* Generic.Strong */
+ /* Generic.Subheading */
+ /* Generic.Traceback */
+ /* Keyword.Constant */
+ /* Keyword.Declaration */
+ /* Keyword.Pseudo */
+ /* Keyword.Reserved */
+ /* Keyword.Type */
+ /* Literal.Number */
+ /* Literal.String */
+ /* Name.Attribute */
+ /* Name.Builtin */
+ /* Name.Class */
+ /* Name.Constant */
+ /* Name.Entity */
+ /* Name.Exception */
+ /* Name.Function */
+ /* Name.Namespace */
+ /* Name.Tag */
+ /* Name.Variable */
+ /* Operator.Word */
+ /* Text.Whitespace */
+ /* Literal.Number.Float */
+ /* Literal.Number.Hex */
+ /* Literal.Number.Integer */
+ /* Literal.Number.Oct */
+ /* Literal.String.Backtick */
+ /* Literal.String.Char */
+ /* Literal.String.Doc */
+ /* Literal.String.Double */
+ /* Literal.String.Escape */
+ /* Literal.String.Heredoc */
+ /* Literal.String.Interpol */
+ /* Literal.String.Other */
+ /* Literal.String.Regex */
+ /* Literal.String.Single */
+ /* Literal.String.Symbol */
+ /* Name.Builtin.Pseudo */
+ /* Name.Variable.Class */
+ /* Name.Variable.Global */
+ /* Name.Variable.Instance */
+ /* Literal.Number.Integer.Long */ }
+ .highlight .c {
+ color: #999988;
+ font-style: italic; }
+ .highlight .err {
+ color: #a61717;
+ background-color: #e3d2d2; }
+ .highlight .k {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .o {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .cm {
+ color: #999988;
+ font-style: italic; }
+ .highlight .cp {
+ color: #999999;
+ font-weight: bold; }
+ .highlight .c1 {
+ color: #999988;
+ font-style: italic; }
+ .highlight .cs {
+ color: #999999;
+ font-weight: bold;
+ font-style: italic; }
+ .highlight .gd {
+ color: #000000;
+ background-color: #ffdddd; }
+ .highlight .gd .x {
+ color: #000000;
+ background-color: #ffaaaa; }
+ .highlight .ge {
+ color: #000000;
+ font-style: italic; }
+ .highlight .gr {
+ color: #aa0000; }
+ .highlight .gh {
+ color: #999999; }
+ .highlight .gi {
+ color: #000000;
+ background-color: #ddffdd; }
+ .highlight .gi .x {
+ color: #000000;
+ background-color: #aaffaa; }
+ .highlight .go {
+ color: #888888; }
+ .highlight .gp {
+ color: #555555; }
+ .highlight .gs {
+ font-weight: bold; }
+ .highlight .gu {
+ color: #aaaaaa; }
+ .highlight .gt {
+ color: #aa0000; }
+ .highlight .kc {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .kd {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .kp {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .kr {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .kt {
+ color: #445588; }
+ .highlight .m {
+ color: #009999; }
+ .highlight .s {
+ color: #d14; }
+ .highlight .na {
+ color: #008080; }
+ .highlight .nb {
+ color: #0086B3; }
+ .highlight .nc {
+ color: #445588;
+ font-weight: bold; }
+ .highlight .no {
+ color: #008080; }
+ .highlight .ni {
+ color: #800080; }
+ .highlight .ne {
+ color: #990000;
+ font-weight: bold; }
+ .highlight .nf {
+ color: #990000; }
+ .highlight .nn {
+ color: #555555; }
+ .highlight .nt {
+ color: #000080; }
+ .highlight .nv {
+ color: #008080; }
+ .highlight .ow {
+ color: #000000;
+ font-weight: bold; }
+ .highlight .w {
+ color: #bbbbbb; }
+ .highlight .mf {
+ color: #009999; }
+ .highlight .mh {
+ color: #009999; }
+ .highlight .mi {
+ color: #009999; }
+ .highlight .mo {
+ color: #009999; }
+ .highlight .sb {
+ color: #d14; }
+ .highlight .sc {
+ color: #d14; }
+ .highlight .sd {
+ color: #d14; }
+ .highlight .s2 {
+ color: #d14; }
+ .highlight .se {
+ color: #d14; }
+ .highlight .sh {
+ color: #d14; }
+ .highlight .si {
+ color: #d14; }
+ .highlight .sx {
+ color: #d14; }
+ .highlight .sr {
+ color: #009926; }
+ .highlight .s1 {
+ color: #d14; }
+ .highlight .ss {
+ color: #990073; }
+ .highlight .bp {
+ color: #999999; }
+ .highlight .vc {
+ color: #008080; }
+ .highlight .vg {
+ color: #008080; }
+ .highlight .vi {
+ color: #008080; }
+ .highlight .il {
+ color: #009999; }
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/css/jazzy.css b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/css/jazzy.css
new file mode 100644
index 0000000000..c83db5bfc5
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/css/jazzy.css
@@ -0,0 +1,368 @@
+*, *:before, *:after {
+ box-sizing: inherit; }
+
+body {
+ margin: 0;
+ background: #fff;
+ color: #333;
+ font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
+ letter-spacing: .2px;
+ -webkit-font-smoothing: antialiased;
+ box-sizing: border-box; }
+
+h1 {
+ font-size: 2rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.6em; }
+
+h2 {
+ font-size: 1.75rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.3em; }
+
+h3 {
+ font-size: 1.5rem;
+ font-weight: 700;
+ margin: 1em 0 0.3em; }
+
+h4 {
+ font-size: 1.25rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.85em; }
+
+h5 {
+ font-size: 1rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.85em; }
+
+h6 {
+ font-size: 1rem;
+ font-weight: 700;
+ margin: 1.275em 0 0.85em;
+ color: #777; }
+
+p {
+ margin: 0 0 1em; }
+
+ul, ol {
+ padding: 0 0 0 2em;
+ margin: 0 0 0.85em; }
+
+blockquote {
+ margin: 0 0 0.85em;
+ padding: 0 15px;
+ color: #858585;
+ border-left: 4px solid #e5e5e5; }
+
+img {
+ max-width: 100%; }
+
+a {
+ color: #4183c4;
+ text-decoration: none; }
+ a:hover, a:focus {
+ outline: 0;
+ text-decoration: underline; }
+
+table {
+ background: #fff;
+ width: 100%;
+ border-collapse: collapse;
+ border-spacing: 0;
+ overflow: auto;
+ margin: 0 0 0.85em; }
+
+tr:nth-child(2n) {
+ background-color: #fbfbfb; }
+
+th, td {
+ padding: 6px 13px;
+ border: 1px solid #ddd; }
+
+pre {
+ margin: 0 0 1.275em;
+ padding: .85em 1em;
+ overflow: auto;
+ background: #f7f7f7;
+ font-size: .85em;
+ font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
+
+code {
+ font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
+
+p > code, li > code {
+ background: #f7f7f7;
+ padding: .2em; }
+ p > code:before, p > code:after, li > code:before, li > code:after {
+ letter-spacing: -.2em;
+ content: "\00a0"; }
+
+pre code {
+ padding: 0;
+ white-space: pre; }
+
+.content-wrapper {
+ display: flex;
+ flex-direction: column; }
+ @media (min-width: 768px) {
+ .content-wrapper {
+ flex-direction: row; } }
+
+.header {
+ display: flex;
+ padding: 8px;
+ font-size: 0.875em;
+ background: #444;
+ color: #999; }
+
+.header-col {
+ margin: 0;
+ padding: 0 8px; }
+
+.header-col--primary {
+ flex: 1; }
+
+.header-link {
+ color: #fff; }
+
+.header-icon {
+ padding-right: 6px;
+ vertical-align: -4px;
+ height: 16px; }
+
+.breadcrumbs {
+ font-size: 0.875em;
+ padding: 8px 16px;
+ margin: 0;
+ background: #fbfbfb;
+ border-bottom: 1px solid #ddd; }
+
+.carat {
+ height: 10px;
+ margin: 0 5px; }
+
+.navigation {
+ order: 2; }
+ @media (min-width: 768px) {
+ .navigation {
+ order: 1;
+ width: 25%;
+ max-width: 300px;
+ padding-bottom: 64px;
+ overflow: hidden;
+ word-wrap: normal;
+ background: #fbfbfb;
+ border-right: 1px solid #ddd; } }
+
+.nav-groups {
+ list-style-type: none;
+ padding-left: 0; }
+
+.nav-group-name {
+ border-bottom: 1px solid #ddd;
+ padding: 8px 0 8px 16px; }
+
+.nav-group-name-link {
+ color: #333; }
+
+.nav-group-tasks {
+ margin: 8px 0;
+ padding: 0 0 0 8px; }
+
+.nav-group-task {
+ font-size: 1em;
+ list-style-type: none;
+ white-space: nowrap; }
+
+.nav-group-task-link {
+ color: #808080; }
+
+.main-content {
+ order: 1; }
+ @media (min-width: 768px) {
+ .main-content {
+ order: 2;
+ flex: 1;
+ padding-bottom: 60px; } }
+
+.section {
+ padding: 0 32px;
+ border-bottom: 1px solid #ddd; }
+
+.section-content {
+ max-width: 834px;
+ margin: 0 auto;
+ padding: 16px 0; }
+
+.section-name {
+ color: #666;
+ display: block; }
+
+.declaration .highlight {
+ overflow-x: initial;
+ padding: 8px 0;
+ margin: 0;
+ background-color: transparent;
+ border: none; }
+
+.task-group-section {
+ border-top: 1px solid #ddd; }
+
+.task-group {
+ padding-top: 0px; }
+
+.task-name-container a[name]:before {
+ content: "";
+ display: block; }
+
+.item-container {
+ padding: 0; }
+
+.item {
+ padding-top: 8px;
+ width: 100%;
+ list-style-type: none; }
+ .item a[name]:before {
+ content: "";
+ display: block; }
+ .item .token {
+ padding-left: 3px;
+ margin-left: 0px;
+ font-size: 1rem; }
+ .item .declaration-note {
+ font-size: .85em;
+ color: #808080;
+ font-style: italic; }
+
+.pointer-container {
+ border-bottom: 1px solid #ddd;
+ left: -23px;
+ padding-bottom: 13px;
+ position: relative;
+ width: 110%; }
+
+.pointer {
+ left: 21px;
+ top: 7px;
+ display: block;
+ position: absolute;
+ width: 12px;
+ height: 12px;
+ border-left: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+ background: #fff;
+ transform: rotate(45deg); }
+
+.height-container {
+ display: none;
+ position: relative;
+ width: 100%;
+ overflow: hidden; }
+ .height-container .section {
+ background: #fff;
+ border: 1px solid #ddd;
+ border-top-width: 0;
+ padding-top: 10px;
+ padding-bottom: 5px;
+ padding: 8px 16px; }
+
+.aside, .language {
+ padding: 6px 12px;
+ margin: 12px 0;
+ border-left: 5px solid #dddddd;
+ overflow-y: hidden; }
+ .aside .aside-title, .language .aside-title {
+ font-size: 9px;
+ letter-spacing: 2px;
+ text-transform: uppercase;
+ padding-bottom: 0;
+ margin: 0;
+ color: #aaa;
+ -webkit-user-select: none; }
+ .aside p:last-child, .language p:last-child {
+ margin-bottom: 0; }
+
+.language {
+ border-left: 5px solid #cde9f4; }
+ .language .aside-title {
+ color: #4183c4; }
+
+.aside-warning {
+ border-left: 5px solid #ff6666; }
+ .aside-warning .aside-title {
+ color: #ff0000; }
+
+.graybox {
+ border-collapse: collapse;
+ width: 100%; }
+ .graybox p {
+ margin: 0;
+ word-break: break-word;
+ min-width: 50px; }
+ .graybox td {
+ border: 1px solid #ddd;
+ padding: 5px 25px 5px 10px;
+ vertical-align: middle; }
+ .graybox tr td:first-of-type {
+ text-align: right;
+ padding: 7px;
+ vertical-align: top;
+ word-break: normal;
+ width: 40px; }
+
+.slightly-smaller {
+ font-size: 0.9em; }
+
+.footer {
+ padding: 8px 16px;
+ background: #444;
+ color: #ddd;
+ font-size: 0.8em; }
+ .footer p {
+ margin: 8px 0; }
+ .footer a {
+ color: #fff; }
+
+html.dash .header, html.dash .breadcrumbs, html.dash .navigation {
+ display: none; }
+html.dash .height-container {
+ display: block; }
+
+form[role=search] input {
+ font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 24px;
+ padding: 0 10px;
+ margin: 0;
+ border: none;
+ border-radius: 1em; }
+ .loading form[role=search] input {
+ background: white url(../img/spinner.gif) center right 4px no-repeat; }
+form[role=search] .tt-menu {
+ margin: 0;
+ min-width: 300px;
+ background: #fbfbfb;
+ color: #333;
+ border: 1px solid #ddd; }
+form[role=search] .tt-highlight {
+ font-weight: bold; }
+form[role=search] .tt-suggestion {
+ font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
+ padding: 0 8px; }
+ form[role=search] .tt-suggestion span {
+ display: table-cell;
+ white-space: nowrap; }
+ form[role=search] .tt-suggestion .doc-parent-name {
+ width: 100%;
+ text-align: right;
+ font-weight: normal;
+ font-size: 0.9em;
+ padding-left: 16px; }
+form[role=search] .tt-suggestion:hover,
+form[role=search] .tt-suggestion.tt-cursor {
+ cursor: pointer;
+ background-color: #4183c4;
+ color: #fff; }
+form[role=search] .tt-suggestion:hover .doc-parent-name,
+form[role=search] .tt-suggestion.tt-cursor .doc-parent-name {
+ color: #fff; }
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/carat.png b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/carat.png
new file mode 100755
index 0000000000..29d2f7fd49
Binary files /dev/null and b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/carat.png differ
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/dash.png b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/dash.png
new file mode 100755
index 0000000000..6f694c7a01
Binary files /dev/null and b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/dash.png differ
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/gh.png b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/gh.png
new file mode 100755
index 0000000000..628da97c70
Binary files /dev/null and b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/gh.png differ
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/spinner.gif b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/spinner.gif
new file mode 100644
index 0000000000..e3038d0a42
Binary files /dev/null and b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/img/spinner.gif differ
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/index.html b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/index.html
new file mode 100644
index 0000000000..ac506ead4e
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/index.html
@@ -0,0 +1,208 @@
+
+
+
+ Adyen Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Adyen Reference
+
+
+
+
+
+
+
+
+
+
+
+
Adyen SDK for iOS
+
+
With Adyen SDK you can help your shoppers pay with a payment method of their choice, selected from a dynamically generated list of available payment methods. Method availability is based on shoppers’ location, transaction currency, and transaction amount.
+
+
You can integrate the SDK in two ways: either make use of the default UI components and flows preconfigured by Adyen (Quick integration), or implement your own UI and checkout experience (Custom integration).
+
+
+
Installation
+
+
Use CocoaPods to integrate the Adyen SDK into your project. For this, add the following line to your Podfile and run pod install
.
+
pod 'Adyen'
+
+
Quick integration
+
+
If you want to quickly integrate with Adyen, use the default UI elements that we provide for selecting payment methods, entering payment details, and completing a payment.
+
+
For this, instantiate CheckoutViewController
, present it in your app, and implement the CheckoutViewControllerDelegate
protocol for callbacks. All UI interactions are handled by Adyen.
+
let viewController = CheckoutViewController ( delegate : self )
+present ( viewController ! , animated : true )
+
+
+
The following CheckoutViewControllerDelegate
methods should be implemented:
+
- checkoutViewController:requiresPaymentDataForToken:completion:
+
+
This method requires you to fetch payment data from your server and pass it to the completion
handler. Upon receiving valid payment data, the SDK will present a list of available payment methods.
+
+
For your convenience, we provide a test merchant server . You can find information on setting up your own server here .
+
- checkoutViewController:requiresReturnURL:
+
+
This method will be called if a selected payment method requires user authentication outside of your app environment (in a web browser, native banking app, etc.). Upon payment authorisation, your app will be reopened using the application(_:open:options:)
callback of UIApplicationDelegate
. The URL used to open your app should be passed to the completion handler.
+
- checkoutViewController:didFinishWith:
+
+
This method will provide you with the result of the completed payment request (authorised, refused, etc.).
+
+
For implementation details, refer to the Quick integration guide .
+
Custom integration
+
+
With custom integration you will have full control over the payment flow and will be able to implement your own unique checkout experience.
+
+
This approach requires instantiating and starting a PaymentRequest
and implementing the PaymentRequestDelegate
protocol for callbacks. The PaymentRequestDelegate
callbacks will provide you with a list of available payment methods, the URL for payment methods that require an external flow, and the result of payment processing.
+
+
For implementation details, refer to the Custom integration guide .
+
Examples
+
+
You can find examples of both quick and custom integrations in the Examples folder of this repository.
+
See also
+
+
+
License
+
+
This repository is open source and available under the MIT license. For more information, see the LICENSE file.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/jazzy.js b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/jazzy.js
new file mode 100755
index 0000000000..009c80d387
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/jazzy.js
@@ -0,0 +1,43 @@
+window.jazzy = {'docset': false}
+if (typeof window.dash != 'undefined') {
+ document.documentElement.className += ' dash'
+ window.jazzy.docset = true
+}
+if (navigator.userAgent.match(/xcode/i)) {
+ document.documentElement.className += ' xcode'
+ window.jazzy.docset = true
+}
+
+// On doc load, toggle the URL hash discussion if present
+$(document).ready(function() {
+ if (!window.jazzy.docset) {
+ var linkToHash = $('a[href="' + window.location.hash +'"]');
+ linkToHash.trigger("click");
+ }
+});
+
+// On token click, toggle its discussion and animate token.marginLeft
+$(".token").click(function(event) {
+ if (window.jazzy.docset) {
+ return;
+ }
+ var link = $(this);
+ var animationDuration = 300;
+ $content = link.parent().parent().next();
+ $content.slideToggle(animationDuration);
+
+ // Keeps the document from jumping to the hash.
+ var href = $(this).attr('href');
+ if (history.pushState) {
+ history.pushState({}, '', href);
+ } else {
+ location.hash = href;
+ }
+ event.preventDefault();
+});
+
+// Dumb down quotes within code blocks that delimit strings instead of quotations
+// https://github.com/realm/jazzy/issues/714
+$("code q").replaceWith(function () {
+ return ["\"", $(this).contents(), "\""];
+});
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/jazzy.search.js b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/jazzy.search.js
new file mode 100644
index 0000000000..54be83cf71
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/jazzy.search.js
@@ -0,0 +1,62 @@
+$(function(){
+ var searchIndex = lunr(function() {
+ this.ref('url');
+ this.field('name');
+ });
+
+ var $typeahead = $('[data-typeahead]');
+ var $form = $typeahead.parents('form');
+ var searchURL = $form.attr('action');
+
+ function displayTemplate(result) {
+ return result.name;
+ }
+
+ function suggestionTemplate(result) {
+ var t = '';
+ t += '' + result.name + ' ';
+ if (result.parent_name) {
+ t += '' + result.parent_name + ' ';
+ }
+ t += '
';
+ return t;
+ }
+
+ $typeahead.one('focus', function() {
+ $form.addClass('loading');
+
+ $.getJSON(searchURL).then(function(searchData) {
+ $.each(searchData, function (url, doc) {
+ searchIndex.add({url: url, name: doc.name});
+ });
+
+ $typeahead.typeahead(
+ {
+ highlight: true,
+ minLength: 3
+ },
+ {
+ limit: 10,
+ display: displayTemplate,
+ templates: { suggestion: suggestionTemplate },
+ source: function(query, sync) {
+ var results = searchIndex.search(query).map(function(result) {
+ var doc = searchData[result.ref];
+ doc.url = result.ref;
+ return doc;
+ });
+ sync(results);
+ }
+ }
+ );
+ $form.removeClass('loading');
+ $typeahead.trigger('focus');
+ });
+ });
+
+ var baseURL = searchURL.slice(0, -"search.json".length);
+
+ $typeahead.on('typeahead:select', function(e, result) {
+ window.location = baseURL + result.url;
+ });
+});
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/jquery.min.js b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/jquery.min.js
new file mode 100755
index 0000000000..ab28a24729
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/jquery.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML=" ",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
+if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" a ",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML=" ",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h ]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""," "],legend:[1,""," "],area:[1,""," "],param:[1,""," "],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:k.htmlSerialize?[0,"",""]:[1,"X","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" a ",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
+},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();ca ",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.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(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/lunr.min.js b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/lunr.min.js
new file mode 100755
index 0000000000..22776bb85e
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/js/lunr.min.js
@@ -0,0 +1,6 @@
+/**
+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.7.2
+ * Copyright (C) 2016 Oliver Nightingale
+ * @license MIT
+ */
+!function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.7.2",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){if(!arguments.length||null==e||void 0==e)return[];if(Array.isArray(e))return e.map(function(e){return t.utils.asString(e).toLowerCase()});var n=t.tokenizer.seperator||t.tokenizer.separator;return e.toString().trim().toLowerCase().split(n)},t.tokenizer.seperator=!1,t.tokenizer.separator=/[\s\-]+/,t.tokenizer.load=function(t){var e=this.registeredFunctions[t];if(!e)throw new Error("Cannot load un-registered function: "+t);return e},t.tokenizer.label="default",t.tokenizer.registeredFunctions={"default":t.tokenizer},t.tokenizer.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing tokenizer: "+n),e.label=n,this.registeredFunctions[n]=e},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,r=0;n>r;r++){for(var o=t[r],s=0;i>s&&(o=this._stack[s](o,r,t),void 0!==o&&""!==o);s++);void 0!==o&&""!==o&&e.push(o)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(e
n.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(o===t)return r;t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r]}return o===t?r:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,r=e+Math.floor(i/2),o=this.elements[r];i>1;)t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r];return o>t?r:t>o?r+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,r=0,o=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>o-1||r>s-1)break;a[i]!==h[r]?a[i]h[r]&&r++:(n.add(a[i]),i++,r++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone();for(var r=0,o=n.toArray();rp;p++)c[p]===a&&d++;h+=d/f*l.boost}}this.tokenStore.add(a,{ref:o,tf:h})}n&&this.eventEmitter.emit("add",e,this)},t.Index.prototype.remove=function(t,e){var n=t[this._ref],e=void 0===e?!0:e;if(this.documentStore.has(n)){var i=this.documentStore.get(n);this.documentStore.remove(n),i.forEach(function(t){this.tokenStore.remove(t,n)},this),e&&this.eventEmitter.emit("remove",t,this)}},t.Index.prototype.update=function(t,e){var e=void 0===e?!0:e;this.remove(t,!1),this.add(t,!1),e&&this.eventEmitter.emit("update",t,this)},t.Index.prototype.idf=function(t){var e="@"+t;if(Object.prototype.hasOwnProperty.call(this._idfCache,e))return this._idfCache[e];var n=this.tokenStore.count(t),i=1;return n>0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(this.tokenizerFn(e)),i=new t.Vector,r=[],o=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*o,h=this,u=this.tokenStore.expand(e).reduce(function(n,r){var o=h.corpusTokens.indexOf(r),s=h.idf(r),u=1,l=new t.SortedSet;if(r!==e){var c=Math.max(3,r.length-e.length);u=1/Math.log(c)}o>-1&&i.insert(o,a*s*u);for(var f=h.tokenStore.get(r),d=Object.keys(f),p=d.length,v=0;p>v;v++)l.add(f[d[v]].ref);return n.union(l)},new t.SortedSet);r.push(u)},this);var a=r.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,r=new t.Vector,o=0;i>o;o++){var s=n.elements[o],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);r.insert(this.corpusTokens.indexOf(s),a*h)}return r},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,tokenizer:this.tokenizerFn.label,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",r=n+"[^aeiouy]*",o=i+"[aeiou]*",s="^("+r+")?"+o+r,a="^("+r+")?"+o+r+"("+o+")?$",h="^("+r+")?"+o+r+o+r,u="^("+r+")?"+i,l=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(u),p=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,g=/^(.+?)eed$/,m=/^(.+?)(ed|ing)$/,y=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),k=new RegExp("^"+r+i+"[^aeiouwxy]$"),x=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,F=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,_=/^(.+?)(s|t)(ion)$/,z=/^(.+?)e$/,O=/ll$/,P=new RegExp("^"+r+i+"[^aeiouwxy]$"),T=function(n){var i,r,o,s,a,h,u;if(n.length<3)return n;if(o=n.substr(0,1),"y"==o&&(n=o.toUpperCase()+n.substr(1)),s=p,a=v,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=g,a=m,s.test(n)){var T=s.exec(n);s=l,s.test(T[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,u=k,a.test(n)?n+="e":h.test(n)?(s=y,n=n.replace(s,"")):u.test(n)&&(n+="e"))}if(s=x,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+t[r])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+e[r])}if(s=F,a=_,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=z,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=P,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=O,a=c,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==o&&(n=o.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.generateStopWordFilter=function(t){var e=t.reduce(function(t,e){return t[e]=e,t},{});return function(t){return t&&e[t]!==t?t:void 0}},t.stopWordFilter=t.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){return t.replace(/^\W+/,"").replace(/\W+$/,"")},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t.charAt(0),r=t.slice(1);return i in n||(n[i]={docs:{}}),0===r.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(r,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n',
+ menu: ''
+ };
+ }
+ function buildSelectors(classes) {
+ var selectors = {};
+ _.each(classes, function(v, k) {
+ selectors[k] = "." + v;
+ });
+ return selectors;
+ }
+ function buildCss() {
+ var css = {
+ wrapper: {
+ position: "relative",
+ display: "inline-block"
+ },
+ hint: {
+ position: "absolute",
+ top: "0",
+ left: "0",
+ borderColor: "transparent",
+ boxShadow: "none",
+ opacity: "1"
+ },
+ input: {
+ position: "relative",
+ verticalAlign: "top",
+ backgroundColor: "transparent"
+ },
+ inputWithNoHint: {
+ position: "relative",
+ verticalAlign: "top"
+ },
+ menu: {
+ position: "absolute",
+ top: "100%",
+ left: "0",
+ zIndex: "100",
+ display: "none"
+ },
+ ltr: {
+ left: "0",
+ right: "auto"
+ },
+ rtl: {
+ left: "auto",
+ right: " 0"
+ }
+ };
+ if (_.isMsie()) {
+ _.mixin(css.input, {
+ backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
+ });
+ }
+ return css;
+ }
+ }();
+ var EventBus = function() {
+ "use strict";
+ var namespace, deprecationMap;
+ namespace = "typeahead:";
+ deprecationMap = {
+ render: "rendered",
+ cursorchange: "cursorchanged",
+ select: "selected",
+ autocomplete: "autocompleted"
+ };
+ function EventBus(o) {
+ if (!o || !o.el) {
+ $.error("EventBus initialized without el");
+ }
+ this.$el = $(o.el);
+ }
+ _.mixin(EventBus.prototype, {
+ _trigger: function(type, args) {
+ var $e;
+ $e = $.Event(namespace + type);
+ (args = args || []).unshift($e);
+ this.$el.trigger.apply(this.$el, args);
+ return $e;
+ },
+ before: function(type) {
+ var args, $e;
+ args = [].slice.call(arguments, 1);
+ $e = this._trigger("before" + type, args);
+ return $e.isDefaultPrevented();
+ },
+ trigger: function(type) {
+ var deprecatedType;
+ this._trigger(type, [].slice.call(arguments, 1));
+ if (deprecatedType = deprecationMap[type]) {
+ this._trigger(deprecatedType, [].slice.call(arguments, 1));
+ }
+ }
+ });
+ return EventBus;
+ }();
+ var EventEmitter = function() {
+ "use strict";
+ var splitter = /\s+/, nextTick = getNextTick();
+ return {
+ onSync: onSync,
+ onAsync: onAsync,
+ off: off,
+ trigger: trigger
+ };
+ function on(method, types, cb, context) {
+ var type;
+ if (!cb) {
+ return this;
+ }
+ types = types.split(splitter);
+ cb = context ? bindContext(cb, context) : cb;
+ this._callbacks = this._callbacks || {};
+ while (type = types.shift()) {
+ this._callbacks[type] = this._callbacks[type] || {
+ sync: [],
+ async: []
+ };
+ this._callbacks[type][method].push(cb);
+ }
+ return this;
+ }
+ function onAsync(types, cb, context) {
+ return on.call(this, "async", types, cb, context);
+ }
+ function onSync(types, cb, context) {
+ return on.call(this, "sync", types, cb, context);
+ }
+ function off(types) {
+ var type;
+ if (!this._callbacks) {
+ return this;
+ }
+ types = types.split(splitter);
+ while (type = types.shift()) {
+ delete this._callbacks[type];
+ }
+ return this;
+ }
+ function trigger(types) {
+ var type, callbacks, args, syncFlush, asyncFlush;
+ if (!this._callbacks) {
+ return this;
+ }
+ types = types.split(splitter);
+ args = [].slice.call(arguments, 1);
+ while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
+ syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
+ asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
+ syncFlush() && nextTick(asyncFlush);
+ }
+ return this;
+ }
+ function getFlush(callbacks, context, args) {
+ return flush;
+ function flush() {
+ var cancelled;
+ for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
+ cancelled = callbacks[i].apply(context, args) === false;
+ }
+ return !cancelled;
+ }
+ }
+ function getNextTick() {
+ var nextTickFn;
+ if (window.setImmediate) {
+ nextTickFn = function nextTickSetImmediate(fn) {
+ setImmediate(function() {
+ fn();
+ });
+ };
+ } else {
+ nextTickFn = function nextTickSetTimeout(fn) {
+ setTimeout(function() {
+ fn();
+ }, 0);
+ };
+ }
+ return nextTickFn;
+ }
+ function bindContext(fn, context) {
+ return fn.bind ? fn.bind(context) : function() {
+ fn.apply(context, [].slice.call(arguments, 0));
+ };
+ }
+ }();
+ var highlight = function(doc) {
+ "use strict";
+ var defaults = {
+ node: null,
+ pattern: null,
+ tagName: "strong",
+ className: null,
+ wordsOnly: false,
+ caseSensitive: false
+ };
+ return function hightlight(o) {
+ var regex;
+ o = _.mixin({}, defaults, o);
+ if (!o.node || !o.pattern) {
+ return;
+ }
+ o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
+ regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
+ traverse(o.node, hightlightTextNode);
+ function hightlightTextNode(textNode) {
+ var match, patternNode, wrapperNode;
+ if (match = regex.exec(textNode.data)) {
+ wrapperNode = doc.createElement(o.tagName);
+ o.className && (wrapperNode.className = o.className);
+ patternNode = textNode.splitText(match.index);
+ patternNode.splitText(match[0].length);
+ wrapperNode.appendChild(patternNode.cloneNode(true));
+ textNode.parentNode.replaceChild(wrapperNode, patternNode);
+ }
+ return !!match;
+ }
+ function traverse(el, hightlightTextNode) {
+ var childNode, TEXT_NODE_TYPE = 3;
+ for (var i = 0; i < el.childNodes.length; i++) {
+ childNode = el.childNodes[i];
+ if (childNode.nodeType === TEXT_NODE_TYPE) {
+ i += hightlightTextNode(childNode) ? 1 : 0;
+ } else {
+ traverse(childNode, hightlightTextNode);
+ }
+ }
+ }
+ };
+ function getRegex(patterns, caseSensitive, wordsOnly) {
+ var escapedPatterns = [], regexStr;
+ for (var i = 0, len = patterns.length; i < len; i++) {
+ escapedPatterns.push(_.escapeRegExChars(patterns[i]));
+ }
+ regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
+ return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
+ }
+ }(window.document);
+ var Input = function() {
+ "use strict";
+ var specialKeyCodeMap;
+ specialKeyCodeMap = {
+ 9: "tab",
+ 27: "esc",
+ 37: "left",
+ 39: "right",
+ 13: "enter",
+ 38: "up",
+ 40: "down"
+ };
+ function Input(o, www) {
+ o = o || {};
+ if (!o.input) {
+ $.error("input is missing");
+ }
+ www.mixin(this);
+ this.$hint = $(o.hint);
+ this.$input = $(o.input);
+ this.query = this.$input.val();
+ this.queryWhenFocused = this.hasFocus() ? this.query : null;
+ this.$overflowHelper = buildOverflowHelper(this.$input);
+ this._checkLanguageDirection();
+ if (this.$hint.length === 0) {
+ this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
+ }
+ }
+ Input.normalizeQuery = function(str) {
+ return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
+ };
+ _.mixin(Input.prototype, EventEmitter, {
+ _onBlur: function onBlur() {
+ this.resetInputValue();
+ this.trigger("blurred");
+ },
+ _onFocus: function onFocus() {
+ this.queryWhenFocused = this.query;
+ this.trigger("focused");
+ },
+ _onKeydown: function onKeydown($e) {
+ var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
+ this._managePreventDefault(keyName, $e);
+ if (keyName && this._shouldTrigger(keyName, $e)) {
+ this.trigger(keyName + "Keyed", $e);
+ }
+ },
+ _onInput: function onInput() {
+ this._setQuery(this.getInputValue());
+ this.clearHintIfInvalid();
+ this._checkLanguageDirection();
+ },
+ _managePreventDefault: function managePreventDefault(keyName, $e) {
+ var preventDefault;
+ switch (keyName) {
+ case "up":
+ case "down":
+ preventDefault = !withModifier($e);
+ break;
+
+ default:
+ preventDefault = false;
+ }
+ preventDefault && $e.preventDefault();
+ },
+ _shouldTrigger: function shouldTrigger(keyName, $e) {
+ var trigger;
+ switch (keyName) {
+ case "tab":
+ trigger = !withModifier($e);
+ break;
+
+ default:
+ trigger = true;
+ }
+ return trigger;
+ },
+ _checkLanguageDirection: function checkLanguageDirection() {
+ var dir = (this.$input.css("direction") || "ltr").toLowerCase();
+ if (this.dir !== dir) {
+ this.dir = dir;
+ this.$hint.attr("dir", dir);
+ this.trigger("langDirChanged", dir);
+ }
+ },
+ _setQuery: function setQuery(val, silent) {
+ var areEquivalent, hasDifferentWhitespace;
+ areEquivalent = areQueriesEquivalent(val, this.query);
+ hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false;
+ this.query = val;
+ if (!silent && !areEquivalent) {
+ this.trigger("queryChanged", this.query);
+ } else if (!silent && hasDifferentWhitespace) {
+ this.trigger("whitespaceChanged", this.query);
+ }
+ },
+ bind: function() {
+ var that = this, onBlur, onFocus, onKeydown, onInput;
+ onBlur = _.bind(this._onBlur, this);
+ onFocus = _.bind(this._onFocus, this);
+ onKeydown = _.bind(this._onKeydown, this);
+ onInput = _.bind(this._onInput, this);
+ this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
+ if (!_.isMsie() || _.isMsie() > 9) {
+ this.$input.on("input.tt", onInput);
+ } else {
+ this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
+ if (specialKeyCodeMap[$e.which || $e.keyCode]) {
+ return;
+ }
+ _.defer(_.bind(that._onInput, that, $e));
+ });
+ }
+ return this;
+ },
+ focus: function focus() {
+ this.$input.focus();
+ },
+ blur: function blur() {
+ this.$input.blur();
+ },
+ getLangDir: function getLangDir() {
+ return this.dir;
+ },
+ getQuery: function getQuery() {
+ return this.query || "";
+ },
+ setQuery: function setQuery(val, silent) {
+ this.setInputValue(val);
+ this._setQuery(val, silent);
+ },
+ hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() {
+ return this.query !== this.queryWhenFocused;
+ },
+ getInputValue: function getInputValue() {
+ return this.$input.val();
+ },
+ setInputValue: function setInputValue(value) {
+ this.$input.val(value);
+ this.clearHintIfInvalid();
+ this._checkLanguageDirection();
+ },
+ resetInputValue: function resetInputValue() {
+ this.setInputValue(this.query);
+ },
+ getHint: function getHint() {
+ return this.$hint.val();
+ },
+ setHint: function setHint(value) {
+ this.$hint.val(value);
+ },
+ clearHint: function clearHint() {
+ this.setHint("");
+ },
+ clearHintIfInvalid: function clearHintIfInvalid() {
+ var val, hint, valIsPrefixOfHint, isValid;
+ val = this.getInputValue();
+ hint = this.getHint();
+ valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
+ isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
+ !isValid && this.clearHint();
+ },
+ hasFocus: function hasFocus() {
+ return this.$input.is(":focus");
+ },
+ hasOverflow: function hasOverflow() {
+ var constraint = this.$input.width() - 2;
+ this.$overflowHelper.text(this.getInputValue());
+ return this.$overflowHelper.width() >= constraint;
+ },
+ isCursorAtEnd: function() {
+ var valueLength, selectionStart, range;
+ valueLength = this.$input.val().length;
+ selectionStart = this.$input[0].selectionStart;
+ if (_.isNumber(selectionStart)) {
+ return selectionStart === valueLength;
+ } else if (document.selection) {
+ range = document.selection.createRange();
+ range.moveStart("character", -valueLength);
+ return valueLength === range.text.length;
+ }
+ return true;
+ },
+ destroy: function destroy() {
+ this.$hint.off(".tt");
+ this.$input.off(".tt");
+ this.$overflowHelper.remove();
+ this.$hint = this.$input = this.$overflowHelper = $("");
+ }
+ });
+ return Input;
+ function buildOverflowHelper($input) {
+ return $('
').css({
+ position: "absolute",
+ visibility: "hidden",
+ whiteSpace: "pre",
+ fontFamily: $input.css("font-family"),
+ fontSize: $input.css("font-size"),
+ fontStyle: $input.css("font-style"),
+ fontVariant: $input.css("font-variant"),
+ fontWeight: $input.css("font-weight"),
+ wordSpacing: $input.css("word-spacing"),
+ letterSpacing: $input.css("letter-spacing"),
+ textIndent: $input.css("text-indent"),
+ textRendering: $input.css("text-rendering"),
+ textTransform: $input.css("text-transform")
+ }).insertAfter($input);
+ }
+ function areQueriesEquivalent(a, b) {
+ return Input.normalizeQuery(a) === Input.normalizeQuery(b);
+ }
+ function withModifier($e) {
+ return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
+ }
+ }();
+ var Dataset = function() {
+ "use strict";
+ var keys, nameGenerator;
+ keys = {
+ val: "tt-selectable-display",
+ obj: "tt-selectable-object"
+ };
+ nameGenerator = _.getIdGenerator();
+ function Dataset(o, www) {
+ o = o || {};
+ o.templates = o.templates || {};
+ o.templates.notFound = o.templates.notFound || o.templates.empty;
+ if (!o.source) {
+ $.error("missing source");
+ }
+ if (!o.node) {
+ $.error("missing node");
+ }
+ if (o.name && !isValidName(o.name)) {
+ $.error("invalid dataset name: " + o.name);
+ }
+ www.mixin(this);
+ this.highlight = !!o.highlight;
+ this.name = o.name || nameGenerator();
+ this.limit = o.limit || 5;
+ this.displayFn = getDisplayFn(o.display || o.displayKey);
+ this.templates = getTemplates(o.templates, this.displayFn);
+ this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
+ this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
+ this._resetLastSuggestion();
+ this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
+ }
+ Dataset.extractData = function extractData(el) {
+ var $el = $(el);
+ if ($el.data(keys.obj)) {
+ return {
+ val: $el.data(keys.val) || "",
+ obj: $el.data(keys.obj) || null
+ };
+ }
+ return null;
+ };
+ _.mixin(Dataset.prototype, EventEmitter, {
+ _overwrite: function overwrite(query, suggestions) {
+ suggestions = suggestions || [];
+ if (suggestions.length) {
+ this._renderSuggestions(query, suggestions);
+ } else if (this.async && this.templates.pending) {
+ this._renderPending(query);
+ } else if (!this.async && this.templates.notFound) {
+ this._renderNotFound(query);
+ } else {
+ this._empty();
+ }
+ this.trigger("rendered", this.name, suggestions, false);
+ },
+ _append: function append(query, suggestions) {
+ suggestions = suggestions || [];
+ if (suggestions.length && this.$lastSuggestion.length) {
+ this._appendSuggestions(query, suggestions);
+ } else if (suggestions.length) {
+ this._renderSuggestions(query, suggestions);
+ } else if (!this.$lastSuggestion.length && this.templates.notFound) {
+ this._renderNotFound(query);
+ }
+ this.trigger("rendered", this.name, suggestions, true);
+ },
+ _renderSuggestions: function renderSuggestions(query, suggestions) {
+ var $fragment;
+ $fragment = this._getSuggestionsFragment(query, suggestions);
+ this.$lastSuggestion = $fragment.children().last();
+ this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions));
+ },
+ _appendSuggestions: function appendSuggestions(query, suggestions) {
+ var $fragment, $lastSuggestion;
+ $fragment = this._getSuggestionsFragment(query, suggestions);
+ $lastSuggestion = $fragment.children().last();
+ this.$lastSuggestion.after($fragment);
+ this.$lastSuggestion = $lastSuggestion;
+ },
+ _renderPending: function renderPending(query) {
+ var template = this.templates.pending;
+ this._resetLastSuggestion();
+ template && this.$el.html(template({
+ query: query,
+ dataset: this.name
+ }));
+ },
+ _renderNotFound: function renderNotFound(query) {
+ var template = this.templates.notFound;
+ this._resetLastSuggestion();
+ template && this.$el.html(template({
+ query: query,
+ dataset: this.name
+ }));
+ },
+ _empty: function empty() {
+ this.$el.empty();
+ this._resetLastSuggestion();
+ },
+ _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) {
+ var that = this, fragment;
+ fragment = document.createDocumentFragment();
+ _.each(suggestions, function getSuggestionNode(suggestion) {
+ var $el, context;
+ context = that._injectQuery(query, suggestion);
+ $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
+ fragment.appendChild($el[0]);
+ });
+ this.highlight && highlight({
+ className: this.classes.highlight,
+ node: fragment,
+ pattern: query
+ });
+ return $(fragment);
+ },
+ _getFooter: function getFooter(query, suggestions) {
+ return this.templates.footer ? this.templates.footer({
+ query: query,
+ suggestions: suggestions,
+ dataset: this.name
+ }) : null;
+ },
+ _getHeader: function getHeader(query, suggestions) {
+ return this.templates.header ? this.templates.header({
+ query: query,
+ suggestions: suggestions,
+ dataset: this.name
+ }) : null;
+ },
+ _resetLastSuggestion: function resetLastSuggestion() {
+ this.$lastSuggestion = $();
+ },
+ _injectQuery: function injectQuery(query, obj) {
+ return _.isObject(obj) ? _.mixin({
+ _query: query
+ }, obj) : obj;
+ },
+ update: function update(query) {
+ var that = this, canceled = false, syncCalled = false, rendered = 0;
+ this.cancel();
+ this.cancel = function cancel() {
+ canceled = true;
+ that.cancel = $.noop;
+ that.async && that.trigger("asyncCanceled", query);
+ };
+ this.source(query, sync, async);
+ !syncCalled && sync([]);
+ function sync(suggestions) {
+ if (syncCalled) {
+ return;
+ }
+ syncCalled = true;
+ suggestions = (suggestions || []).slice(0, that.limit);
+ rendered = suggestions.length;
+ that._overwrite(query, suggestions);
+ if (rendered < that.limit && that.async) {
+ that.trigger("asyncRequested", query);
+ }
+ }
+ function async(suggestions) {
+ suggestions = suggestions || [];
+ if (!canceled && rendered < that.limit) {
+ that.cancel = $.noop;
+ rendered += suggestions.length;
+ that._append(query, suggestions.slice(0, that.limit - rendered));
+ that.async && that.trigger("asyncReceived", query);
+ }
+ }
+ },
+ cancel: $.noop,
+ clear: function clear() {
+ this._empty();
+ this.cancel();
+ this.trigger("cleared");
+ },
+ isEmpty: function isEmpty() {
+ return this.$el.is(":empty");
+ },
+ destroy: function destroy() {
+ this.$el = $("
");
+ }
+ });
+ return Dataset;
+ function getDisplayFn(display) {
+ display = display || _.stringify;
+ return _.isFunction(display) ? display : displayFn;
+ function displayFn(obj) {
+ return obj[display];
+ }
+ }
+ function getTemplates(templates, displayFn) {
+ return {
+ notFound: templates.notFound && _.templatify(templates.notFound),
+ pending: templates.pending && _.templatify(templates.pending),
+ header: templates.header && _.templatify(templates.header),
+ footer: templates.footer && _.templatify(templates.footer),
+ suggestion: templates.suggestion || suggestionTemplate
+ };
+ function suggestionTemplate(context) {
+ return $("
").text(displayFn(context));
+ }
+ }
+ function isValidName(str) {
+ return /^[_a-zA-Z0-9-]+$/.test(str);
+ }
+ }();
+ var Menu = function() {
+ "use strict";
+ function Menu(o, www) {
+ var that = this;
+ o = o || {};
+ if (!o.node) {
+ $.error("node is required");
+ }
+ www.mixin(this);
+ this.$node = $(o.node);
+ this.query = null;
+ this.datasets = _.map(o.datasets, initializeDataset);
+ function initializeDataset(oDataset) {
+ var node = that.$node.find(oDataset.node).first();
+ oDataset.node = node.length ? node : $("
").appendTo(that.$node);
+ return new Dataset(oDataset, www);
+ }
+ }
+ _.mixin(Menu.prototype, EventEmitter, {
+ _onSelectableClick: function onSelectableClick($e) {
+ this.trigger("selectableClicked", $($e.currentTarget));
+ },
+ _onRendered: function onRendered(type, dataset, suggestions, async) {
+ this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
+ this.trigger("datasetRendered", dataset, suggestions, async);
+ },
+ _onCleared: function onCleared() {
+ this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
+ this.trigger("datasetCleared");
+ },
+ _propagate: function propagate() {
+ this.trigger.apply(this, arguments);
+ },
+ _allDatasetsEmpty: function allDatasetsEmpty() {
+ return _.every(this.datasets, isDatasetEmpty);
+ function isDatasetEmpty(dataset) {
+ return dataset.isEmpty();
+ }
+ },
+ _getSelectables: function getSelectables() {
+ return this.$node.find(this.selectors.selectable);
+ },
+ _removeCursor: function _removeCursor() {
+ var $selectable = this.getActiveSelectable();
+ $selectable && $selectable.removeClass(this.classes.cursor);
+ },
+ _ensureVisible: function ensureVisible($el) {
+ var elTop, elBottom, nodeScrollTop, nodeHeight;
+ elTop = $el.position().top;
+ elBottom = elTop + $el.outerHeight(true);
+ nodeScrollTop = this.$node.scrollTop();
+ nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10);
+ if (elTop < 0) {
+ this.$node.scrollTop(nodeScrollTop + elTop);
+ } else if (nodeHeight < elBottom) {
+ this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
+ }
+ },
+ bind: function() {
+ var that = this, onSelectableClick;
+ onSelectableClick = _.bind(this._onSelectableClick, this);
+ this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
+ _.each(this.datasets, function(dataset) {
+ dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
+ });
+ return this;
+ },
+ isOpen: function isOpen() {
+ return this.$node.hasClass(this.classes.open);
+ },
+ open: function open() {
+ this.$node.addClass(this.classes.open);
+ },
+ close: function close() {
+ this.$node.removeClass(this.classes.open);
+ this._removeCursor();
+ },
+ setLanguageDirection: function setLanguageDirection(dir) {
+ this.$node.attr("dir", dir);
+ },
+ selectableRelativeToCursor: function selectableRelativeToCursor(delta) {
+ var $selectables, $oldCursor, oldIndex, newIndex;
+ $oldCursor = this.getActiveSelectable();
+ $selectables = this._getSelectables();
+ oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1;
+ newIndex = oldIndex + delta;
+ newIndex = (newIndex + 1) % ($selectables.length + 1) - 1;
+ newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex;
+ return newIndex === -1 ? null : $selectables.eq(newIndex);
+ },
+ setCursor: function setCursor($selectable) {
+ this._removeCursor();
+ if ($selectable = $selectable && $selectable.first()) {
+ $selectable.addClass(this.classes.cursor);
+ this._ensureVisible($selectable);
+ }
+ },
+ getSelectableData: function getSelectableData($el) {
+ return $el && $el.length ? Dataset.extractData($el) : null;
+ },
+ getActiveSelectable: function getActiveSelectable() {
+ var $selectable = this._getSelectables().filter(this.selectors.cursor).first();
+ return $selectable.length ? $selectable : null;
+ },
+ getTopSelectable: function getTopSelectable() {
+ var $selectable = this._getSelectables().first();
+ return $selectable.length ? $selectable : null;
+ },
+ update: function update(query) {
+ var isValidUpdate = query !== this.query;
+ if (isValidUpdate) {
+ this.query = query;
+ _.each(this.datasets, updateDataset);
+ }
+ return isValidUpdate;
+ function updateDataset(dataset) {
+ dataset.update(query);
+ }
+ },
+ empty: function empty() {
+ _.each(this.datasets, clearDataset);
+ this.query = null;
+ this.$node.addClass(this.classes.empty);
+ function clearDataset(dataset) {
+ dataset.clear();
+ }
+ },
+ destroy: function destroy() {
+ this.$node.off(".tt");
+ this.$node = $("
");
+ _.each(this.datasets, destroyDataset);
+ function destroyDataset(dataset) {
+ dataset.destroy();
+ }
+ }
+ });
+ return Menu;
+ }();
+ var DefaultMenu = function() {
+ "use strict";
+ var s = Menu.prototype;
+ function DefaultMenu() {
+ Menu.apply(this, [].slice.call(arguments, 0));
+ }
+ _.mixin(DefaultMenu.prototype, Menu.prototype, {
+ open: function open() {
+ !this._allDatasetsEmpty() && this._show();
+ return s.open.apply(this, [].slice.call(arguments, 0));
+ },
+ close: function close() {
+ this._hide();
+ return s.close.apply(this, [].slice.call(arguments, 0));
+ },
+ _onRendered: function onRendered() {
+ if (this._allDatasetsEmpty()) {
+ this._hide();
+ } else {
+ this.isOpen() && this._show();
+ }
+ return s._onRendered.apply(this, [].slice.call(arguments, 0));
+ },
+ _onCleared: function onCleared() {
+ if (this._allDatasetsEmpty()) {
+ this._hide();
+ } else {
+ this.isOpen() && this._show();
+ }
+ return s._onCleared.apply(this, [].slice.call(arguments, 0));
+ },
+ setLanguageDirection: function setLanguageDirection(dir) {
+ this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl);
+ return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0));
+ },
+ _hide: function hide() {
+ this.$node.hide();
+ },
+ _show: function show() {
+ this.$node.css("display", "block");
+ }
+ });
+ return DefaultMenu;
+ }();
+ var Typeahead = function() {
+ "use strict";
+ function Typeahead(o, www) {
+ var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged;
+ o = o || {};
+ if (!o.input) {
+ $.error("missing input");
+ }
+ if (!o.menu) {
+ $.error("missing menu");
+ }
+ if (!o.eventBus) {
+ $.error("missing event bus");
+ }
+ www.mixin(this);
+ this.eventBus = o.eventBus;
+ this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
+ this.input = o.input;
+ this.menu = o.menu;
+ this.enabled = true;
+ this.active = false;
+ this.input.hasFocus() && this.activate();
+ this.dir = this.input.getLangDir();
+ this._hacks();
+ this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this);
+ onFocused = c(this, "activate", "open", "_onFocused");
+ onBlurred = c(this, "deactivate", "_onBlurred");
+ onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed");
+ onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed");
+ onEscKeyed = c(this, "isActive", "_onEscKeyed");
+ onUpKeyed = c(this, "isActive", "open", "_onUpKeyed");
+ onDownKeyed = c(this, "isActive", "open", "_onDownKeyed");
+ onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed");
+ onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed");
+ onQueryChanged = c(this, "_openIfActive", "_onQueryChanged");
+ onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged");
+ this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this);
+ }
+ _.mixin(Typeahead.prototype, {
+ _hacks: function hacks() {
+ var $input, $menu;
+ $input = this.input.$input || $("
");
+ $menu = this.menu.$node || $("
");
+ $input.on("blur.tt", function($e) {
+ var active, isActive, hasActive;
+ active = document.activeElement;
+ isActive = $menu.is(active);
+ hasActive = $menu.has(active).length > 0;
+ if (_.isMsie() && (isActive || hasActive)) {
+ $e.preventDefault();
+ $e.stopImmediatePropagation();
+ _.defer(function() {
+ $input.focus();
+ });
+ }
+ });
+ $menu.on("mousedown.tt", function($e) {
+ $e.preventDefault();
+ });
+ },
+ _onSelectableClicked: function onSelectableClicked(type, $el) {
+ this.select($el);
+ },
+ _onDatasetCleared: function onDatasetCleared() {
+ this._updateHint();
+ },
+ _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {
+ this._updateHint();
+ this.eventBus.trigger("render", suggestions, async, dataset);
+ },
+ _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
+ this.eventBus.trigger("asyncrequest", query, dataset);
+ },
+ _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {
+ this.eventBus.trigger("asynccancel", query, dataset);
+ },
+ _onAsyncReceived: function onAsyncReceived(type, dataset, query) {
+ this.eventBus.trigger("asyncreceive", query, dataset);
+ },
+ _onFocused: function onFocused() {
+ this._minLengthMet() && this.menu.update(this.input.getQuery());
+ },
+ _onBlurred: function onBlurred() {
+ if (this.input.hasQueryChangedSinceLastFocus()) {
+ this.eventBus.trigger("change", this.input.getQuery());
+ }
+ },
+ _onEnterKeyed: function onEnterKeyed(type, $e) {
+ var $selectable;
+ if ($selectable = this.menu.getActiveSelectable()) {
+ this.select($selectable) && $e.preventDefault();
+ }
+ },
+ _onTabKeyed: function onTabKeyed(type, $e) {
+ var $selectable;
+ if ($selectable = this.menu.getActiveSelectable()) {
+ this.select($selectable) && $e.preventDefault();
+ } else if ($selectable = this.menu.getTopSelectable()) {
+ this.autocomplete($selectable) && $e.preventDefault();
+ }
+ },
+ _onEscKeyed: function onEscKeyed() {
+ this.close();
+ },
+ _onUpKeyed: function onUpKeyed() {
+ this.moveCursor(-1);
+ },
+ _onDownKeyed: function onDownKeyed() {
+ this.moveCursor(+1);
+ },
+ _onLeftKeyed: function onLeftKeyed() {
+ if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
+ this.autocomplete(this.menu.getTopSelectable());
+ }
+ },
+ _onRightKeyed: function onRightKeyed() {
+ if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
+ this.autocomplete(this.menu.getTopSelectable());
+ }
+ },
+ _onQueryChanged: function onQueryChanged(e, query) {
+ this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();
+ },
+ _onWhitespaceChanged: function onWhitespaceChanged() {
+ this._updateHint();
+ },
+ _onLangDirChanged: function onLangDirChanged(e, dir) {
+ if (this.dir !== dir) {
+ this.dir = dir;
+ this.menu.setLanguageDirection(dir);
+ }
+ },
+ _openIfActive: function openIfActive() {
+ this.isActive() && this.open();
+ },
+ _minLengthMet: function minLengthMet(query) {
+ query = _.isString(query) ? query : this.input.getQuery() || "";
+ return query.length >= this.minLength;
+ },
+ _updateHint: function updateHint() {
+ var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;
+ $selectable = this.menu.getTopSelectable();
+ data = this.menu.getSelectableData($selectable);
+ val = this.input.getInputValue();
+ if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {
+ query = Input.normalizeQuery(val);
+ escapedQuery = _.escapeRegExChars(query);
+ frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
+ match = frontMatchRegEx.exec(data.val);
+ match && this.input.setHint(val + match[1]);
+ } else {
+ this.input.clearHint();
+ }
+ },
+ isEnabled: function isEnabled() {
+ return this.enabled;
+ },
+ enable: function enable() {
+ this.enabled = true;
+ },
+ disable: function disable() {
+ this.enabled = false;
+ },
+ isActive: function isActive() {
+ return this.active;
+ },
+ activate: function activate() {
+ if (this.isActive()) {
+ return true;
+ } else if (!this.isEnabled() || this.eventBus.before("active")) {
+ return false;
+ } else {
+ this.active = true;
+ this.eventBus.trigger("active");
+ return true;
+ }
+ },
+ deactivate: function deactivate() {
+ if (!this.isActive()) {
+ return true;
+ } else if (this.eventBus.before("idle")) {
+ return false;
+ } else {
+ this.active = false;
+ this.close();
+ this.eventBus.trigger("idle");
+ return true;
+ }
+ },
+ isOpen: function isOpen() {
+ return this.menu.isOpen();
+ },
+ open: function open() {
+ if (!this.isOpen() && !this.eventBus.before("open")) {
+ this.menu.open();
+ this._updateHint();
+ this.eventBus.trigger("open");
+ }
+ return this.isOpen();
+ },
+ close: function close() {
+ if (this.isOpen() && !this.eventBus.before("close")) {
+ this.menu.close();
+ this.input.clearHint();
+ this.input.resetInputValue();
+ this.eventBus.trigger("close");
+ }
+ return !this.isOpen();
+ },
+ setVal: function setVal(val) {
+ this.input.setQuery(_.toStr(val));
+ },
+ getVal: function getVal() {
+ return this.input.getQuery();
+ },
+ select: function select($selectable) {
+ var data = this.menu.getSelectableData($selectable);
+ if (data && !this.eventBus.before("select", data.obj)) {
+ this.input.setQuery(data.val, true);
+ this.eventBus.trigger("select", data.obj);
+ this.close();
+ return true;
+ }
+ return false;
+ },
+ autocomplete: function autocomplete($selectable) {
+ var query, data, isValid;
+ query = this.input.getQuery();
+ data = this.menu.getSelectableData($selectable);
+ isValid = data && query !== data.val;
+ if (isValid && !this.eventBus.before("autocomplete", data.obj)) {
+ this.input.setQuery(data.val);
+ this.eventBus.trigger("autocomplete", data.obj);
+ return true;
+ }
+ return false;
+ },
+ moveCursor: function moveCursor(delta) {
+ var query, $candidate, data, payload, cancelMove;
+ query = this.input.getQuery();
+ $candidate = this.menu.selectableRelativeToCursor(delta);
+ data = this.menu.getSelectableData($candidate);
+ payload = data ? data.obj : null;
+ cancelMove = this._minLengthMet() && this.menu.update(query);
+ if (!cancelMove && !this.eventBus.before("cursorchange", payload)) {
+ this.menu.setCursor($candidate);
+ if (data) {
+ this.input.setInputValue(data.val);
+ } else {
+ this.input.resetInputValue();
+ this._updateHint();
+ }
+ this.eventBus.trigger("cursorchange", payload);
+ return true;
+ }
+ return false;
+ },
+ destroy: function destroy() {
+ this.input.destroy();
+ this.menu.destroy();
+ }
+ });
+ return Typeahead;
+ function c(ctx) {
+ var methods = [].slice.call(arguments, 1);
+ return function() {
+ var args = [].slice.call(arguments);
+ _.each(methods, function(method) {
+ return ctx[method].apply(ctx, args);
+ });
+ };
+ }
+ }();
+ (function() {
+ "use strict";
+ var old, keys, methods;
+ old = $.fn.typeahead;
+ keys = {
+ www: "tt-www",
+ attrs: "tt-attrs",
+ typeahead: "tt-typeahead"
+ };
+ methods = {
+ initialize: function initialize(o, datasets) {
+ var www;
+ datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
+ o = o || {};
+ www = WWW(o.classNames);
+ return this.each(attach);
+ function attach() {
+ var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor;
+ _.each(datasets, function(d) {
+ d.highlight = !!o.highlight;
+ });
+ $input = $(this);
+ $wrapper = $(www.html.wrapper);
+ $hint = $elOrNull(o.hint);
+ $menu = $elOrNull(o.menu);
+ defaultHint = o.hint !== false && !$hint;
+ defaultMenu = o.menu !== false && !$menu;
+ defaultHint && ($hint = buildHintFromInput($input, www));
+ defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));
+ $hint && $hint.val("");
+ $input = prepInput($input, www);
+ if (defaultHint || defaultMenu) {
+ $wrapper.css(www.css.wrapper);
+ $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);
+ $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null);
+ }
+ MenuConstructor = defaultMenu ? DefaultMenu : Menu;
+ eventBus = new EventBus({
+ el: $input
+ });
+ input = new Input({
+ hint: $hint,
+ input: $input
+ }, www);
+ menu = new MenuConstructor({
+ node: $menu,
+ datasets: datasets
+ }, www);
+ typeahead = new Typeahead({
+ input: input,
+ menu: menu,
+ eventBus: eventBus,
+ minLength: o.minLength
+ }, www);
+ $input.data(keys.www, www);
+ $input.data(keys.typeahead, typeahead);
+ }
+ },
+ isEnabled: function isEnabled() {
+ var enabled;
+ ttEach(this.first(), function(t) {
+ enabled = t.isEnabled();
+ });
+ return enabled;
+ },
+ enable: function enable() {
+ ttEach(this, function(t) {
+ t.enable();
+ });
+ return this;
+ },
+ disable: function disable() {
+ ttEach(this, function(t) {
+ t.disable();
+ });
+ return this;
+ },
+ isActive: function isActive() {
+ var active;
+ ttEach(this.first(), function(t) {
+ active = t.isActive();
+ });
+ return active;
+ },
+ activate: function activate() {
+ ttEach(this, function(t) {
+ t.activate();
+ });
+ return this;
+ },
+ deactivate: function deactivate() {
+ ttEach(this, function(t) {
+ t.deactivate();
+ });
+ return this;
+ },
+ isOpen: function isOpen() {
+ var open;
+ ttEach(this.first(), function(t) {
+ open = t.isOpen();
+ });
+ return open;
+ },
+ open: function open() {
+ ttEach(this, function(t) {
+ t.open();
+ });
+ return this;
+ },
+ close: function close() {
+ ttEach(this, function(t) {
+ t.close();
+ });
+ return this;
+ },
+ select: function select(el) {
+ var success = false, $el = $(el);
+ ttEach(this.first(), function(t) {
+ success = t.select($el);
+ });
+ return success;
+ },
+ autocomplete: function autocomplete(el) {
+ var success = false, $el = $(el);
+ ttEach(this.first(), function(t) {
+ success = t.autocomplete($el);
+ });
+ return success;
+ },
+ moveCursor: function moveCursoe(delta) {
+ var success = false;
+ ttEach(this.first(), function(t) {
+ success = t.moveCursor(delta);
+ });
+ return success;
+ },
+ val: function val(newVal) {
+ var query;
+ if (!arguments.length) {
+ ttEach(this.first(), function(t) {
+ query = t.getVal();
+ });
+ return query;
+ } else {
+ ttEach(this, function(t) {
+ t.setVal(newVal);
+ });
+ return this;
+ }
+ },
+ destroy: function destroy() {
+ ttEach(this, function(typeahead, $input) {
+ revert($input);
+ typeahead.destroy();
+ });
+ return this;
+ }
+ };
+ $.fn.typeahead = function(method) {
+ if (methods[method]) {
+ return methods[method].apply(this, [].slice.call(arguments, 1));
+ } else {
+ return methods.initialize.apply(this, arguments);
+ }
+ };
+ $.fn.typeahead.noConflict = function noConflict() {
+ $.fn.typeahead = old;
+ return this;
+ };
+ function ttEach($els, fn) {
+ $els.each(function() {
+ var $input = $(this), typeahead;
+ (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);
+ });
+ }
+ function buildHintFromInput($input, www) {
+ return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({
+ autocomplete: "off",
+ spellcheck: "false",
+ tabindex: -1
+ });
+ }
+ function prepInput($input, www) {
+ $input.data(keys.attrs, {
+ dir: $input.attr("dir"),
+ autocomplete: $input.attr("autocomplete"),
+ spellcheck: $input.attr("spellcheck"),
+ style: $input.attr("style")
+ });
+ $input.addClass(www.classes.input).attr({
+ autocomplete: "off",
+ spellcheck: false
+ });
+ try {
+ !$input.attr("dir") && $input.attr("dir", "auto");
+ } catch (e) {}
+ return $input;
+ }
+ function getBackgroundStyles($el) {
+ return {
+ backgroundAttachment: $el.css("background-attachment"),
+ backgroundClip: $el.css("background-clip"),
+ backgroundColor: $el.css("background-color"),
+ backgroundImage: $el.css("background-image"),
+ backgroundOrigin: $el.css("background-origin"),
+ backgroundPosition: $el.css("background-position"),
+ backgroundRepeat: $el.css("background-repeat"),
+ backgroundSize: $el.css("background-size")
+ };
+ }
+ function revert($input) {
+ var www, $wrapper;
+ www = $input.data(keys.www);
+ $wrapper = $input.parent().filter(www.selectors.wrapper);
+ _.each($input.data(keys.attrs), function(val, key) {
+ _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
+ });
+ $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input);
+ if ($wrapper.length) {
+ $input.detach().insertAfter($wrapper);
+ $wrapper.remove();
+ }
+ }
+ function $elOrNull(obj) {
+ var isValid, $el;
+ isValid = _.isJQuery(obj) || _.isElement(obj);
+ $el = isValid ? $(obj).first() : [];
+ return $el.length ? $el : null;
+ }
+ })();
+});
\ No newline at end of file
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/search.json b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/search.json
new file mode 100644
index 0000000000..ef32685aef
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/search.json
@@ -0,0 +1 @@
+{"Classes/IBANTextField.html#/s:vC5Adyen13IBANTextField4ibanGSqSS_":{"name":"iban","abstract":"
The IBAN entered in the text field, or nil
if no valid IBAN has been entered.
","parent_name":"IBANTextField"},"Classes/IBANValidator.html#/s:ZFC5Adyen13IBANValidator7isValidFSSSb":{"name":"isValid(_:)","abstract":"
Checks if the given string is a valid IBAN value.
","parent_name":"IBANValidator"},"Structs/IBANSpecification.html#/s:vV5Adyen17IBANSpecification11countryCodeSS":{"name":"countryCode","abstract":"
The code of the country to which the specifications apply.
","parent_name":"IBANSpecification"},"Structs/IBANSpecification.html#/s:vV5Adyen17IBANSpecification6lengthSi":{"name":"length","abstract":"
The length of a valid IBAN.
","parent_name":"IBANSpecification"},"Structs/IBANSpecification.html#/s:vV5Adyen17IBANSpecification9structureSS":{"name":"structure","abstract":"
The structure of the underlying BBAN.
","parent_name":"IBANSpecification"},"Structs/IBANSpecification.html#/s:vV5Adyen17IBANSpecification7exampleSS":{"name":"example","abstract":"
An example of a valid IBAN.
","parent_name":"IBANSpecification"},"Structs/IBANSpecification.html#/s:FV5Adyen17IBANSpecificationcFT14forCountryCodeSS_GSqS0__":{"name":"init(forCountryCode:)","abstract":"
Returns the IBAN specification for the country with the given code, or nil
if none could be found.
","parent_name":"IBANSpecification"},"Classes/CardValidator.html#/s:ZFC5Adyen13CardValidator8validateFT10cardNumberSS17acceptedCardTypesGSaOS_8CardType__T7isValidSb4typeGSqS1__15formattedNumberSS_":{"name":"validate(cardNumber:acceptedCardTypes:)","abstract":"
Validates and formats the given card number, and detects its card type.
","parent_name":"CardValidator"},"Classes/CardValidator.html#/s:ZFC5Adyen13CardValidator8validateFT10expiryDateSS9separatorGSqSS__T7isValidSb13formattedDateSS_":{"name":"validate(expiryDate:separator:)","abstract":"
Validates and formats the given expiration date.
","parent_name":"CardValidator"},"Classes/CardValidator.html#/s:ZFC5Adyen13CardValidator8validateFT3cvcSS_T7isValidSb12formattedCvcSS_":{"name":"validate(cvc:)","abstract":"
Validates and formats the given cvc.
","parent_name":"CardValidator"},"Enums/CardType.html#/s:FO5Adyen8CardType24alphaBankBonusMasterCardFMS0_S0_":{"name":"alphaBankBonusMasterCard","abstract":"
Alpha Bank Bonus MasterCard
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType18alphaBankBonusVISAFMS0_S0_":{"name":"alphaBankBonusVISA","abstract":"
Alpha Bank Bonus VISA
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType15americanExpressFMS0_S0_":{"name":"americanExpress","abstract":"
American Express
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType4bcmcFMS0_S0_":{"name":"bcmc","abstract":"
BCMC
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType13bijenkorfCardFMS0_S0_":{"name":"bijenkorfCard","abstract":"
de Bijenkorf Card
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType13carteBancaireFMS0_S0_":{"name":"carteBancaire","abstract":"
Carte Bancaire
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType13chinaUnionPayFMS0_S0_":{"name":"chinaUnionPay","abstract":"
China UnionPay
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType7codensaFMS0_S0_":{"name":"codensa","abstract":"
Codensa
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType7dankortFMS0_S0_":{"name":"dankort","abstract":"
Dankort
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType11dankortVISAFMS0_S0_":{"name":"dankortVISA","abstract":"
Dankort VISA
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType6dinersFMS0_S0_":{"name":"diners","abstract":"
Diners Club
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType8discoverFMS0_S0_":{"name":"discover","abstract":"
Discover
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType3eloFMS0_S0_":{"name":"elo","abstract":"
Elo
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType5hiperFMS0_S0_":{"name":"hiper","abstract":"
Hiper
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType9hipercardFMS0_S0_":{"name":"hipercard","abstract":"
Hipercard
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType3jcbFMS0_S0_":{"name":"jcb","abstract":"
JCB
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType11karenMillenFMS0_S0_":{"name":"karenMillen","abstract":"
KarenMillen
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType7maestroFMS0_S0_":{"name":"maestro","abstract":"
Maestro
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType9maestroUKFMS0_S0_":{"name":"maestroUK","abstract":"
Maestro UK
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType10masterCardFMS0_S0_":{"name":"masterCard","abstract":"
MasterCard
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType3mirFMS0_S0_":{"name":"mir","abstract":"
Mir
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType5oasisFMS0_S0_":{"name":"oasis","abstract":"
Oasis
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType4soloFMS0_S0_":{"name":"solo","abstract":"
Solo
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType4uatpFMS0_S0_":{"name":"uatp","abstract":"
Universal Air Travel Plan
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType8unionPayFMS0_S0_":{"name":"unionPay","abstract":"
UnionPay
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType4visaFMS0_S0_":{"name":"visa","abstract":"
VISA
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType9warehouseFMS0_S0_":{"name":"warehouse","abstract":"
The Warehouse
","parent_name":"CardType"},"Enums/CardType.html#/s:ZvO5Adyen8CardType3allGSaS0__":{"name":"all","abstract":"
Array containing all card types in this enum.
","parent_name":"CardType"},"Enums/CardType.html":{"name":"CardType","abstract":"
Enum containing most known types of credit and debit cards.
"},"Classes/CardValidator.html":{"name":"CardValidator","abstract":"
The CardValidator class provides static methods to validate and format card numbers and expiry dates, and to detect card types.
"},"Structs/IBANSpecification.html":{"name":"IBANSpecification","abstract":"
Contains the country-specific specifications for countries that adopt the IBAN standard.
"},"Classes/IBANValidator.html":{"name":"IBANValidator","abstract":"
Provides a static method to validate an IBAN value.
"},"Classes/IBANTextField.html":{"name":"IBANTextField","abstract":"
Provides a text field designed for the entry of an IBAN value. This field formats and validates the IBAN in real time.
"},"Classes/InputSelectItem.html#/s:vC5Adyen15InputSelectItem10identifierSS":{"name":"identifier","abstract":"
Identifier of an item. Should be used to indicate selection of a particular item in InputDetail
object. Assign identifier
to the value
property of the InputDetail
object.
","parent_name":"InputSelectItem"},"Classes/InputSelectItem.html#/s:vC5Adyen15InputSelectItem4nameSS":{"name":"name","abstract":"
Display name of an item.
","parent_name":"InputSelectItem"},"Classes/InputSelectItem.html#/s:vC5Adyen15InputSelectItem8imageURLGSqV10Foundation3URL_":{"name":"imageURL","abstract":"
Contains a URL to image representation of an item, when applicable.
","parent_name":"InputSelectItem"},"Enums/InputType.html#/s:FO5Adyen9InputType4textFMS0_S0_":{"name":"text","abstract":"
Text input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType7booleanFMS0_S0_":{"name":"boolean","abstract":"
Boolean input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType6selectFMS0_S0_":{"name":"select","abstract":"
Input type should be selected from the given list.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType4ibanFMS0_S0_":{"name":"iban","abstract":"
IBAN input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType3cvcFMS0_S0_":{"name":"cvc","abstract":"
CVC input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType9cardTokenFMS0_S0_":{"name":"cardToken","abstract":"
Card token input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType13applePayTokenFMS0_S0_":{"name":"applePayToken","abstract":"
Apple Pay token input type.
","parent_name":"InputType"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail4typeOS_9InputType":{"name":"type","abstract":"
The detail type. Check InputType
.
","parent_name":"InputDetail"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail8optionalSb":{"name":"optional","abstract":"
Whether the detail is optional.
","parent_name":"InputDetail"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail5itemsGSqGSaCS_15InputSelectItem__":{"name":"items","abstract":"
Array of InputSelectItem
. Will only be available if type
is .select
.
","parent_name":"InputDetail"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail11stringValueGSqSS_":{"name":"stringValue","abstract":"
Detail string value.
","parent_name":"InputDetail"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail9boolValueGSqSb_":{"name":"boolValue","abstract":"
Detail bool value.
","parent_name":"InputDetail"},"Classes/PaymentDetails.html#/s:vC5Adyen14PaymentDetails4listGSaCS_11InputDetail_":{"name":"list","abstract":"
List of InputDetail
.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails9setDetailFT5valueSS6forKeySS_T_":{"name":"setDetail(value:forKey:)","abstract":"
Update the detail defined by a given key
with the string value
provided.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails9setDetailFT5valueGSqSb_6forKeySS_T_":{"name":"setDetail(value:forKey:)","abstract":"
Update the detail defined by a given key
with the bool value
provided.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails12fillApplePayFT5tokenSS_T_":{"name":"fillApplePay(token:)","abstract":"
Fill details for the Apple Pay transaction.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails8fillCardFT5tokenSS12storeDetailsGSqSb__T_":{"name":"fillCard(token:storeDetails:)","abstract":"
Fill details for the Card transaction with a token.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails8fillCardFT3cvcSS_T_":{"name":"fillCard(cvc:)","abstract":"
Fill details for the Card transaction with CVC.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails9fillIdealFT16issuerIdentifierSS_T_":{"name":"fillIdeal(issuerIdentifier:)","abstract":"
Fill details for the iDEAL transaction.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails8fillSepaFT4nameSS4ibanSS_T_":{"name":"fillSepa(name:iban:)","abstract":"
Fill details for the SEPA transaction.
","parent_name":"PaymentDetails"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod4nameSS":{"name":"name","abstract":"
The name of the payment method.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod4typeSS":{"name":"type","abstract":"
The payment method type.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod10isOneClickSb":{"name":"isOneClick","abstract":"
A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod7logoURLGSqV10Foundation3URL_":{"name":"logoURL","abstract":"
A URL to the logo of the payment method.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod12inputDetailsGSqGSaCS_11InputDetail__":{"name":"inputDetails","abstract":"
The input details that should be filled in to complete the payment method.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod7membersGSqGSaS0___":{"name":"members","abstract":"
Members of the payment method (only applicable when the receiver is a group).
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod8oneClickSb":{"name":"oneClick","abstract":"
A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html":{"name":"PaymentMethod","abstract":"
Represents a locale payment method that can be used to complete a payment.
"},"Classes/PaymentDetails.html":{"name":"PaymentDetails","abstract":"
Holds the list of InputDetail
needed for the transaction.
"},"Classes/InputDetail.html":{"name":"InputDetail","abstract":"
The payment detail needed for the transaction."},"Enums/InputType.html":{"name":"InputType","abstract":"
Defines types of payment details.
"},"Classes/InputSelectItem.html":{"name":"InputSelectItem","abstract":"
Represents a selectable item used in InputDetail
with select
type.
"},"Enums/Error.html#/s:FO5Adyen5Error7messageFMS0_FSSS0_":{"name":"message","abstract":"
Error with a message. This enum case is deprecated. Please use serverError
instead.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error11serverErrorFMS0_FSSS0_":{"name":"serverError","abstract":"
Error returned from server.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error12networkErrorFMS0_FPs5Error_S0_":{"name":"networkError","abstract":"
Network error.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error14unexpectedDataFMS0_S0_":{"name":"unexpectedData","abstract":"
Unexpected data or data format.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error15unexpectedErrorFMS0_S0_":{"name":"unexpectedError","abstract":"
Unexpected error.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error8canceledFMS0_S0_":{"name":"canceled","abstract":"
Payment was canceled.
","parent_name":"Error"},"Enums/Error.html#/s:vP10Foundation14LocalizedError16errorDescriptionGSqSS_":{"name":"errorDescription","parent_name":"Error"},"Enums/PaymentRequestResult.html#/s:FO5Adyen20PaymentRequestResult7paymentFMS0_FCS_7PaymentS0_":{"name":"payment","abstract":"
In case of success a Payment
object will be returned.
","parent_name":"PaymentRequestResult"},"Enums/PaymentRequestResult.html#/s:FO5Adyen20PaymentRequestResult5errorFMS0_FOS_5ErrorS0_":{"name":"error","abstract":"
In case of failure an Error
will be returned.
","parent_name":"PaymentRequestResult"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest27requiresPaymentDataForTokenSS10completionFV10Foundation4DataT__T_":{"name":"paymentRequest(_:requiresPaymentDataForToken:completion:)","abstract":"
Given the PaymentRequest
that started the payment flow and token
, waits for data from merchant server to be passed via completion
.
","parent_name":"PaymentRequestDelegate"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest25requiresPaymentMethodFromGSqGSaCS_13PaymentMethod__9availableGSaS2__10completionFS2_T__T_":{"name":"paymentRequest(_:requiresPaymentMethodFrom:available:completion:)","abstract":"
Given a list of PaymentMethod
(available and preferred) waits for the selection via completion
.
","parent_name":"PaymentRequestDelegate"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest21requiresReturnURLFromV10Foundation3URL10completionFS3_T__T_":{"name":"paymentRequest(_:requiresReturnURLFrom:completion:)","abstract":"
This method is called when a URL redirection needs to be executed. Use the url
to continue payment flow in Safari or SFSafariViewController
. After the process is completed, the completion
for the given URL must be called.
","parent_name":"PaymentRequestDelegate"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest22requiresPaymentDetailsCS_14PaymentDetails10completionFS2_T__T_":{"name":"paymentRequest(_:requiresPaymentDetails:completion:)","abstract":"
This method is called when input is needed for completing the transation. The filled PaymentDetails
should be sent via completion
.
","parent_name":"PaymentRequestDelegate"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest13didFinishWithOS_20PaymentRequestResult_T_":{"name":"paymentRequest(_:didFinishWith:)","abstract":"
This method is called when the payment flow is finished.
","parent_name":"PaymentRequestDelegate"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest8delegateXwGSqPS_22PaymentRequestDelegate__":{"name":"delegate","abstract":"
Delegate for controlling the payment flow. See PaymentRequestDelegate
.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest13paymentMethodGSqCS_13PaymentMethod_":{"name":"paymentMethod","abstract":"
The selected payment method.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest6amountGSqSi_":{"name":"amount","abstract":"
Amount to be charged.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest8currencyGSqSS_":{"name":"currency","abstract":"
Payment currency.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest9referenceGSqSS_":{"name":"reference","abstract":"
Payment reference.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest11countryCodeGSqSS_":{"name":"countryCode","abstract":"
Payment country code.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest13shopperLocaleGSqSS_":{"name":"shopperLocale","abstract":"
Shopper locale.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest16shopperReferenceGSqSS_":{"name":"shopperReference","abstract":"
Shopper reference.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest14generationTimeGSqSS_":{"name":"generationTime","abstract":"
Generation time. Used for generating a token for card payments.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest9publicKeyGSqSS_":{"name":"publicKey","abstract":"
Public key. Used for generating a token for card payments.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:FC5Adyen14PaymentRequestcFT8delegatePS_22PaymentRequestDelegate__S0_":{"name":"init(delegate:)","abstract":"
Creates a PaymentRequest
object and initialises it with a provided delegate.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:FC5Adyen14PaymentRequest5startFT_T_":{"name":"start()","abstract":"
Starts the payment request.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:FC5Adyen14PaymentRequest15deletePreferredFT13paymentMethodCS_13PaymentMethod10completionFTSbGSqOS_5Error__T__T_":{"name":"deletePreferred(paymentMethod:completion:)","abstract":"
Permanently deletes payment method from shopper’s preferred payment options.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:FC5Adyen14PaymentRequest6cancelFT_T_":{"name":"cancel()","abstract":"
Cancels the payment request.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html":{"name":"PaymentRequest","abstract":"
This class is the starting point for Custom Integration .
"},"Protocols/PaymentRequestDelegate.html":{"name":"PaymentRequestDelegate","abstract":"
The payment request delegate. Used for Custom integration comunication. All delegate methods are invoked on the main thread.
"},"Enums/PaymentRequestResult.html":{"name":"PaymentRequestResult","abstract":"
Result of a payment request.
"},"Enums/Error.html":{"name":"Error","abstract":"
Error type.
"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus8receivedFMS0_S0_":{"name":"received","abstract":"
Payment pending.
","parent_name":"PaymentStatus"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus10authorisedFMS0_S0_":{"name":"authorised","abstract":"
Payment authorised.
","parent_name":"PaymentStatus"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus5errorFMS0_S0_":{"name":"error","abstract":"
Payment error.
","parent_name":"PaymentStatus"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus7refusedFMS0_S0_":{"name":"refused","abstract":"
Payment refused.
","parent_name":"PaymentStatus"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus9cancelledFMS0_S0_":{"name":"cancelled","abstract":"
Payment cancelled.
","parent_name":"PaymentStatus"},"Classes/Payment.html#/s:vC5Adyen7Payment6statusOS_13PaymentStatus":{"name":"status","abstract":"
The status of the payment.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment6methodCS_13PaymentMethod":{"name":"method","abstract":"
The method that was used to complete the payment.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment7payloadSS":{"name":"payload","abstract":"
The payload as returned from the server.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment6amountSi":{"name":"amount","abstract":"
The amount of the payment, in minor units.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment12currencyCodeSS":{"name":"currencyCode","abstract":"
The code of the currency for the payment amount.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment17merchantReferenceSS":{"name":"merchantReference","abstract":"
The reference of the merchant.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment16shopperReferenceGSqSS_":{"name":"shopperReference","abstract":"
The reference of the shopper.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment18shopperCountryCodeSS":{"name":"shopperCountryCode","abstract":"
The country code of the shopper.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment23shopperLocaleIdentifierGSqSS_":{"name":"shopperLocaleIdentifier","abstract":"
The locale identifier of the shopper.
","parent_name":"Payment"},"Classes/Payment.html":{"name":"Payment","abstract":"
Represents a payment that has been completed by the user. The result of the payment can be retrieved via the status
property.
"},"Enums/PaymentStatus.html":{"name":"PaymentStatus","abstract":"
Payment statuses.
"},"Classes/AppearanceConfiguration.html#/s:FC5Adyen23AppearanceConfigurationcFT_S0_":{"name":"init()","abstract":"
Initializes the appearance configuration.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration23preferredStatusBarStyleOSC16UIStatusBarStyle":{"name":"preferredStatusBarStyle","abstract":"
The preferred status bar style.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration32navigationBarTitleTextAttributesGSqGVs10DictionarySSP___":{"name":"navigationBarTitleTextAttributes","abstract":"
The attributes used for the navigation bar’s title.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration22navigationBarTintColorGSqCSo7UIColor_":{"name":"navigationBarTintColor","abstract":"
The navigation bar’s tint color.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration28navigationBarBackgroundColorGSqCSo7UIColor_":{"name":"navigationBarBackgroundColor","abstract":"
The navigation bar’s background color.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration26isNavigationBarTranslucentSb":{"name":"isNavigationBarTranslucent","abstract":"
A Boolean value indicating whether the navigation bar is translucent.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration30navigationBarCancelButtonImageGSqCSo7UIImage_":{"name":"navigationBarCancelButtonImage","abstract":"
The image of the cancel button in the navigation bar, or nil
if a title should be used instead.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration33checkoutButtonTitleTextAttributesGSqGVs10DictionarySSP___":{"name":"checkoutButtonTitleTextAttributes","abstract":"
The attributes used for the checkout button’s title.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration29checkoutButtonTitleEdgeInsetsGSqVSC12UIEdgeInsets_":{"name":"checkoutButtonTitleEdgeInsets","abstract":"
The insets from the edges of the checkout button to the title.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration26checkoutButtonCornerRadiusV12CoreGraphics7CGFloat":{"name":"checkoutButtonCornerRadius","abstract":"
The corner radius of the checkout button.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration9tintColorGSqCSo7UIColor_":{"name":"tintColor","abstract":"
The tint color of most buttons and actionable elements.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:ZvC5Adyen23AppearanceConfiguration7defaultS0_":{"name":"default","abstract":"
The default appearance configuration.
","parent_name":"AppearanceConfiguration"},"Protocols/CheckoutViewControllerDelegate.html#/s:FP5Adyen30CheckoutViewControllerDelegate22checkoutViewControllerFTCS_22CheckoutViewController27requiresPaymentDataForTokenSS10completionFV10Foundation4DataT__T_":{"name":"checkoutViewController(_:requiresPaymentDataForToken:completion:)","abstract":"
Invoked when the payment flow has started and payment data is requested from the merchant server.
","parent_name":"CheckoutViewControllerDelegate"},"Protocols/CheckoutViewControllerDelegate.html#/s:FP5Adyen30CheckoutViewControllerDelegate22checkoutViewControllerFTCS_22CheckoutViewController17requiresReturnURLFV10Foundation3URLT__T_":{"name":"checkoutViewController(_:requiresReturnURL:)","abstract":"
Invoked when the redirection to a URL has been made. The given completion handler should be invoked when the user returns to the application through a URL.
","parent_name":"CheckoutViewControllerDelegate"},"Protocols/CheckoutViewControllerDelegate.html#/s:FP5Adyen30CheckoutViewControllerDelegate22checkoutViewControllerFTCS_22CheckoutViewController13didFinishWithOS_20PaymentRequestResult_T_":{"name":"checkoutViewController(_:didFinishWith:)","abstract":"
Invoked when the payment flow has finished.
","parent_name":"CheckoutViewControllerDelegate"},"Classes/CheckoutViewController.html#/s:vC5Adyen22CheckoutViewController8delegateXwGSqPS_30CheckoutViewControllerDelegate__":{"name":"delegate","abstract":"
The delegate for Quick integration.
","parent_name":"CheckoutViewController"},"Classes/CheckoutViewController.html#/s:FC5Adyen22CheckoutViewControllercFT8delegatePS_30CheckoutViewControllerDelegate_23appearanceConfigurationCS_23AppearanceConfiguration_S0_":{"name":"init(delegate:appearanceConfiguration:)","abstract":"
Initializes the checkout view controller.
","parent_name":"CheckoutViewController"},"Classes/CheckoutViewController.html":{"name":"CheckoutViewController","abstract":"
The starting point for Quick integration . Initialize with CheckoutViewContollerDelegate
and present this view controller in your app to start the payment flow. If you don’t embed the CheckoutViewController
in an existing UINavigationController
, a new one will be created automatically.
"},"Protocols/CheckoutViewControllerDelegate.html":{"name":"CheckoutViewControllerDelegate","abstract":"
The CheckoutViewControllerDelegate
protocol defines the methods that a delegate of CheckoutViewController
should implement to provide payment data and be informed of the payment flow progress.
"},"Classes/AppearanceConfiguration.html":{"name":"AppearanceConfiguration","abstract":"
Provides properties to customize the appearance of the UI components provided by this library."},"UI.html":{"name":"UI"},"Payment.html":{"name":"Payment"},"Payment Request.html":{"name":"Payment Request"},"Payment Method.html":{"name":"Payment Method"},"Utilities.html":{"name":"Utilities"}}
\ No newline at end of file
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/Documents/undocumented.json b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/undocumented.json
new file mode 100644
index 0000000000..69b9469e04
--- /dev/null
+++ b/Docs/docsets/Adyen.docset/Contents/Resources/Documents/undocumented.json
@@ -0,0 +1,6 @@
+{
+ "warnings": [
+
+ ],
+ "source_directory": "/Users/joostv/Repositories/adyen-checkout-ios"
+}
\ No newline at end of file
diff --git a/Docs/docsets/Adyen.docset/Contents/Resources/docSet.dsidx b/Docs/docsets/Adyen.docset/Contents/Resources/docSet.dsidx
new file mode 100644
index 0000000000..c6dc824d01
Binary files /dev/null and b/Docs/docsets/Adyen.docset/Contents/Resources/docSet.dsidx differ
diff --git a/Docs/docsets/Adyen.tgz b/Docs/docsets/Adyen.tgz
new file mode 100644
index 0000000000..5dc7cc8e9e
Binary files /dev/null and b/Docs/docsets/Adyen.tgz differ
diff --git a/Docs/img/carat.png b/Docs/img/carat.png
new file mode 100755
index 0000000000..29d2f7fd49
Binary files /dev/null and b/Docs/img/carat.png differ
diff --git a/Docs/img/dash.png b/Docs/img/dash.png
new file mode 100755
index 0000000000..6f694c7a01
Binary files /dev/null and b/Docs/img/dash.png differ
diff --git a/Docs/img/gh.png b/Docs/img/gh.png
new file mode 100755
index 0000000000..628da97c70
Binary files /dev/null and b/Docs/img/gh.png differ
diff --git a/Docs/img/spinner.gif b/Docs/img/spinner.gif
new file mode 100644
index 0000000000..e3038d0a42
Binary files /dev/null and b/Docs/img/spinner.gif differ
diff --git a/Docs/index.html b/Docs/index.html
new file mode 100644
index 0000000000..ac506ead4e
--- /dev/null
+++ b/Docs/index.html
@@ -0,0 +1,208 @@
+
+
+
+
Adyen Reference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adyen Reference
+
+ Adyen Reference
+
+
+
+
+
+
+
+
+
+
+
+
Adyen SDK for iOS
+
+
With Adyen SDK you can help your shoppers pay with a payment method of their choice, selected from a dynamically generated list of available payment methods. Method availability is based on shoppers’ location, transaction currency, and transaction amount.
+
+
You can integrate the SDK in two ways: either make use of the default UI components and flows preconfigured by Adyen (Quick integration), or implement your own UI and checkout experience (Custom integration).
+
+
+
Installation
+
+
Use CocoaPods to integrate the Adyen SDK into your project. For this, add the following line to your Podfile and run pod install
.
+
pod 'Adyen'
+
+
Quick integration
+
+
If you want to quickly integrate with Adyen, use the default UI elements that we provide for selecting payment methods, entering payment details, and completing a payment.
+
+
For this, instantiate CheckoutViewController
, present it in your app, and implement the CheckoutViewControllerDelegate
protocol for callbacks. All UI interactions are handled by Adyen.
+
let viewController = CheckoutViewController ( delegate : self )
+present ( viewController ! , animated : true )
+
+
+
The following CheckoutViewControllerDelegate
methods should be implemented:
+
- checkoutViewController:requiresPaymentDataForToken:completion:
+
+
This method requires you to fetch payment data from your server and pass it to the completion
handler. Upon receiving valid payment data, the SDK will present a list of available payment methods.
+
+
For your convenience, we provide a test merchant server . You can find information on setting up your own server here .
+
- checkoutViewController:requiresReturnURL:
+
+
This method will be called if a selected payment method requires user authentication outside of your app environment (in a web browser, native banking app, etc.). Upon payment authorisation, your app will be reopened using the application(_:open:options:)
callback of UIApplicationDelegate
. The URL used to open your app should be passed to the completion handler.
+
- checkoutViewController:didFinishWith:
+
+
This method will provide you with the result of the completed payment request (authorised, refused, etc.).
+
+
For implementation details, refer to the Quick integration guide .
+
Custom integration
+
+
With custom integration you will have full control over the payment flow and will be able to implement your own unique checkout experience.
+
+
This approach requires instantiating and starting a PaymentRequest
and implementing the PaymentRequestDelegate
protocol for callbacks. The PaymentRequestDelegate
callbacks will provide you with a list of available payment methods, the URL for payment methods that require an external flow, and the result of payment processing.
+
+
For implementation details, refer to the Custom integration guide .
+
Examples
+
+
You can find examples of both quick and custom integrations in the Examples folder of this repository.
+
See also
+
+
+
License
+
+
This repository is open source and available under the MIT license. For more information, see the LICENSE file.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Docs/js/jazzy.js b/Docs/js/jazzy.js
new file mode 100755
index 0000000000..009c80d387
--- /dev/null
+++ b/Docs/js/jazzy.js
@@ -0,0 +1,43 @@
+window.jazzy = {'docset': false}
+if (typeof window.dash != 'undefined') {
+ document.documentElement.className += ' dash'
+ window.jazzy.docset = true
+}
+if (navigator.userAgent.match(/xcode/i)) {
+ document.documentElement.className += ' xcode'
+ window.jazzy.docset = true
+}
+
+// On doc load, toggle the URL hash discussion if present
+$(document).ready(function() {
+ if (!window.jazzy.docset) {
+ var linkToHash = $('a[href="' + window.location.hash +'"]');
+ linkToHash.trigger("click");
+ }
+});
+
+// On token click, toggle its discussion and animate token.marginLeft
+$(".token").click(function(event) {
+ if (window.jazzy.docset) {
+ return;
+ }
+ var link = $(this);
+ var animationDuration = 300;
+ $content = link.parent().parent().next();
+ $content.slideToggle(animationDuration);
+
+ // Keeps the document from jumping to the hash.
+ var href = $(this).attr('href');
+ if (history.pushState) {
+ history.pushState({}, '', href);
+ } else {
+ location.hash = href;
+ }
+ event.preventDefault();
+});
+
+// Dumb down quotes within code blocks that delimit strings instead of quotations
+// https://github.com/realm/jazzy/issues/714
+$("code q").replaceWith(function () {
+ return ["\"", $(this).contents(), "\""];
+});
diff --git a/Docs/js/jazzy.search.js b/Docs/js/jazzy.search.js
new file mode 100644
index 0000000000..54be83cf71
--- /dev/null
+++ b/Docs/js/jazzy.search.js
@@ -0,0 +1,62 @@
+$(function(){
+ var searchIndex = lunr(function() {
+ this.ref('url');
+ this.field('name');
+ });
+
+ var $typeahead = $('[data-typeahead]');
+ var $form = $typeahead.parents('form');
+ var searchURL = $form.attr('action');
+
+ function displayTemplate(result) {
+ return result.name;
+ }
+
+ function suggestionTemplate(result) {
+ var t = '
';
+ t += '' + result.name + ' ';
+ if (result.parent_name) {
+ t += '' + result.parent_name + ' ';
+ }
+ t += '
';
+ return t;
+ }
+
+ $typeahead.one('focus', function() {
+ $form.addClass('loading');
+
+ $.getJSON(searchURL).then(function(searchData) {
+ $.each(searchData, function (url, doc) {
+ searchIndex.add({url: url, name: doc.name});
+ });
+
+ $typeahead.typeahead(
+ {
+ highlight: true,
+ minLength: 3
+ },
+ {
+ limit: 10,
+ display: displayTemplate,
+ templates: { suggestion: suggestionTemplate },
+ source: function(query, sync) {
+ var results = searchIndex.search(query).map(function(result) {
+ var doc = searchData[result.ref];
+ doc.url = result.ref;
+ return doc;
+ });
+ sync(results);
+ }
+ }
+ );
+ $form.removeClass('loading');
+ $typeahead.trigger('focus');
+ });
+ });
+
+ var baseURL = searchURL.slice(0, -"search.json".length);
+
+ $typeahead.on('typeahead:select', function(e, result) {
+ window.location = baseURL + result.url;
+ });
+});
diff --git a/Docs/js/jquery.min.js b/Docs/js/jquery.min.js
new file mode 100755
index 0000000000..ab28a24729
--- /dev/null
+++ b/Docs/js/jquery.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="
",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d
b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
+if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" a ",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML=" ",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h ]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""," "],legend:[1,""," "],area:[1,""," "],param:[1,""," "],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:k.htmlSerialize?[0,"",""]:[1,"X","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" a ",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
+},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();ca ",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.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(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
diff --git a/Docs/js/lunr.min.js b/Docs/js/lunr.min.js
new file mode 100755
index 0000000000..22776bb85e
--- /dev/null
+++ b/Docs/js/lunr.min.js
@@ -0,0 +1,6 @@
+/**
+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.7.2
+ * Copyright (C) 2016 Oliver Nightingale
+ * @license MIT
+ */
+!function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.7.2",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){if(!arguments.length||null==e||void 0==e)return[];if(Array.isArray(e))return e.map(function(e){return t.utils.asString(e).toLowerCase()});var n=t.tokenizer.seperator||t.tokenizer.separator;return e.toString().trim().toLowerCase().split(n)},t.tokenizer.seperator=!1,t.tokenizer.separator=/[\s\-]+/,t.tokenizer.load=function(t){var e=this.registeredFunctions[t];if(!e)throw new Error("Cannot load un-registered function: "+t);return e},t.tokenizer.label="default",t.tokenizer.registeredFunctions={"default":t.tokenizer},t.tokenizer.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing tokenizer: "+n),e.label=n,this.registeredFunctions[n]=e},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,r=0;n>r;r++){for(var o=t[r],s=0;i>s&&(o=this._stack[s](o,r,t),void 0!==o&&""!==o);s++);void 0!==o&&""!==o&&e.push(o)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(e
n.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(o===t)return r;t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r]}return o===t?r:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,r=e+Math.floor(i/2),o=this.elements[r];i>1;)t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r];return o>t?r:t>o?r+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,r=0,o=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>o-1||r>s-1)break;a[i]!==h[r]?a[i]h[r]&&r++:(n.add(a[i]),i++,r++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone();for(var r=0,o=n.toArray();rp;p++)c[p]===a&&d++;h+=d/f*l.boost}}this.tokenStore.add(a,{ref:o,tf:h})}n&&this.eventEmitter.emit("add",e,this)},t.Index.prototype.remove=function(t,e){var n=t[this._ref],e=void 0===e?!0:e;if(this.documentStore.has(n)){var i=this.documentStore.get(n);this.documentStore.remove(n),i.forEach(function(t){this.tokenStore.remove(t,n)},this),e&&this.eventEmitter.emit("remove",t,this)}},t.Index.prototype.update=function(t,e){var e=void 0===e?!0:e;this.remove(t,!1),this.add(t,!1),e&&this.eventEmitter.emit("update",t,this)},t.Index.prototype.idf=function(t){var e="@"+t;if(Object.prototype.hasOwnProperty.call(this._idfCache,e))return this._idfCache[e];var n=this.tokenStore.count(t),i=1;return n>0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(this.tokenizerFn(e)),i=new t.Vector,r=[],o=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*o,h=this,u=this.tokenStore.expand(e).reduce(function(n,r){var o=h.corpusTokens.indexOf(r),s=h.idf(r),u=1,l=new t.SortedSet;if(r!==e){var c=Math.max(3,r.length-e.length);u=1/Math.log(c)}o>-1&&i.insert(o,a*s*u);for(var f=h.tokenStore.get(r),d=Object.keys(f),p=d.length,v=0;p>v;v++)l.add(f[d[v]].ref);return n.union(l)},new t.SortedSet);r.push(u)},this);var a=r.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,r=new t.Vector,o=0;i>o;o++){var s=n.elements[o],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);r.insert(this.corpusTokens.indexOf(s),a*h)}return r},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,tokenizer:this.tokenizerFn.label,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",r=n+"[^aeiouy]*",o=i+"[aeiou]*",s="^("+r+")?"+o+r,a="^("+r+")?"+o+r+"("+o+")?$",h="^("+r+")?"+o+r+o+r,u="^("+r+")?"+i,l=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(u),p=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,g=/^(.+?)eed$/,m=/^(.+?)(ed|ing)$/,y=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),k=new RegExp("^"+r+i+"[^aeiouwxy]$"),x=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,F=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,_=/^(.+?)(s|t)(ion)$/,z=/^(.+?)e$/,O=/ll$/,P=new RegExp("^"+r+i+"[^aeiouwxy]$"),T=function(n){var i,r,o,s,a,h,u;if(n.length<3)return n;if(o=n.substr(0,1),"y"==o&&(n=o.toUpperCase()+n.substr(1)),s=p,a=v,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=g,a=m,s.test(n)){var T=s.exec(n);s=l,s.test(T[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,u=k,a.test(n)?n+="e":h.test(n)?(s=y,n=n.replace(s,"")):u.test(n)&&(n+="e"))}if(s=x,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+t[r])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+e[r])}if(s=F,a=_,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=z,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=P,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=O,a=c,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==o&&(n=o.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.generateStopWordFilter=function(t){var e=t.reduce(function(t,e){return t[e]=e,t},{});return function(t){return t&&e[t]!==t?t:void 0}},t.stopWordFilter=t.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){return t.replace(/^\W+/,"").replace(/\W+$/,"")},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t.charAt(0),r=t.slice(1);return i in n||(n[i]={docs:{}}),0===r.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(r,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n',
+ menu: ''
+ };
+ }
+ function buildSelectors(classes) {
+ var selectors = {};
+ _.each(classes, function(v, k) {
+ selectors[k] = "." + v;
+ });
+ return selectors;
+ }
+ function buildCss() {
+ var css = {
+ wrapper: {
+ position: "relative",
+ display: "inline-block"
+ },
+ hint: {
+ position: "absolute",
+ top: "0",
+ left: "0",
+ borderColor: "transparent",
+ boxShadow: "none",
+ opacity: "1"
+ },
+ input: {
+ position: "relative",
+ verticalAlign: "top",
+ backgroundColor: "transparent"
+ },
+ inputWithNoHint: {
+ position: "relative",
+ verticalAlign: "top"
+ },
+ menu: {
+ position: "absolute",
+ top: "100%",
+ left: "0",
+ zIndex: "100",
+ display: "none"
+ },
+ ltr: {
+ left: "0",
+ right: "auto"
+ },
+ rtl: {
+ left: "auto",
+ right: " 0"
+ }
+ };
+ if (_.isMsie()) {
+ _.mixin(css.input, {
+ backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
+ });
+ }
+ return css;
+ }
+ }();
+ var EventBus = function() {
+ "use strict";
+ var namespace, deprecationMap;
+ namespace = "typeahead:";
+ deprecationMap = {
+ render: "rendered",
+ cursorchange: "cursorchanged",
+ select: "selected",
+ autocomplete: "autocompleted"
+ };
+ function EventBus(o) {
+ if (!o || !o.el) {
+ $.error("EventBus initialized without el");
+ }
+ this.$el = $(o.el);
+ }
+ _.mixin(EventBus.prototype, {
+ _trigger: function(type, args) {
+ var $e;
+ $e = $.Event(namespace + type);
+ (args = args || []).unshift($e);
+ this.$el.trigger.apply(this.$el, args);
+ return $e;
+ },
+ before: function(type) {
+ var args, $e;
+ args = [].slice.call(arguments, 1);
+ $e = this._trigger("before" + type, args);
+ return $e.isDefaultPrevented();
+ },
+ trigger: function(type) {
+ var deprecatedType;
+ this._trigger(type, [].slice.call(arguments, 1));
+ if (deprecatedType = deprecationMap[type]) {
+ this._trigger(deprecatedType, [].slice.call(arguments, 1));
+ }
+ }
+ });
+ return EventBus;
+ }();
+ var EventEmitter = function() {
+ "use strict";
+ var splitter = /\s+/, nextTick = getNextTick();
+ return {
+ onSync: onSync,
+ onAsync: onAsync,
+ off: off,
+ trigger: trigger
+ };
+ function on(method, types, cb, context) {
+ var type;
+ if (!cb) {
+ return this;
+ }
+ types = types.split(splitter);
+ cb = context ? bindContext(cb, context) : cb;
+ this._callbacks = this._callbacks || {};
+ while (type = types.shift()) {
+ this._callbacks[type] = this._callbacks[type] || {
+ sync: [],
+ async: []
+ };
+ this._callbacks[type][method].push(cb);
+ }
+ return this;
+ }
+ function onAsync(types, cb, context) {
+ return on.call(this, "async", types, cb, context);
+ }
+ function onSync(types, cb, context) {
+ return on.call(this, "sync", types, cb, context);
+ }
+ function off(types) {
+ var type;
+ if (!this._callbacks) {
+ return this;
+ }
+ types = types.split(splitter);
+ while (type = types.shift()) {
+ delete this._callbacks[type];
+ }
+ return this;
+ }
+ function trigger(types) {
+ var type, callbacks, args, syncFlush, asyncFlush;
+ if (!this._callbacks) {
+ return this;
+ }
+ types = types.split(splitter);
+ args = [].slice.call(arguments, 1);
+ while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
+ syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
+ asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
+ syncFlush() && nextTick(asyncFlush);
+ }
+ return this;
+ }
+ function getFlush(callbacks, context, args) {
+ return flush;
+ function flush() {
+ var cancelled;
+ for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
+ cancelled = callbacks[i].apply(context, args) === false;
+ }
+ return !cancelled;
+ }
+ }
+ function getNextTick() {
+ var nextTickFn;
+ if (window.setImmediate) {
+ nextTickFn = function nextTickSetImmediate(fn) {
+ setImmediate(function() {
+ fn();
+ });
+ };
+ } else {
+ nextTickFn = function nextTickSetTimeout(fn) {
+ setTimeout(function() {
+ fn();
+ }, 0);
+ };
+ }
+ return nextTickFn;
+ }
+ function bindContext(fn, context) {
+ return fn.bind ? fn.bind(context) : function() {
+ fn.apply(context, [].slice.call(arguments, 0));
+ };
+ }
+ }();
+ var highlight = function(doc) {
+ "use strict";
+ var defaults = {
+ node: null,
+ pattern: null,
+ tagName: "strong",
+ className: null,
+ wordsOnly: false,
+ caseSensitive: false
+ };
+ return function hightlight(o) {
+ var regex;
+ o = _.mixin({}, defaults, o);
+ if (!o.node || !o.pattern) {
+ return;
+ }
+ o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
+ regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
+ traverse(o.node, hightlightTextNode);
+ function hightlightTextNode(textNode) {
+ var match, patternNode, wrapperNode;
+ if (match = regex.exec(textNode.data)) {
+ wrapperNode = doc.createElement(o.tagName);
+ o.className && (wrapperNode.className = o.className);
+ patternNode = textNode.splitText(match.index);
+ patternNode.splitText(match[0].length);
+ wrapperNode.appendChild(patternNode.cloneNode(true));
+ textNode.parentNode.replaceChild(wrapperNode, patternNode);
+ }
+ return !!match;
+ }
+ function traverse(el, hightlightTextNode) {
+ var childNode, TEXT_NODE_TYPE = 3;
+ for (var i = 0; i < el.childNodes.length; i++) {
+ childNode = el.childNodes[i];
+ if (childNode.nodeType === TEXT_NODE_TYPE) {
+ i += hightlightTextNode(childNode) ? 1 : 0;
+ } else {
+ traverse(childNode, hightlightTextNode);
+ }
+ }
+ }
+ };
+ function getRegex(patterns, caseSensitive, wordsOnly) {
+ var escapedPatterns = [], regexStr;
+ for (var i = 0, len = patterns.length; i < len; i++) {
+ escapedPatterns.push(_.escapeRegExChars(patterns[i]));
+ }
+ regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
+ return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
+ }
+ }(window.document);
+ var Input = function() {
+ "use strict";
+ var specialKeyCodeMap;
+ specialKeyCodeMap = {
+ 9: "tab",
+ 27: "esc",
+ 37: "left",
+ 39: "right",
+ 13: "enter",
+ 38: "up",
+ 40: "down"
+ };
+ function Input(o, www) {
+ o = o || {};
+ if (!o.input) {
+ $.error("input is missing");
+ }
+ www.mixin(this);
+ this.$hint = $(o.hint);
+ this.$input = $(o.input);
+ this.query = this.$input.val();
+ this.queryWhenFocused = this.hasFocus() ? this.query : null;
+ this.$overflowHelper = buildOverflowHelper(this.$input);
+ this._checkLanguageDirection();
+ if (this.$hint.length === 0) {
+ this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
+ }
+ }
+ Input.normalizeQuery = function(str) {
+ return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
+ };
+ _.mixin(Input.prototype, EventEmitter, {
+ _onBlur: function onBlur() {
+ this.resetInputValue();
+ this.trigger("blurred");
+ },
+ _onFocus: function onFocus() {
+ this.queryWhenFocused = this.query;
+ this.trigger("focused");
+ },
+ _onKeydown: function onKeydown($e) {
+ var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
+ this._managePreventDefault(keyName, $e);
+ if (keyName && this._shouldTrigger(keyName, $e)) {
+ this.trigger(keyName + "Keyed", $e);
+ }
+ },
+ _onInput: function onInput() {
+ this._setQuery(this.getInputValue());
+ this.clearHintIfInvalid();
+ this._checkLanguageDirection();
+ },
+ _managePreventDefault: function managePreventDefault(keyName, $e) {
+ var preventDefault;
+ switch (keyName) {
+ case "up":
+ case "down":
+ preventDefault = !withModifier($e);
+ break;
+
+ default:
+ preventDefault = false;
+ }
+ preventDefault && $e.preventDefault();
+ },
+ _shouldTrigger: function shouldTrigger(keyName, $e) {
+ var trigger;
+ switch (keyName) {
+ case "tab":
+ trigger = !withModifier($e);
+ break;
+
+ default:
+ trigger = true;
+ }
+ return trigger;
+ },
+ _checkLanguageDirection: function checkLanguageDirection() {
+ var dir = (this.$input.css("direction") || "ltr").toLowerCase();
+ if (this.dir !== dir) {
+ this.dir = dir;
+ this.$hint.attr("dir", dir);
+ this.trigger("langDirChanged", dir);
+ }
+ },
+ _setQuery: function setQuery(val, silent) {
+ var areEquivalent, hasDifferentWhitespace;
+ areEquivalent = areQueriesEquivalent(val, this.query);
+ hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false;
+ this.query = val;
+ if (!silent && !areEquivalent) {
+ this.trigger("queryChanged", this.query);
+ } else if (!silent && hasDifferentWhitespace) {
+ this.trigger("whitespaceChanged", this.query);
+ }
+ },
+ bind: function() {
+ var that = this, onBlur, onFocus, onKeydown, onInput;
+ onBlur = _.bind(this._onBlur, this);
+ onFocus = _.bind(this._onFocus, this);
+ onKeydown = _.bind(this._onKeydown, this);
+ onInput = _.bind(this._onInput, this);
+ this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
+ if (!_.isMsie() || _.isMsie() > 9) {
+ this.$input.on("input.tt", onInput);
+ } else {
+ this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
+ if (specialKeyCodeMap[$e.which || $e.keyCode]) {
+ return;
+ }
+ _.defer(_.bind(that._onInput, that, $e));
+ });
+ }
+ return this;
+ },
+ focus: function focus() {
+ this.$input.focus();
+ },
+ blur: function blur() {
+ this.$input.blur();
+ },
+ getLangDir: function getLangDir() {
+ return this.dir;
+ },
+ getQuery: function getQuery() {
+ return this.query || "";
+ },
+ setQuery: function setQuery(val, silent) {
+ this.setInputValue(val);
+ this._setQuery(val, silent);
+ },
+ hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() {
+ return this.query !== this.queryWhenFocused;
+ },
+ getInputValue: function getInputValue() {
+ return this.$input.val();
+ },
+ setInputValue: function setInputValue(value) {
+ this.$input.val(value);
+ this.clearHintIfInvalid();
+ this._checkLanguageDirection();
+ },
+ resetInputValue: function resetInputValue() {
+ this.setInputValue(this.query);
+ },
+ getHint: function getHint() {
+ return this.$hint.val();
+ },
+ setHint: function setHint(value) {
+ this.$hint.val(value);
+ },
+ clearHint: function clearHint() {
+ this.setHint("");
+ },
+ clearHintIfInvalid: function clearHintIfInvalid() {
+ var val, hint, valIsPrefixOfHint, isValid;
+ val = this.getInputValue();
+ hint = this.getHint();
+ valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
+ isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
+ !isValid && this.clearHint();
+ },
+ hasFocus: function hasFocus() {
+ return this.$input.is(":focus");
+ },
+ hasOverflow: function hasOverflow() {
+ var constraint = this.$input.width() - 2;
+ this.$overflowHelper.text(this.getInputValue());
+ return this.$overflowHelper.width() >= constraint;
+ },
+ isCursorAtEnd: function() {
+ var valueLength, selectionStart, range;
+ valueLength = this.$input.val().length;
+ selectionStart = this.$input[0].selectionStart;
+ if (_.isNumber(selectionStart)) {
+ return selectionStart === valueLength;
+ } else if (document.selection) {
+ range = document.selection.createRange();
+ range.moveStart("character", -valueLength);
+ return valueLength === range.text.length;
+ }
+ return true;
+ },
+ destroy: function destroy() {
+ this.$hint.off(".tt");
+ this.$input.off(".tt");
+ this.$overflowHelper.remove();
+ this.$hint = this.$input = this.$overflowHelper = $("");
+ }
+ });
+ return Input;
+ function buildOverflowHelper($input) {
+ return $('
').css({
+ position: "absolute",
+ visibility: "hidden",
+ whiteSpace: "pre",
+ fontFamily: $input.css("font-family"),
+ fontSize: $input.css("font-size"),
+ fontStyle: $input.css("font-style"),
+ fontVariant: $input.css("font-variant"),
+ fontWeight: $input.css("font-weight"),
+ wordSpacing: $input.css("word-spacing"),
+ letterSpacing: $input.css("letter-spacing"),
+ textIndent: $input.css("text-indent"),
+ textRendering: $input.css("text-rendering"),
+ textTransform: $input.css("text-transform")
+ }).insertAfter($input);
+ }
+ function areQueriesEquivalent(a, b) {
+ return Input.normalizeQuery(a) === Input.normalizeQuery(b);
+ }
+ function withModifier($e) {
+ return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
+ }
+ }();
+ var Dataset = function() {
+ "use strict";
+ var keys, nameGenerator;
+ keys = {
+ val: "tt-selectable-display",
+ obj: "tt-selectable-object"
+ };
+ nameGenerator = _.getIdGenerator();
+ function Dataset(o, www) {
+ o = o || {};
+ o.templates = o.templates || {};
+ o.templates.notFound = o.templates.notFound || o.templates.empty;
+ if (!o.source) {
+ $.error("missing source");
+ }
+ if (!o.node) {
+ $.error("missing node");
+ }
+ if (o.name && !isValidName(o.name)) {
+ $.error("invalid dataset name: " + o.name);
+ }
+ www.mixin(this);
+ this.highlight = !!o.highlight;
+ this.name = o.name || nameGenerator();
+ this.limit = o.limit || 5;
+ this.displayFn = getDisplayFn(o.display || o.displayKey);
+ this.templates = getTemplates(o.templates, this.displayFn);
+ this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
+ this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
+ this._resetLastSuggestion();
+ this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
+ }
+ Dataset.extractData = function extractData(el) {
+ var $el = $(el);
+ if ($el.data(keys.obj)) {
+ return {
+ val: $el.data(keys.val) || "",
+ obj: $el.data(keys.obj) || null
+ };
+ }
+ return null;
+ };
+ _.mixin(Dataset.prototype, EventEmitter, {
+ _overwrite: function overwrite(query, suggestions) {
+ suggestions = suggestions || [];
+ if (suggestions.length) {
+ this._renderSuggestions(query, suggestions);
+ } else if (this.async && this.templates.pending) {
+ this._renderPending(query);
+ } else if (!this.async && this.templates.notFound) {
+ this._renderNotFound(query);
+ } else {
+ this._empty();
+ }
+ this.trigger("rendered", this.name, suggestions, false);
+ },
+ _append: function append(query, suggestions) {
+ suggestions = suggestions || [];
+ if (suggestions.length && this.$lastSuggestion.length) {
+ this._appendSuggestions(query, suggestions);
+ } else if (suggestions.length) {
+ this._renderSuggestions(query, suggestions);
+ } else if (!this.$lastSuggestion.length && this.templates.notFound) {
+ this._renderNotFound(query);
+ }
+ this.trigger("rendered", this.name, suggestions, true);
+ },
+ _renderSuggestions: function renderSuggestions(query, suggestions) {
+ var $fragment;
+ $fragment = this._getSuggestionsFragment(query, suggestions);
+ this.$lastSuggestion = $fragment.children().last();
+ this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions));
+ },
+ _appendSuggestions: function appendSuggestions(query, suggestions) {
+ var $fragment, $lastSuggestion;
+ $fragment = this._getSuggestionsFragment(query, suggestions);
+ $lastSuggestion = $fragment.children().last();
+ this.$lastSuggestion.after($fragment);
+ this.$lastSuggestion = $lastSuggestion;
+ },
+ _renderPending: function renderPending(query) {
+ var template = this.templates.pending;
+ this._resetLastSuggestion();
+ template && this.$el.html(template({
+ query: query,
+ dataset: this.name
+ }));
+ },
+ _renderNotFound: function renderNotFound(query) {
+ var template = this.templates.notFound;
+ this._resetLastSuggestion();
+ template && this.$el.html(template({
+ query: query,
+ dataset: this.name
+ }));
+ },
+ _empty: function empty() {
+ this.$el.empty();
+ this._resetLastSuggestion();
+ },
+ _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) {
+ var that = this, fragment;
+ fragment = document.createDocumentFragment();
+ _.each(suggestions, function getSuggestionNode(suggestion) {
+ var $el, context;
+ context = that._injectQuery(query, suggestion);
+ $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
+ fragment.appendChild($el[0]);
+ });
+ this.highlight && highlight({
+ className: this.classes.highlight,
+ node: fragment,
+ pattern: query
+ });
+ return $(fragment);
+ },
+ _getFooter: function getFooter(query, suggestions) {
+ return this.templates.footer ? this.templates.footer({
+ query: query,
+ suggestions: suggestions,
+ dataset: this.name
+ }) : null;
+ },
+ _getHeader: function getHeader(query, suggestions) {
+ return this.templates.header ? this.templates.header({
+ query: query,
+ suggestions: suggestions,
+ dataset: this.name
+ }) : null;
+ },
+ _resetLastSuggestion: function resetLastSuggestion() {
+ this.$lastSuggestion = $();
+ },
+ _injectQuery: function injectQuery(query, obj) {
+ return _.isObject(obj) ? _.mixin({
+ _query: query
+ }, obj) : obj;
+ },
+ update: function update(query) {
+ var that = this, canceled = false, syncCalled = false, rendered = 0;
+ this.cancel();
+ this.cancel = function cancel() {
+ canceled = true;
+ that.cancel = $.noop;
+ that.async && that.trigger("asyncCanceled", query);
+ };
+ this.source(query, sync, async);
+ !syncCalled && sync([]);
+ function sync(suggestions) {
+ if (syncCalled) {
+ return;
+ }
+ syncCalled = true;
+ suggestions = (suggestions || []).slice(0, that.limit);
+ rendered = suggestions.length;
+ that._overwrite(query, suggestions);
+ if (rendered < that.limit && that.async) {
+ that.trigger("asyncRequested", query);
+ }
+ }
+ function async(suggestions) {
+ suggestions = suggestions || [];
+ if (!canceled && rendered < that.limit) {
+ that.cancel = $.noop;
+ rendered += suggestions.length;
+ that._append(query, suggestions.slice(0, that.limit - rendered));
+ that.async && that.trigger("asyncReceived", query);
+ }
+ }
+ },
+ cancel: $.noop,
+ clear: function clear() {
+ this._empty();
+ this.cancel();
+ this.trigger("cleared");
+ },
+ isEmpty: function isEmpty() {
+ return this.$el.is(":empty");
+ },
+ destroy: function destroy() {
+ this.$el = $("
");
+ }
+ });
+ return Dataset;
+ function getDisplayFn(display) {
+ display = display || _.stringify;
+ return _.isFunction(display) ? display : displayFn;
+ function displayFn(obj) {
+ return obj[display];
+ }
+ }
+ function getTemplates(templates, displayFn) {
+ return {
+ notFound: templates.notFound && _.templatify(templates.notFound),
+ pending: templates.pending && _.templatify(templates.pending),
+ header: templates.header && _.templatify(templates.header),
+ footer: templates.footer && _.templatify(templates.footer),
+ suggestion: templates.suggestion || suggestionTemplate
+ };
+ function suggestionTemplate(context) {
+ return $("
").text(displayFn(context));
+ }
+ }
+ function isValidName(str) {
+ return /^[_a-zA-Z0-9-]+$/.test(str);
+ }
+ }();
+ var Menu = function() {
+ "use strict";
+ function Menu(o, www) {
+ var that = this;
+ o = o || {};
+ if (!o.node) {
+ $.error("node is required");
+ }
+ www.mixin(this);
+ this.$node = $(o.node);
+ this.query = null;
+ this.datasets = _.map(o.datasets, initializeDataset);
+ function initializeDataset(oDataset) {
+ var node = that.$node.find(oDataset.node).first();
+ oDataset.node = node.length ? node : $("
").appendTo(that.$node);
+ return new Dataset(oDataset, www);
+ }
+ }
+ _.mixin(Menu.prototype, EventEmitter, {
+ _onSelectableClick: function onSelectableClick($e) {
+ this.trigger("selectableClicked", $($e.currentTarget));
+ },
+ _onRendered: function onRendered(type, dataset, suggestions, async) {
+ this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
+ this.trigger("datasetRendered", dataset, suggestions, async);
+ },
+ _onCleared: function onCleared() {
+ this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
+ this.trigger("datasetCleared");
+ },
+ _propagate: function propagate() {
+ this.trigger.apply(this, arguments);
+ },
+ _allDatasetsEmpty: function allDatasetsEmpty() {
+ return _.every(this.datasets, isDatasetEmpty);
+ function isDatasetEmpty(dataset) {
+ return dataset.isEmpty();
+ }
+ },
+ _getSelectables: function getSelectables() {
+ return this.$node.find(this.selectors.selectable);
+ },
+ _removeCursor: function _removeCursor() {
+ var $selectable = this.getActiveSelectable();
+ $selectable && $selectable.removeClass(this.classes.cursor);
+ },
+ _ensureVisible: function ensureVisible($el) {
+ var elTop, elBottom, nodeScrollTop, nodeHeight;
+ elTop = $el.position().top;
+ elBottom = elTop + $el.outerHeight(true);
+ nodeScrollTop = this.$node.scrollTop();
+ nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10);
+ if (elTop < 0) {
+ this.$node.scrollTop(nodeScrollTop + elTop);
+ } else if (nodeHeight < elBottom) {
+ this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
+ }
+ },
+ bind: function() {
+ var that = this, onSelectableClick;
+ onSelectableClick = _.bind(this._onSelectableClick, this);
+ this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
+ _.each(this.datasets, function(dataset) {
+ dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
+ });
+ return this;
+ },
+ isOpen: function isOpen() {
+ return this.$node.hasClass(this.classes.open);
+ },
+ open: function open() {
+ this.$node.addClass(this.classes.open);
+ },
+ close: function close() {
+ this.$node.removeClass(this.classes.open);
+ this._removeCursor();
+ },
+ setLanguageDirection: function setLanguageDirection(dir) {
+ this.$node.attr("dir", dir);
+ },
+ selectableRelativeToCursor: function selectableRelativeToCursor(delta) {
+ var $selectables, $oldCursor, oldIndex, newIndex;
+ $oldCursor = this.getActiveSelectable();
+ $selectables = this._getSelectables();
+ oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1;
+ newIndex = oldIndex + delta;
+ newIndex = (newIndex + 1) % ($selectables.length + 1) - 1;
+ newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex;
+ return newIndex === -1 ? null : $selectables.eq(newIndex);
+ },
+ setCursor: function setCursor($selectable) {
+ this._removeCursor();
+ if ($selectable = $selectable && $selectable.first()) {
+ $selectable.addClass(this.classes.cursor);
+ this._ensureVisible($selectable);
+ }
+ },
+ getSelectableData: function getSelectableData($el) {
+ return $el && $el.length ? Dataset.extractData($el) : null;
+ },
+ getActiveSelectable: function getActiveSelectable() {
+ var $selectable = this._getSelectables().filter(this.selectors.cursor).first();
+ return $selectable.length ? $selectable : null;
+ },
+ getTopSelectable: function getTopSelectable() {
+ var $selectable = this._getSelectables().first();
+ return $selectable.length ? $selectable : null;
+ },
+ update: function update(query) {
+ var isValidUpdate = query !== this.query;
+ if (isValidUpdate) {
+ this.query = query;
+ _.each(this.datasets, updateDataset);
+ }
+ return isValidUpdate;
+ function updateDataset(dataset) {
+ dataset.update(query);
+ }
+ },
+ empty: function empty() {
+ _.each(this.datasets, clearDataset);
+ this.query = null;
+ this.$node.addClass(this.classes.empty);
+ function clearDataset(dataset) {
+ dataset.clear();
+ }
+ },
+ destroy: function destroy() {
+ this.$node.off(".tt");
+ this.$node = $("
");
+ _.each(this.datasets, destroyDataset);
+ function destroyDataset(dataset) {
+ dataset.destroy();
+ }
+ }
+ });
+ return Menu;
+ }();
+ var DefaultMenu = function() {
+ "use strict";
+ var s = Menu.prototype;
+ function DefaultMenu() {
+ Menu.apply(this, [].slice.call(arguments, 0));
+ }
+ _.mixin(DefaultMenu.prototype, Menu.prototype, {
+ open: function open() {
+ !this._allDatasetsEmpty() && this._show();
+ return s.open.apply(this, [].slice.call(arguments, 0));
+ },
+ close: function close() {
+ this._hide();
+ return s.close.apply(this, [].slice.call(arguments, 0));
+ },
+ _onRendered: function onRendered() {
+ if (this._allDatasetsEmpty()) {
+ this._hide();
+ } else {
+ this.isOpen() && this._show();
+ }
+ return s._onRendered.apply(this, [].slice.call(arguments, 0));
+ },
+ _onCleared: function onCleared() {
+ if (this._allDatasetsEmpty()) {
+ this._hide();
+ } else {
+ this.isOpen() && this._show();
+ }
+ return s._onCleared.apply(this, [].slice.call(arguments, 0));
+ },
+ setLanguageDirection: function setLanguageDirection(dir) {
+ this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl);
+ return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0));
+ },
+ _hide: function hide() {
+ this.$node.hide();
+ },
+ _show: function show() {
+ this.$node.css("display", "block");
+ }
+ });
+ return DefaultMenu;
+ }();
+ var Typeahead = function() {
+ "use strict";
+ function Typeahead(o, www) {
+ var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged;
+ o = o || {};
+ if (!o.input) {
+ $.error("missing input");
+ }
+ if (!o.menu) {
+ $.error("missing menu");
+ }
+ if (!o.eventBus) {
+ $.error("missing event bus");
+ }
+ www.mixin(this);
+ this.eventBus = o.eventBus;
+ this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
+ this.input = o.input;
+ this.menu = o.menu;
+ this.enabled = true;
+ this.active = false;
+ this.input.hasFocus() && this.activate();
+ this.dir = this.input.getLangDir();
+ this._hacks();
+ this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this);
+ onFocused = c(this, "activate", "open", "_onFocused");
+ onBlurred = c(this, "deactivate", "_onBlurred");
+ onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed");
+ onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed");
+ onEscKeyed = c(this, "isActive", "_onEscKeyed");
+ onUpKeyed = c(this, "isActive", "open", "_onUpKeyed");
+ onDownKeyed = c(this, "isActive", "open", "_onDownKeyed");
+ onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed");
+ onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed");
+ onQueryChanged = c(this, "_openIfActive", "_onQueryChanged");
+ onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged");
+ this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this);
+ }
+ _.mixin(Typeahead.prototype, {
+ _hacks: function hacks() {
+ var $input, $menu;
+ $input = this.input.$input || $("
");
+ $menu = this.menu.$node || $("
");
+ $input.on("blur.tt", function($e) {
+ var active, isActive, hasActive;
+ active = document.activeElement;
+ isActive = $menu.is(active);
+ hasActive = $menu.has(active).length > 0;
+ if (_.isMsie() && (isActive || hasActive)) {
+ $e.preventDefault();
+ $e.stopImmediatePropagation();
+ _.defer(function() {
+ $input.focus();
+ });
+ }
+ });
+ $menu.on("mousedown.tt", function($e) {
+ $e.preventDefault();
+ });
+ },
+ _onSelectableClicked: function onSelectableClicked(type, $el) {
+ this.select($el);
+ },
+ _onDatasetCleared: function onDatasetCleared() {
+ this._updateHint();
+ },
+ _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {
+ this._updateHint();
+ this.eventBus.trigger("render", suggestions, async, dataset);
+ },
+ _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
+ this.eventBus.trigger("asyncrequest", query, dataset);
+ },
+ _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {
+ this.eventBus.trigger("asynccancel", query, dataset);
+ },
+ _onAsyncReceived: function onAsyncReceived(type, dataset, query) {
+ this.eventBus.trigger("asyncreceive", query, dataset);
+ },
+ _onFocused: function onFocused() {
+ this._minLengthMet() && this.menu.update(this.input.getQuery());
+ },
+ _onBlurred: function onBlurred() {
+ if (this.input.hasQueryChangedSinceLastFocus()) {
+ this.eventBus.trigger("change", this.input.getQuery());
+ }
+ },
+ _onEnterKeyed: function onEnterKeyed(type, $e) {
+ var $selectable;
+ if ($selectable = this.menu.getActiveSelectable()) {
+ this.select($selectable) && $e.preventDefault();
+ }
+ },
+ _onTabKeyed: function onTabKeyed(type, $e) {
+ var $selectable;
+ if ($selectable = this.menu.getActiveSelectable()) {
+ this.select($selectable) && $e.preventDefault();
+ } else if ($selectable = this.menu.getTopSelectable()) {
+ this.autocomplete($selectable) && $e.preventDefault();
+ }
+ },
+ _onEscKeyed: function onEscKeyed() {
+ this.close();
+ },
+ _onUpKeyed: function onUpKeyed() {
+ this.moveCursor(-1);
+ },
+ _onDownKeyed: function onDownKeyed() {
+ this.moveCursor(+1);
+ },
+ _onLeftKeyed: function onLeftKeyed() {
+ if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
+ this.autocomplete(this.menu.getTopSelectable());
+ }
+ },
+ _onRightKeyed: function onRightKeyed() {
+ if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
+ this.autocomplete(this.menu.getTopSelectable());
+ }
+ },
+ _onQueryChanged: function onQueryChanged(e, query) {
+ this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();
+ },
+ _onWhitespaceChanged: function onWhitespaceChanged() {
+ this._updateHint();
+ },
+ _onLangDirChanged: function onLangDirChanged(e, dir) {
+ if (this.dir !== dir) {
+ this.dir = dir;
+ this.menu.setLanguageDirection(dir);
+ }
+ },
+ _openIfActive: function openIfActive() {
+ this.isActive() && this.open();
+ },
+ _minLengthMet: function minLengthMet(query) {
+ query = _.isString(query) ? query : this.input.getQuery() || "";
+ return query.length >= this.minLength;
+ },
+ _updateHint: function updateHint() {
+ var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;
+ $selectable = this.menu.getTopSelectable();
+ data = this.menu.getSelectableData($selectable);
+ val = this.input.getInputValue();
+ if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {
+ query = Input.normalizeQuery(val);
+ escapedQuery = _.escapeRegExChars(query);
+ frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
+ match = frontMatchRegEx.exec(data.val);
+ match && this.input.setHint(val + match[1]);
+ } else {
+ this.input.clearHint();
+ }
+ },
+ isEnabled: function isEnabled() {
+ return this.enabled;
+ },
+ enable: function enable() {
+ this.enabled = true;
+ },
+ disable: function disable() {
+ this.enabled = false;
+ },
+ isActive: function isActive() {
+ return this.active;
+ },
+ activate: function activate() {
+ if (this.isActive()) {
+ return true;
+ } else if (!this.isEnabled() || this.eventBus.before("active")) {
+ return false;
+ } else {
+ this.active = true;
+ this.eventBus.trigger("active");
+ return true;
+ }
+ },
+ deactivate: function deactivate() {
+ if (!this.isActive()) {
+ return true;
+ } else if (this.eventBus.before("idle")) {
+ return false;
+ } else {
+ this.active = false;
+ this.close();
+ this.eventBus.trigger("idle");
+ return true;
+ }
+ },
+ isOpen: function isOpen() {
+ return this.menu.isOpen();
+ },
+ open: function open() {
+ if (!this.isOpen() && !this.eventBus.before("open")) {
+ this.menu.open();
+ this._updateHint();
+ this.eventBus.trigger("open");
+ }
+ return this.isOpen();
+ },
+ close: function close() {
+ if (this.isOpen() && !this.eventBus.before("close")) {
+ this.menu.close();
+ this.input.clearHint();
+ this.input.resetInputValue();
+ this.eventBus.trigger("close");
+ }
+ return !this.isOpen();
+ },
+ setVal: function setVal(val) {
+ this.input.setQuery(_.toStr(val));
+ },
+ getVal: function getVal() {
+ return this.input.getQuery();
+ },
+ select: function select($selectable) {
+ var data = this.menu.getSelectableData($selectable);
+ if (data && !this.eventBus.before("select", data.obj)) {
+ this.input.setQuery(data.val, true);
+ this.eventBus.trigger("select", data.obj);
+ this.close();
+ return true;
+ }
+ return false;
+ },
+ autocomplete: function autocomplete($selectable) {
+ var query, data, isValid;
+ query = this.input.getQuery();
+ data = this.menu.getSelectableData($selectable);
+ isValid = data && query !== data.val;
+ if (isValid && !this.eventBus.before("autocomplete", data.obj)) {
+ this.input.setQuery(data.val);
+ this.eventBus.trigger("autocomplete", data.obj);
+ return true;
+ }
+ return false;
+ },
+ moveCursor: function moveCursor(delta) {
+ var query, $candidate, data, payload, cancelMove;
+ query = this.input.getQuery();
+ $candidate = this.menu.selectableRelativeToCursor(delta);
+ data = this.menu.getSelectableData($candidate);
+ payload = data ? data.obj : null;
+ cancelMove = this._minLengthMet() && this.menu.update(query);
+ if (!cancelMove && !this.eventBus.before("cursorchange", payload)) {
+ this.menu.setCursor($candidate);
+ if (data) {
+ this.input.setInputValue(data.val);
+ } else {
+ this.input.resetInputValue();
+ this._updateHint();
+ }
+ this.eventBus.trigger("cursorchange", payload);
+ return true;
+ }
+ return false;
+ },
+ destroy: function destroy() {
+ this.input.destroy();
+ this.menu.destroy();
+ }
+ });
+ return Typeahead;
+ function c(ctx) {
+ var methods = [].slice.call(arguments, 1);
+ return function() {
+ var args = [].slice.call(arguments);
+ _.each(methods, function(method) {
+ return ctx[method].apply(ctx, args);
+ });
+ };
+ }
+ }();
+ (function() {
+ "use strict";
+ var old, keys, methods;
+ old = $.fn.typeahead;
+ keys = {
+ www: "tt-www",
+ attrs: "tt-attrs",
+ typeahead: "tt-typeahead"
+ };
+ methods = {
+ initialize: function initialize(o, datasets) {
+ var www;
+ datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
+ o = o || {};
+ www = WWW(o.classNames);
+ return this.each(attach);
+ function attach() {
+ var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor;
+ _.each(datasets, function(d) {
+ d.highlight = !!o.highlight;
+ });
+ $input = $(this);
+ $wrapper = $(www.html.wrapper);
+ $hint = $elOrNull(o.hint);
+ $menu = $elOrNull(o.menu);
+ defaultHint = o.hint !== false && !$hint;
+ defaultMenu = o.menu !== false && !$menu;
+ defaultHint && ($hint = buildHintFromInput($input, www));
+ defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));
+ $hint && $hint.val("");
+ $input = prepInput($input, www);
+ if (defaultHint || defaultMenu) {
+ $wrapper.css(www.css.wrapper);
+ $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);
+ $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null);
+ }
+ MenuConstructor = defaultMenu ? DefaultMenu : Menu;
+ eventBus = new EventBus({
+ el: $input
+ });
+ input = new Input({
+ hint: $hint,
+ input: $input
+ }, www);
+ menu = new MenuConstructor({
+ node: $menu,
+ datasets: datasets
+ }, www);
+ typeahead = new Typeahead({
+ input: input,
+ menu: menu,
+ eventBus: eventBus,
+ minLength: o.minLength
+ }, www);
+ $input.data(keys.www, www);
+ $input.data(keys.typeahead, typeahead);
+ }
+ },
+ isEnabled: function isEnabled() {
+ var enabled;
+ ttEach(this.first(), function(t) {
+ enabled = t.isEnabled();
+ });
+ return enabled;
+ },
+ enable: function enable() {
+ ttEach(this, function(t) {
+ t.enable();
+ });
+ return this;
+ },
+ disable: function disable() {
+ ttEach(this, function(t) {
+ t.disable();
+ });
+ return this;
+ },
+ isActive: function isActive() {
+ var active;
+ ttEach(this.first(), function(t) {
+ active = t.isActive();
+ });
+ return active;
+ },
+ activate: function activate() {
+ ttEach(this, function(t) {
+ t.activate();
+ });
+ return this;
+ },
+ deactivate: function deactivate() {
+ ttEach(this, function(t) {
+ t.deactivate();
+ });
+ return this;
+ },
+ isOpen: function isOpen() {
+ var open;
+ ttEach(this.first(), function(t) {
+ open = t.isOpen();
+ });
+ return open;
+ },
+ open: function open() {
+ ttEach(this, function(t) {
+ t.open();
+ });
+ return this;
+ },
+ close: function close() {
+ ttEach(this, function(t) {
+ t.close();
+ });
+ return this;
+ },
+ select: function select(el) {
+ var success = false, $el = $(el);
+ ttEach(this.first(), function(t) {
+ success = t.select($el);
+ });
+ return success;
+ },
+ autocomplete: function autocomplete(el) {
+ var success = false, $el = $(el);
+ ttEach(this.first(), function(t) {
+ success = t.autocomplete($el);
+ });
+ return success;
+ },
+ moveCursor: function moveCursoe(delta) {
+ var success = false;
+ ttEach(this.first(), function(t) {
+ success = t.moveCursor(delta);
+ });
+ return success;
+ },
+ val: function val(newVal) {
+ var query;
+ if (!arguments.length) {
+ ttEach(this.first(), function(t) {
+ query = t.getVal();
+ });
+ return query;
+ } else {
+ ttEach(this, function(t) {
+ t.setVal(newVal);
+ });
+ return this;
+ }
+ },
+ destroy: function destroy() {
+ ttEach(this, function(typeahead, $input) {
+ revert($input);
+ typeahead.destroy();
+ });
+ return this;
+ }
+ };
+ $.fn.typeahead = function(method) {
+ if (methods[method]) {
+ return methods[method].apply(this, [].slice.call(arguments, 1));
+ } else {
+ return methods.initialize.apply(this, arguments);
+ }
+ };
+ $.fn.typeahead.noConflict = function noConflict() {
+ $.fn.typeahead = old;
+ return this;
+ };
+ function ttEach($els, fn) {
+ $els.each(function() {
+ var $input = $(this), typeahead;
+ (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);
+ });
+ }
+ function buildHintFromInput($input, www) {
+ return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({
+ autocomplete: "off",
+ spellcheck: "false",
+ tabindex: -1
+ });
+ }
+ function prepInput($input, www) {
+ $input.data(keys.attrs, {
+ dir: $input.attr("dir"),
+ autocomplete: $input.attr("autocomplete"),
+ spellcheck: $input.attr("spellcheck"),
+ style: $input.attr("style")
+ });
+ $input.addClass(www.classes.input).attr({
+ autocomplete: "off",
+ spellcheck: false
+ });
+ try {
+ !$input.attr("dir") && $input.attr("dir", "auto");
+ } catch (e) {}
+ return $input;
+ }
+ function getBackgroundStyles($el) {
+ return {
+ backgroundAttachment: $el.css("background-attachment"),
+ backgroundClip: $el.css("background-clip"),
+ backgroundColor: $el.css("background-color"),
+ backgroundImage: $el.css("background-image"),
+ backgroundOrigin: $el.css("background-origin"),
+ backgroundPosition: $el.css("background-position"),
+ backgroundRepeat: $el.css("background-repeat"),
+ backgroundSize: $el.css("background-size")
+ };
+ }
+ function revert($input) {
+ var www, $wrapper;
+ www = $input.data(keys.www);
+ $wrapper = $input.parent().filter(www.selectors.wrapper);
+ _.each($input.data(keys.attrs), function(val, key) {
+ _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
+ });
+ $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input);
+ if ($wrapper.length) {
+ $input.detach().insertAfter($wrapper);
+ $wrapper.remove();
+ }
+ }
+ function $elOrNull(obj) {
+ var isValid, $el;
+ isValid = _.isJQuery(obj) || _.isElement(obj);
+ $el = isValid ? $(obj).first() : [];
+ return $el.length ? $el : null;
+ }
+ })();
+});
\ No newline at end of file
diff --git a/Docs/search.json b/Docs/search.json
new file mode 100644
index 0000000000..ef32685aef
--- /dev/null
+++ b/Docs/search.json
@@ -0,0 +1 @@
+{"Classes/IBANTextField.html#/s:vC5Adyen13IBANTextField4ibanGSqSS_":{"name":"iban","abstract":"
The IBAN entered in the text field, or nil
if no valid IBAN has been entered.
","parent_name":"IBANTextField"},"Classes/IBANValidator.html#/s:ZFC5Adyen13IBANValidator7isValidFSSSb":{"name":"isValid(_:)","abstract":"
Checks if the given string is a valid IBAN value.
","parent_name":"IBANValidator"},"Structs/IBANSpecification.html#/s:vV5Adyen17IBANSpecification11countryCodeSS":{"name":"countryCode","abstract":"
The code of the country to which the specifications apply.
","parent_name":"IBANSpecification"},"Structs/IBANSpecification.html#/s:vV5Adyen17IBANSpecification6lengthSi":{"name":"length","abstract":"
The length of a valid IBAN.
","parent_name":"IBANSpecification"},"Structs/IBANSpecification.html#/s:vV5Adyen17IBANSpecification9structureSS":{"name":"structure","abstract":"
The structure of the underlying BBAN.
","parent_name":"IBANSpecification"},"Structs/IBANSpecification.html#/s:vV5Adyen17IBANSpecification7exampleSS":{"name":"example","abstract":"
An example of a valid IBAN.
","parent_name":"IBANSpecification"},"Structs/IBANSpecification.html#/s:FV5Adyen17IBANSpecificationcFT14forCountryCodeSS_GSqS0__":{"name":"init(forCountryCode:)","abstract":"
Returns the IBAN specification for the country with the given code, or nil
if none could be found.
","parent_name":"IBANSpecification"},"Classes/CardValidator.html#/s:ZFC5Adyen13CardValidator8validateFT10cardNumberSS17acceptedCardTypesGSaOS_8CardType__T7isValidSb4typeGSqS1__15formattedNumberSS_":{"name":"validate(cardNumber:acceptedCardTypes:)","abstract":"
Validates and formats the given card number, and detects its card type.
","parent_name":"CardValidator"},"Classes/CardValidator.html#/s:ZFC5Adyen13CardValidator8validateFT10expiryDateSS9separatorGSqSS__T7isValidSb13formattedDateSS_":{"name":"validate(expiryDate:separator:)","abstract":"
Validates and formats the given expiration date.
","parent_name":"CardValidator"},"Classes/CardValidator.html#/s:ZFC5Adyen13CardValidator8validateFT3cvcSS_T7isValidSb12formattedCvcSS_":{"name":"validate(cvc:)","abstract":"
Validates and formats the given cvc.
","parent_name":"CardValidator"},"Enums/CardType.html#/s:FO5Adyen8CardType24alphaBankBonusMasterCardFMS0_S0_":{"name":"alphaBankBonusMasterCard","abstract":"
Alpha Bank Bonus MasterCard
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType18alphaBankBonusVISAFMS0_S0_":{"name":"alphaBankBonusVISA","abstract":"
Alpha Bank Bonus VISA
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType15americanExpressFMS0_S0_":{"name":"americanExpress","abstract":"
American Express
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType4bcmcFMS0_S0_":{"name":"bcmc","abstract":"
BCMC
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType13bijenkorfCardFMS0_S0_":{"name":"bijenkorfCard","abstract":"
de Bijenkorf Card
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType13carteBancaireFMS0_S0_":{"name":"carteBancaire","abstract":"
Carte Bancaire
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType13chinaUnionPayFMS0_S0_":{"name":"chinaUnionPay","abstract":"
China UnionPay
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType7codensaFMS0_S0_":{"name":"codensa","abstract":"
Codensa
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType7dankortFMS0_S0_":{"name":"dankort","abstract":"
Dankort
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType11dankortVISAFMS0_S0_":{"name":"dankortVISA","abstract":"
Dankort VISA
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType6dinersFMS0_S0_":{"name":"diners","abstract":"
Diners Club
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType8discoverFMS0_S0_":{"name":"discover","abstract":"
Discover
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType3eloFMS0_S0_":{"name":"elo","abstract":"
Elo
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType5hiperFMS0_S0_":{"name":"hiper","abstract":"
Hiper
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType9hipercardFMS0_S0_":{"name":"hipercard","abstract":"
Hipercard
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType3jcbFMS0_S0_":{"name":"jcb","abstract":"
JCB
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType11karenMillenFMS0_S0_":{"name":"karenMillen","abstract":"
KarenMillen
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType7maestroFMS0_S0_":{"name":"maestro","abstract":"
Maestro
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType9maestroUKFMS0_S0_":{"name":"maestroUK","abstract":"
Maestro UK
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType10masterCardFMS0_S0_":{"name":"masterCard","abstract":"
MasterCard
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType3mirFMS0_S0_":{"name":"mir","abstract":"
Mir
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType5oasisFMS0_S0_":{"name":"oasis","abstract":"
Oasis
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType4soloFMS0_S0_":{"name":"solo","abstract":"
Solo
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType4uatpFMS0_S0_":{"name":"uatp","abstract":"
Universal Air Travel Plan
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType8unionPayFMS0_S0_":{"name":"unionPay","abstract":"
UnionPay
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType4visaFMS0_S0_":{"name":"visa","abstract":"
VISA
","parent_name":"CardType"},"Enums/CardType.html#/s:FO5Adyen8CardType9warehouseFMS0_S0_":{"name":"warehouse","abstract":"
The Warehouse
","parent_name":"CardType"},"Enums/CardType.html#/s:ZvO5Adyen8CardType3allGSaS0__":{"name":"all","abstract":"
Array containing all card types in this enum.
","parent_name":"CardType"},"Enums/CardType.html":{"name":"CardType","abstract":"
Enum containing most known types of credit and debit cards.
"},"Classes/CardValidator.html":{"name":"CardValidator","abstract":"
The CardValidator class provides static methods to validate and format card numbers and expiry dates, and to detect card types.
"},"Structs/IBANSpecification.html":{"name":"IBANSpecification","abstract":"
Contains the country-specific specifications for countries that adopt the IBAN standard.
"},"Classes/IBANValidator.html":{"name":"IBANValidator","abstract":"
Provides a static method to validate an IBAN value.
"},"Classes/IBANTextField.html":{"name":"IBANTextField","abstract":"
Provides a text field designed for the entry of an IBAN value. This field formats and validates the IBAN in real time.
"},"Classes/InputSelectItem.html#/s:vC5Adyen15InputSelectItem10identifierSS":{"name":"identifier","abstract":"
Identifier of an item. Should be used to indicate selection of a particular item in InputDetail
object. Assign identifier
to the value
property of the InputDetail
object.
","parent_name":"InputSelectItem"},"Classes/InputSelectItem.html#/s:vC5Adyen15InputSelectItem4nameSS":{"name":"name","abstract":"
Display name of an item.
","parent_name":"InputSelectItem"},"Classes/InputSelectItem.html#/s:vC5Adyen15InputSelectItem8imageURLGSqV10Foundation3URL_":{"name":"imageURL","abstract":"
Contains a URL to image representation of an item, when applicable.
","parent_name":"InputSelectItem"},"Enums/InputType.html#/s:FO5Adyen9InputType4textFMS0_S0_":{"name":"text","abstract":"
Text input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType7booleanFMS0_S0_":{"name":"boolean","abstract":"
Boolean input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType6selectFMS0_S0_":{"name":"select","abstract":"
Input type should be selected from the given list.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType4ibanFMS0_S0_":{"name":"iban","abstract":"
IBAN input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType3cvcFMS0_S0_":{"name":"cvc","abstract":"
CVC input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType9cardTokenFMS0_S0_":{"name":"cardToken","abstract":"
Card token input type.
","parent_name":"InputType"},"Enums/InputType.html#/s:FO5Adyen9InputType13applePayTokenFMS0_S0_":{"name":"applePayToken","abstract":"
Apple Pay token input type.
","parent_name":"InputType"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail4typeOS_9InputType":{"name":"type","abstract":"
The detail type. Check InputType
.
","parent_name":"InputDetail"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail8optionalSb":{"name":"optional","abstract":"
Whether the detail is optional.
","parent_name":"InputDetail"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail5itemsGSqGSaCS_15InputSelectItem__":{"name":"items","abstract":"
Array of InputSelectItem
. Will only be available if type
is .select
.
","parent_name":"InputDetail"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail11stringValueGSqSS_":{"name":"stringValue","abstract":"
Detail string value.
","parent_name":"InputDetail"},"Classes/InputDetail.html#/s:vC5Adyen11InputDetail9boolValueGSqSb_":{"name":"boolValue","abstract":"
Detail bool value.
","parent_name":"InputDetail"},"Classes/PaymentDetails.html#/s:vC5Adyen14PaymentDetails4listGSaCS_11InputDetail_":{"name":"list","abstract":"
List of InputDetail
.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails9setDetailFT5valueSS6forKeySS_T_":{"name":"setDetail(value:forKey:)","abstract":"
Update the detail defined by a given key
with the string value
provided.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails9setDetailFT5valueGSqSb_6forKeySS_T_":{"name":"setDetail(value:forKey:)","abstract":"
Update the detail defined by a given key
with the bool value
provided.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails12fillApplePayFT5tokenSS_T_":{"name":"fillApplePay(token:)","abstract":"
Fill details for the Apple Pay transaction.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails8fillCardFT5tokenSS12storeDetailsGSqSb__T_":{"name":"fillCard(token:storeDetails:)","abstract":"
Fill details for the Card transaction with a token.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails8fillCardFT3cvcSS_T_":{"name":"fillCard(cvc:)","abstract":"
Fill details for the Card transaction with CVC.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails9fillIdealFT16issuerIdentifierSS_T_":{"name":"fillIdeal(issuerIdentifier:)","abstract":"
Fill details for the iDEAL transaction.
","parent_name":"PaymentDetails"},"Classes/PaymentDetails.html#/s:FC5Adyen14PaymentDetails8fillSepaFT4nameSS4ibanSS_T_":{"name":"fillSepa(name:iban:)","abstract":"
Fill details for the SEPA transaction.
","parent_name":"PaymentDetails"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod4nameSS":{"name":"name","abstract":"
The name of the payment method.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod4typeSS":{"name":"type","abstract":"
The payment method type.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod10isOneClickSb":{"name":"isOneClick","abstract":"
A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod7logoURLGSqV10Foundation3URL_":{"name":"logoURL","abstract":"
A URL to the logo of the payment method.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod12inputDetailsGSqGSaCS_11InputDetail__":{"name":"inputDetails","abstract":"
The input details that should be filled in to complete the payment method.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod7membersGSqGSaS0___":{"name":"members","abstract":"
Members of the payment method (only applicable when the receiver is a group).
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html#/s:vC5Adyen13PaymentMethod8oneClickSb":{"name":"oneClick","abstract":"
A Boolean value indicating whether the payment method is a one-click payment method, which means that it can be easily completed by the user.
","parent_name":"PaymentMethod"},"Classes/PaymentMethod.html":{"name":"PaymentMethod","abstract":"
Represents a locale payment method that can be used to complete a payment.
"},"Classes/PaymentDetails.html":{"name":"PaymentDetails","abstract":"
Holds the list of InputDetail
needed for the transaction.
"},"Classes/InputDetail.html":{"name":"InputDetail","abstract":"
The payment detail needed for the transaction."},"Enums/InputType.html":{"name":"InputType","abstract":"
Defines types of payment details.
"},"Classes/InputSelectItem.html":{"name":"InputSelectItem","abstract":"
Represents a selectable item used in InputDetail
with select
type.
"},"Enums/Error.html#/s:FO5Adyen5Error7messageFMS0_FSSS0_":{"name":"message","abstract":"
Error with a message. This enum case is deprecated. Please use serverError
instead.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error11serverErrorFMS0_FSSS0_":{"name":"serverError","abstract":"
Error returned from server.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error12networkErrorFMS0_FPs5Error_S0_":{"name":"networkError","abstract":"
Network error.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error14unexpectedDataFMS0_S0_":{"name":"unexpectedData","abstract":"
Unexpected data or data format.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error15unexpectedErrorFMS0_S0_":{"name":"unexpectedError","abstract":"
Unexpected error.
","parent_name":"Error"},"Enums/Error.html#/s:FO5Adyen5Error8canceledFMS0_S0_":{"name":"canceled","abstract":"
Payment was canceled.
","parent_name":"Error"},"Enums/Error.html#/s:vP10Foundation14LocalizedError16errorDescriptionGSqSS_":{"name":"errorDescription","parent_name":"Error"},"Enums/PaymentRequestResult.html#/s:FO5Adyen20PaymentRequestResult7paymentFMS0_FCS_7PaymentS0_":{"name":"payment","abstract":"
In case of success a Payment
object will be returned.
","parent_name":"PaymentRequestResult"},"Enums/PaymentRequestResult.html#/s:FO5Adyen20PaymentRequestResult5errorFMS0_FOS_5ErrorS0_":{"name":"error","abstract":"
In case of failure an Error
will be returned.
","parent_name":"PaymentRequestResult"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest27requiresPaymentDataForTokenSS10completionFV10Foundation4DataT__T_":{"name":"paymentRequest(_:requiresPaymentDataForToken:completion:)","abstract":"
Given the PaymentRequest
that started the payment flow and token
, waits for data from merchant server to be passed via completion
.
","parent_name":"PaymentRequestDelegate"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest25requiresPaymentMethodFromGSqGSaCS_13PaymentMethod__9availableGSaS2__10completionFS2_T__T_":{"name":"paymentRequest(_:requiresPaymentMethodFrom:available:completion:)","abstract":"
Given a list of PaymentMethod
(available and preferred) waits for the selection via completion
.
","parent_name":"PaymentRequestDelegate"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest21requiresReturnURLFromV10Foundation3URL10completionFS3_T__T_":{"name":"paymentRequest(_:requiresReturnURLFrom:completion:)","abstract":"
This method is called when a URL redirection needs to be executed. Use the url
to continue payment flow in Safari or SFSafariViewController
. After the process is completed, the completion
for the given URL must be called.
","parent_name":"PaymentRequestDelegate"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest22requiresPaymentDetailsCS_14PaymentDetails10completionFS2_T__T_":{"name":"paymentRequest(_:requiresPaymentDetails:completion:)","abstract":"
This method is called when input is needed for completing the transation. The filled PaymentDetails
should be sent via completion
.
","parent_name":"PaymentRequestDelegate"},"Protocols/PaymentRequestDelegate.html#/s:FP5Adyen22PaymentRequestDelegate14paymentRequestFTCS_14PaymentRequest13didFinishWithOS_20PaymentRequestResult_T_":{"name":"paymentRequest(_:didFinishWith:)","abstract":"
This method is called when the payment flow is finished.
","parent_name":"PaymentRequestDelegate"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest8delegateXwGSqPS_22PaymentRequestDelegate__":{"name":"delegate","abstract":"
Delegate for controlling the payment flow. See PaymentRequestDelegate
.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest13paymentMethodGSqCS_13PaymentMethod_":{"name":"paymentMethod","abstract":"
The selected payment method.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest6amountGSqSi_":{"name":"amount","abstract":"
Amount to be charged.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest8currencyGSqSS_":{"name":"currency","abstract":"
Payment currency.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest9referenceGSqSS_":{"name":"reference","abstract":"
Payment reference.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest11countryCodeGSqSS_":{"name":"countryCode","abstract":"
Payment country code.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest13shopperLocaleGSqSS_":{"name":"shopperLocale","abstract":"
Shopper locale.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest16shopperReferenceGSqSS_":{"name":"shopperReference","abstract":"
Shopper reference.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest14generationTimeGSqSS_":{"name":"generationTime","abstract":"
Generation time. Used for generating a token for card payments.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:vC5Adyen14PaymentRequest9publicKeyGSqSS_":{"name":"publicKey","abstract":"
Public key. Used for generating a token for card payments.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:FC5Adyen14PaymentRequestcFT8delegatePS_22PaymentRequestDelegate__S0_":{"name":"init(delegate:)","abstract":"
Creates a PaymentRequest
object and initialises it with a provided delegate.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:FC5Adyen14PaymentRequest5startFT_T_":{"name":"start()","abstract":"
Starts the payment request.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:FC5Adyen14PaymentRequest15deletePreferredFT13paymentMethodCS_13PaymentMethod10completionFTSbGSqOS_5Error__T__T_":{"name":"deletePreferred(paymentMethod:completion:)","abstract":"
Permanently deletes payment method from shopper’s preferred payment options.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html#/s:FC5Adyen14PaymentRequest6cancelFT_T_":{"name":"cancel()","abstract":"
Cancels the payment request.
","parent_name":"PaymentRequest"},"Classes/PaymentRequest.html":{"name":"PaymentRequest","abstract":"
This class is the starting point for Custom Integration .
"},"Protocols/PaymentRequestDelegate.html":{"name":"PaymentRequestDelegate","abstract":"
The payment request delegate. Used for Custom integration comunication. All delegate methods are invoked on the main thread.
"},"Enums/PaymentRequestResult.html":{"name":"PaymentRequestResult","abstract":"
Result of a payment request.
"},"Enums/Error.html":{"name":"Error","abstract":"
Error type.
"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus8receivedFMS0_S0_":{"name":"received","abstract":"
Payment pending.
","parent_name":"PaymentStatus"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus10authorisedFMS0_S0_":{"name":"authorised","abstract":"
Payment authorised.
","parent_name":"PaymentStatus"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus5errorFMS0_S0_":{"name":"error","abstract":"
Payment error.
","parent_name":"PaymentStatus"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus7refusedFMS0_S0_":{"name":"refused","abstract":"
Payment refused.
","parent_name":"PaymentStatus"},"Enums/PaymentStatus.html#/s:FO5Adyen13PaymentStatus9cancelledFMS0_S0_":{"name":"cancelled","abstract":"
Payment cancelled.
","parent_name":"PaymentStatus"},"Classes/Payment.html#/s:vC5Adyen7Payment6statusOS_13PaymentStatus":{"name":"status","abstract":"
The status of the payment.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment6methodCS_13PaymentMethod":{"name":"method","abstract":"
The method that was used to complete the payment.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment7payloadSS":{"name":"payload","abstract":"
The payload as returned from the server.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment6amountSi":{"name":"amount","abstract":"
The amount of the payment, in minor units.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment12currencyCodeSS":{"name":"currencyCode","abstract":"
The code of the currency for the payment amount.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment17merchantReferenceSS":{"name":"merchantReference","abstract":"
The reference of the merchant.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment16shopperReferenceGSqSS_":{"name":"shopperReference","abstract":"
The reference of the shopper.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment18shopperCountryCodeSS":{"name":"shopperCountryCode","abstract":"
The country code of the shopper.
","parent_name":"Payment"},"Classes/Payment.html#/s:vC5Adyen7Payment23shopperLocaleIdentifierGSqSS_":{"name":"shopperLocaleIdentifier","abstract":"
The locale identifier of the shopper.
","parent_name":"Payment"},"Classes/Payment.html":{"name":"Payment","abstract":"
Represents a payment that has been completed by the user. The result of the payment can be retrieved via the status
property.
"},"Enums/PaymentStatus.html":{"name":"PaymentStatus","abstract":"
Payment statuses.
"},"Classes/AppearanceConfiguration.html#/s:FC5Adyen23AppearanceConfigurationcFT_S0_":{"name":"init()","abstract":"
Initializes the appearance configuration.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration23preferredStatusBarStyleOSC16UIStatusBarStyle":{"name":"preferredStatusBarStyle","abstract":"
The preferred status bar style.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration32navigationBarTitleTextAttributesGSqGVs10DictionarySSP___":{"name":"navigationBarTitleTextAttributes","abstract":"
The attributes used for the navigation bar’s title.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration22navigationBarTintColorGSqCSo7UIColor_":{"name":"navigationBarTintColor","abstract":"
The navigation bar’s tint color.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration28navigationBarBackgroundColorGSqCSo7UIColor_":{"name":"navigationBarBackgroundColor","abstract":"
The navigation bar’s background color.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration26isNavigationBarTranslucentSb":{"name":"isNavigationBarTranslucent","abstract":"
A Boolean value indicating whether the navigation bar is translucent.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration30navigationBarCancelButtonImageGSqCSo7UIImage_":{"name":"navigationBarCancelButtonImage","abstract":"
The image of the cancel button in the navigation bar, or nil
if a title should be used instead.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration33checkoutButtonTitleTextAttributesGSqGVs10DictionarySSP___":{"name":"checkoutButtonTitleTextAttributes","abstract":"
The attributes used for the checkout button’s title.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration29checkoutButtonTitleEdgeInsetsGSqVSC12UIEdgeInsets_":{"name":"checkoutButtonTitleEdgeInsets","abstract":"
The insets from the edges of the checkout button to the title.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration26checkoutButtonCornerRadiusV12CoreGraphics7CGFloat":{"name":"checkoutButtonCornerRadius","abstract":"
The corner radius of the checkout button.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:vC5Adyen23AppearanceConfiguration9tintColorGSqCSo7UIColor_":{"name":"tintColor","abstract":"
The tint color of most buttons and actionable elements.
","parent_name":"AppearanceConfiguration"},"Classes/AppearanceConfiguration.html#/s:ZvC5Adyen23AppearanceConfiguration7defaultS0_":{"name":"default","abstract":"
The default appearance configuration.
","parent_name":"AppearanceConfiguration"},"Protocols/CheckoutViewControllerDelegate.html#/s:FP5Adyen30CheckoutViewControllerDelegate22checkoutViewControllerFTCS_22CheckoutViewController27requiresPaymentDataForTokenSS10completionFV10Foundation4DataT__T_":{"name":"checkoutViewController(_:requiresPaymentDataForToken:completion:)","abstract":"
Invoked when the payment flow has started and payment data is requested from the merchant server.
","parent_name":"CheckoutViewControllerDelegate"},"Protocols/CheckoutViewControllerDelegate.html#/s:FP5Adyen30CheckoutViewControllerDelegate22checkoutViewControllerFTCS_22CheckoutViewController17requiresReturnURLFV10Foundation3URLT__T_":{"name":"checkoutViewController(_:requiresReturnURL:)","abstract":"
Invoked when the redirection to a URL has been made. The given completion handler should be invoked when the user returns to the application through a URL.
","parent_name":"CheckoutViewControllerDelegate"},"Protocols/CheckoutViewControllerDelegate.html#/s:FP5Adyen30CheckoutViewControllerDelegate22checkoutViewControllerFTCS_22CheckoutViewController13didFinishWithOS_20PaymentRequestResult_T_":{"name":"checkoutViewController(_:didFinishWith:)","abstract":"
Invoked when the payment flow has finished.
","parent_name":"CheckoutViewControllerDelegate"},"Classes/CheckoutViewController.html#/s:vC5Adyen22CheckoutViewController8delegateXwGSqPS_30CheckoutViewControllerDelegate__":{"name":"delegate","abstract":"
The delegate for Quick integration.
","parent_name":"CheckoutViewController"},"Classes/CheckoutViewController.html#/s:FC5Adyen22CheckoutViewControllercFT8delegatePS_30CheckoutViewControllerDelegate_23appearanceConfigurationCS_23AppearanceConfiguration_S0_":{"name":"init(delegate:appearanceConfiguration:)","abstract":"
Initializes the checkout view controller.
","parent_name":"CheckoutViewController"},"Classes/CheckoutViewController.html":{"name":"CheckoutViewController","abstract":"
The starting point for Quick integration . Initialize with CheckoutViewContollerDelegate
and present this view controller in your app to start the payment flow. If you don’t embed the CheckoutViewController
in an existing UINavigationController
, a new one will be created automatically.
"},"Protocols/CheckoutViewControllerDelegate.html":{"name":"CheckoutViewControllerDelegate","abstract":"
The CheckoutViewControllerDelegate
protocol defines the methods that a delegate of CheckoutViewController
should implement to provide payment data and be informed of the payment flow progress.
"},"Classes/AppearanceConfiguration.html":{"name":"AppearanceConfiguration","abstract":"
Provides properties to customize the appearance of the UI components provided by this library."},"UI.html":{"name":"UI"},"Payment.html":{"name":"Payment"},"Payment Request.html":{"name":"Payment Request"},"Payment Method.html":{"name":"Payment Method"},"Utilities.html":{"name":"Utilities"}}
\ No newline at end of file
diff --git a/Docs/undocumented.json b/Docs/undocumented.json
new file mode 100644
index 0000000000..69b9469e04
--- /dev/null
+++ b/Docs/undocumented.json
@@ -0,0 +1,6 @@
+{
+ "warnings": [
+
+ ],
+ "source_directory": "/Users/joostv/Repositories/adyen-checkout-ios"
+}
\ No newline at end of file
diff --git a/Example/1-quick-integration-example/Podfile b/Example/1-quick-integration-example/Podfile
deleted file mode 100644
index 2474878904..0000000000
--- a/Example/1-quick-integration-example/Podfile
+++ /dev/null
@@ -1,16 +0,0 @@
-platform :ios, '9.0'
-
-target 'ShoppingApp' do
- # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
- use_frameworks!
-
- pod 'Adyen', :path => '../../'
- pod 'Adyen/ApplePay', :path => '../../'
-
- pod 'SwiftFormat/CLI', '~> 0.28.5'
- pod 'SwiftLint', '~> 0.19.0'
-
- target 'UnitTests' do
- inherit! :search_paths
- end
-end
diff --git a/Example/1-quick-integration-example/ShoppingApp.xcodeproj/project.pbxproj b/Example/1-quick-integration-example/ShoppingApp.xcodeproj/project.pbxproj
deleted file mode 100644
index 0e9e8379d9..0000000000
--- a/Example/1-quick-integration-example/ShoppingApp.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,724 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 46;
- objects = {
-
-/* Begin PBXBuildFile section */
- 2E64252AFF0ED07F8F63491D /* Pods_UnitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 19879BFA4E451156342596B3 /* Pods_UnitTests.framework */; };
- 6439ED5AD5980BF05177FB97 /* Pods_ShoppingApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 59976158BAE4A1D93B0471C9 /* Pods_ShoppingApp.framework */; };
- 7CAC59E11E364F6500CAE0C9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CAC59E01E364F6500CAE0C9 /* AppDelegate.swift */; };
- 7CAC59E61E364F6500CAE0C9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7CAC59E41E364F6500CAE0C9 /* Main.storyboard */; };
- 7CAC59E81E364F6500CAE0C9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7CAC59E71E364F6500CAE0C9 /* Assets.xcassets */; };
- 7CAC59EB1E364F6500CAE0C9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7CAC59E91E364F6500CAE0C9 /* LaunchScreen.storyboard */; };
- 7CAC59F41E3659D200CAE0C9 /* ShoppingCartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CAC59F21E3659D200CAE0C9 /* ShoppingCartViewController.swift */; };
- 7CAC59F51E3659D200CAE0C9 /* ConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CAC59F31E3659D200CAE0C9 /* ConfirmationViewController.swift */; };
- E97DE19F1EEEA80600ED3333 /* PaymentMethodPaypalRecurring.json in Resources */ = {isa = PBXBuildFile; fileRef = E97DE19E1EEEA80600ED3333 /* PaymentMethodPaypalRecurring.json */; };
- E9C250721ED85D72002D3B8E /* CardValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C250591ED85D72002D3B8E /* CardValidatorTests.swift */; };
- E9C250731ED85D72002D3B8E /* ArrayExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C2505B1ED85D72002D3B8E /* ArrayExtensionTests.swift */; };
- E9C250741ED85D72002D3B8E /* BoolExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C2505C1ED85D72002D3B8E /* BoolExtensionsTests.swift */; };
- E9C250751ED85D72002D3B8E /* CurrencyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C2505D1ED85D72002D3B8E /* CurrencyTests.swift */; };
- E9C250761ED85D72002D3B8E /* DictionaryExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C2505E1ED85D72002D3B8E /* DictionaryExtensionTests.swift */; };
- E9C250771ED85D72002D3B8E /* InputDetailsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C2505F1ED85D72002D3B8E /* InputDetailsTests.swift */; };
- E9C250781ED85D72002D3B8E /* InputSelectItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C250601ED85D72002D3B8E /* InputSelectItemTests.swift */; };
- E9C250791ED85D72002D3B8E /* PaymentDetailsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C250611ED85D72002D3B8E /* PaymentDetailsTests.swift */; };
- E9C2507A1ED85D72002D3B8E /* PaymentMethodTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C250621ED85D72002D3B8E /* PaymentMethodTests.swift */; };
- E9C2507B1ED85D72002D3B8E /* StringExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C250631ED85D72002D3B8E /* StringExtensionsTests.swift */; };
- E9C2507C1ED85D72002D3B8E /* URLExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C250641ED85D72002D3B8E /* URLExtensionsTests.swift */; };
- E9C2507D1ED85D72002D3B8E /* UIColorExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C250661ED85D72002D3B8E /* UIColorExtensionsTests.swift */; };
- E9C2507F1ED85D72002D3B8E /* JsonReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C250681ED85D72002D3B8E /* JsonReader.swift */; };
- E9C250801ED85D72002D3B8E /* PaymentMethodApplePay.json in Resources */ = {isa = PBXBuildFile; fileRef = E9C2506B1ED85D72002D3B8E /* PaymentMethodApplePay.json */; };
- E9C250811ED85D72002D3B8E /* PaymentMethodCard.json in Resources */ = {isa = PBXBuildFile; fileRef = E9C2506C1ED85D72002D3B8E /* PaymentMethodCard.json */; };
- E9C250821ED85D72002D3B8E /* PaymentMethodCardCvc.json in Resources */ = {isa = PBXBuildFile; fileRef = E9C2506D1ED85D72002D3B8E /* PaymentMethodCardCvc.json */; };
- E9C250831ED85D72002D3B8E /* PaymentMethodIdeal.json in Resources */ = {isa = PBXBuildFile; fileRef = E9C2506E1ED85D72002D3B8E /* PaymentMethodIdeal.json */; };
- E9C250841ED85D72002D3B8E /* PaymentMethodKlarna.json in Resources */ = {isa = PBXBuildFile; fileRef = E9C2506F1ED85D72002D3B8E /* PaymentMethodKlarna.json */; };
- E9C250851ED85D72002D3B8E /* PaymentMethodPaypal.json in Resources */ = {isa = PBXBuildFile; fileRef = E9C250701ED85D72002D3B8E /* PaymentMethodPaypal.json */; };
- E9C250861ED85D72002D3B8E /* PaymentMethodSepa.json in Resources */ = {isa = PBXBuildFile; fileRef = E9C250711ED85D72002D3B8E /* PaymentMethodSepa.json */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXContainerItemProxy section */
- E9C250221ED85BF6002D3B8E /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 7CAC59D51E364F6400CAE0C9 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 7CAC59DC1E364F6500CAE0C9;
- remoteInfo = ShoppingApp;
- };
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- 7CD28FA81E8D62D0009EAA09 /* Embed Frameworks */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- );
- name = "Embed Frameworks";
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
- 19879BFA4E451156342596B3 /* Pods_UnitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UnitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 3B20A497033B79B16FDFA04C /* Pods-UnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.debug.xcconfig"; sourceTree = ""; };
- 59976158BAE4A1D93B0471C9 /* Pods_ShoppingApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShoppingApp.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 5D6D174E4A5200CA9327C23D /* Pods-UnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.release.xcconfig"; sourceTree = ""; };
- 7CAC59DD1E364F6500CAE0C9 /* ShoppingApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ShoppingApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 7CAC59E01E364F6500CAE0C9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
- 7CAC59E51E364F6500CAE0C9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
- 7CAC59E71E364F6500CAE0C9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- 7CAC59EA1E364F6500CAE0C9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
- 7CAC59EC1E364F6500CAE0C9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 7CAC59F21E3659D200CAE0C9 /* ShoppingCartViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShoppingCartViewController.swift; sourceTree = ""; };
- 7CAC59F31E3659D200CAE0C9 /* ConfirmationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfirmationViewController.swift; sourceTree = ""; };
- 81A51A66751D4275B9DAEC27 /* Pods-ShoppingApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShoppingApp.release.xcconfig"; path = "Pods/Target Support Files/Pods-ShoppingApp/Pods-ShoppingApp.release.xcconfig"; sourceTree = ""; };
- 91B6B59168E978035AD7F41C /* Pods-ShoppingApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShoppingApp.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ShoppingApp/Pods-ShoppingApp.debug.xcconfig"; sourceTree = ""; };
- E97DE19E1EEEA80600ED3333 /* PaymentMethodPaypalRecurring.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodPaypalRecurring.json; sourceTree = ""; };
- E9C2501D1ED85BF6002D3B8E /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
- E9C250591ED85D72002D3B8E /* CardValidatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardValidatorTests.swift; sourceTree = ""; };
- E9C2505B1ED85D72002D3B8E /* ArrayExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtensionTests.swift; sourceTree = ""; };
- E9C2505C1ED85D72002D3B8E /* BoolExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolExtensionsTests.swift; sourceTree = ""; };
- E9C2505D1ED85D72002D3B8E /* CurrencyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencyTests.swift; sourceTree = ""; };
- E9C2505E1ED85D72002D3B8E /* DictionaryExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryExtensionTests.swift; sourceTree = ""; };
- E9C2505F1ED85D72002D3B8E /* InputDetailsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputDetailsTests.swift; sourceTree = ""; };
- E9C250601ED85D72002D3B8E /* InputSelectItemTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputSelectItemTests.swift; sourceTree = ""; };
- E9C250611ED85D72002D3B8E /* PaymentDetailsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentDetailsTests.swift; sourceTree = ""; };
- E9C250621ED85D72002D3B8E /* PaymentMethodTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaymentMethodTests.swift; sourceTree = ""; };
- E9C250631ED85D72002D3B8E /* StringExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensionsTests.swift; sourceTree = ""; };
- E9C250641ED85D72002D3B8E /* URLExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLExtensionsTests.swift; sourceTree = ""; };
- E9C250661ED85D72002D3B8E /* UIColorExtensionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColorExtensionsTests.swift; sourceTree = ""; };
- E9C250671ED85D72002D3B8E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- E9C250681ED85D72002D3B8E /* JsonReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JsonReader.swift; sourceTree = ""; };
- E9C2506B1ED85D72002D3B8E /* PaymentMethodApplePay.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodApplePay.json; sourceTree = ""; };
- E9C2506C1ED85D72002D3B8E /* PaymentMethodCard.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodCard.json; sourceTree = ""; };
- E9C2506D1ED85D72002D3B8E /* PaymentMethodCardCvc.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodCardCvc.json; sourceTree = ""; };
- E9C2506E1ED85D72002D3B8E /* PaymentMethodIdeal.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodIdeal.json; sourceTree = ""; };
- E9C2506F1ED85D72002D3B8E /* PaymentMethodKlarna.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodKlarna.json; sourceTree = ""; };
- E9C250701ED85D72002D3B8E /* PaymentMethodPaypal.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodPaypal.json; sourceTree = ""; };
- E9C250711ED85D72002D3B8E /* PaymentMethodSepa.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PaymentMethodSepa.json; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 7CAC59DA1E364F6500CAE0C9 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 6439ED5AD5980BF05177FB97 /* Pods_ShoppingApp.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- E9C2501A1ED85BF6002D3B8E /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 2E64252AFF0ED07F8F63491D /* Pods_UnitTests.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 6190A52F427FF1FE1B1B8DCD /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- 59976158BAE4A1D93B0471C9 /* Pods_ShoppingApp.framework */,
- 19879BFA4E451156342596B3 /* Pods_UnitTests.framework */,
- );
- name = Frameworks;
- sourceTree = "";
- };
- 7CAC59D41E364F6400CAE0C9 = {
- isa = PBXGroup;
- children = (
- 7CAC59DF1E364F6500CAE0C9 /* ShoppingApp */,
- E9C250571ED85D72002D3B8E /* UnitTests */,
- 7CAC59DE1E364F6500CAE0C9 /* Products */,
- 899370914FAF7C11A7EA5D52 /* Pods */,
- 6190A52F427FF1FE1B1B8DCD /* Frameworks */,
- );
- sourceTree = "";
- };
- 7CAC59DE1E364F6500CAE0C9 /* Products */ = {
- isa = PBXGroup;
- children = (
- 7CAC59DD1E364F6500CAE0C9 /* ShoppingApp.app */,
- E9C2501D1ED85BF6002D3B8E /* UnitTests.xctest */,
- );
- name = Products;
- sourceTree = "";
- };
- 7CAC59DF1E364F6500CAE0C9 /* ShoppingApp */ = {
- isa = PBXGroup;
- children = (
- 7CAC59F21E3659D200CAE0C9 /* ShoppingCartViewController.swift */,
- 7CAC59F31E3659D200CAE0C9 /* ConfirmationViewController.swift */,
- 7CAC59E01E364F6500CAE0C9 /* AppDelegate.swift */,
- 7CAC59E41E364F6500CAE0C9 /* Main.storyboard */,
- 7CAC59E71E364F6500CAE0C9 /* Assets.xcassets */,
- 7CAC59E91E364F6500CAE0C9 /* LaunchScreen.storyboard */,
- 7CAC59EC1E364F6500CAE0C9 /* Info.plist */,
- );
- path = ShoppingApp;
- sourceTree = "";
- };
- 899370914FAF7C11A7EA5D52 /* Pods */ = {
- isa = PBXGroup;
- children = (
- 91B6B59168E978035AD7F41C /* Pods-ShoppingApp.debug.xcconfig */,
- 81A51A66751D4275B9DAEC27 /* Pods-ShoppingApp.release.xcconfig */,
- 3B20A497033B79B16FDFA04C /* Pods-UnitTests.debug.xcconfig */,
- 5D6D174E4A5200CA9327C23D /* Pods-UnitTests.release.xcconfig */,
- );
- name = Pods;
- sourceTree = "";
- };
- E9C250571ED85D72002D3B8E /* UnitTests */ = {
- isa = PBXGroup;
- children = (
- E9C250581ED85D72002D3B8E /* Cards */,
- E9C2505A1ED85D72002D3B8E /* Core */,
- E9C250651ED85D72002D3B8E /* CoreUI */,
- E9C250671ED85D72002D3B8E /* Info.plist */,
- E9C250681ED85D72002D3B8E /* JsonReader.swift */,
- E9C250691ED85D72002D3B8E /* Resources */,
- );
- name = UnitTests;
- path = ../../UnitTests;
- sourceTree = "";
- };
- E9C250581ED85D72002D3B8E /* Cards */ = {
- isa = PBXGroup;
- children = (
- E9C250591ED85D72002D3B8E /* CardValidatorTests.swift */,
- );
- path = Cards;
- sourceTree = "";
- };
- E9C2505A1ED85D72002D3B8E /* Core */ = {
- isa = PBXGroup;
- children = (
- E9C2505B1ED85D72002D3B8E /* ArrayExtensionTests.swift */,
- E9C2505C1ED85D72002D3B8E /* BoolExtensionsTests.swift */,
- E9C2505D1ED85D72002D3B8E /* CurrencyTests.swift */,
- E9C2505E1ED85D72002D3B8E /* DictionaryExtensionTests.swift */,
- E9C2505F1ED85D72002D3B8E /* InputDetailsTests.swift */,
- E9C250601ED85D72002D3B8E /* InputSelectItemTests.swift */,
- E9C250611ED85D72002D3B8E /* PaymentDetailsTests.swift */,
- E9C250621ED85D72002D3B8E /* PaymentMethodTests.swift */,
- E9C250631ED85D72002D3B8E /* StringExtensionsTests.swift */,
- E9C250641ED85D72002D3B8E /* URLExtensionsTests.swift */,
- );
- path = Core;
- sourceTree = "";
- };
- E9C250651ED85D72002D3B8E /* CoreUI */ = {
- isa = PBXGroup;
- children = (
- E9C250661ED85D72002D3B8E /* UIColorExtensionsTests.swift */,
- );
- path = CoreUI;
- sourceTree = "";
- };
- E9C250691ED85D72002D3B8E /* Resources */ = {
- isa = PBXGroup;
- children = (
- E9C2506A1ED85D72002D3B8E /* Json */,
- );
- path = Resources;
- sourceTree = "";
- };
- E9C2506A1ED85D72002D3B8E /* Json */ = {
- isa = PBXGroup;
- children = (
- E97DE19E1EEEA80600ED3333 /* PaymentMethodPaypalRecurring.json */,
- E9C2506B1ED85D72002D3B8E /* PaymentMethodApplePay.json */,
- E9C2506C1ED85D72002D3B8E /* PaymentMethodCard.json */,
- E9C2506D1ED85D72002D3B8E /* PaymentMethodCardCvc.json */,
- E9C2506E1ED85D72002D3B8E /* PaymentMethodIdeal.json */,
- E9C2506F1ED85D72002D3B8E /* PaymentMethodKlarna.json */,
- E9C250701ED85D72002D3B8E /* PaymentMethodPaypal.json */,
- E9C250711ED85D72002D3B8E /* PaymentMethodSepa.json */,
- );
- path = Json;
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 7CAC59DC1E364F6500CAE0C9 /* ShoppingApp */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 7CAC59EF1E364F6500CAE0C9 /* Build configuration list for PBXNativeTarget "ShoppingApp" */;
- buildPhases = (
- 941D061A6589DD71F6753188 /* [CP] Check Pods Manifest.lock */,
- 7CAC59D91E364F6500CAE0C9 /* Sources */,
- 7CAC59DA1E364F6500CAE0C9 /* Frameworks */,
- 7CAC59DB1E364F6500CAE0C9 /* Resources */,
- 7CD28FA81E8D62D0009EAA09 /* Embed Frameworks */,
- B0775148E293186281F7BCC4 /* [CP] Embed Pods Frameworks */,
- 02AF6F12DDE34815D1DC6679 /* [CP] Copy Pods Resources */,
- E9C250881ED86145002D3B8E /* Swift Lint */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = ShoppingApp;
- productName = ShoppingApp;
- productReference = 7CAC59DD1E364F6500CAE0C9 /* ShoppingApp.app */;
- productType = "com.apple.product-type.application";
- };
- E9C2501C1ED85BF6002D3B8E /* UnitTests */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = E9C250241ED85BF6002D3B8E /* Build configuration list for PBXNativeTarget "UnitTests" */;
- buildPhases = (
- 46929631E9EA9869C54951D5 /* [CP] Check Pods Manifest.lock */,
- E9C250191ED85BF6002D3B8E /* Sources */,
- E9C2501A1ED85BF6002D3B8E /* Frameworks */,
- E9C2501B1ED85BF6002D3B8E /* Resources */,
- 4F16478B54A55C2CEC583E93 /* [CP] Embed Pods Frameworks */,
- 67F5387A5ED81FE483AAE592 /* [CP] Copy Pods Resources */,
- );
- buildRules = (
- );
- dependencies = (
- E9C250231ED85BF6002D3B8E /* PBXTargetDependency */,
- );
- name = UnitTests;
- productName = UnitTests;
- productReference = E9C2501D1ED85BF6002D3B8E /* UnitTests.xctest */;
- productType = "com.apple.product-type.bundle.unit-test";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 7CAC59D51E364F6400CAE0C9 /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastSwiftUpdateCheck = 0830;
- LastUpgradeCheck = 0830;
- ORGANIZATIONNAME = Adyen;
- TargetAttributes = {
- 7CAC59DC1E364F6500CAE0C9 = {
- CreatedOnToolsVersion = 8.2.1;
- DevelopmentTeam = B2NYSS5932;
- ProvisioningStyle = Automatic;
- };
- E9C2501C1ED85BF6002D3B8E = {
- CreatedOnToolsVersion = 8.3.2;
- DevelopmentTeam = B2NYSS5932;
- ProvisioningStyle = Automatic;
- TestTargetID = 7CAC59DC1E364F6500CAE0C9;
- };
- };
- };
- buildConfigurationList = 7CAC59D81E364F6400CAE0C9 /* Build configuration list for PBXProject "ShoppingApp" */;
- compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- Base,
- );
- mainGroup = 7CAC59D41E364F6400CAE0C9;
- productRefGroup = 7CAC59DE1E364F6500CAE0C9 /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 7CAC59DC1E364F6500CAE0C9 /* ShoppingApp */,
- E9C2501C1ED85BF6002D3B8E /* UnitTests */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 7CAC59DB1E364F6500CAE0C9 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 7CAC59EB1E364F6500CAE0C9 /* LaunchScreen.storyboard in Resources */,
- 7CAC59E81E364F6500CAE0C9 /* Assets.xcassets in Resources */,
- 7CAC59E61E364F6500CAE0C9 /* Main.storyboard in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- E9C2501B1ED85BF6002D3B8E /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- E97DE19F1EEEA80600ED3333 /* PaymentMethodPaypalRecurring.json in Resources */,
- E9C250841ED85D72002D3B8E /* PaymentMethodKlarna.json in Resources */,
- E9C250801ED85D72002D3B8E /* PaymentMethodApplePay.json in Resources */,
- E9C250821ED85D72002D3B8E /* PaymentMethodCardCvc.json in Resources */,
- E9C250831ED85D72002D3B8E /* PaymentMethodIdeal.json in Resources */,
- E9C250851ED85D72002D3B8E /* PaymentMethodPaypal.json in Resources */,
- E9C250861ED85D72002D3B8E /* PaymentMethodSepa.json in Resources */,
- E9C250811ED85D72002D3B8E /* PaymentMethodCard.json in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
- 02AF6F12DDE34815D1DC6679 /* [CP] Copy Pods Resources */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Copy Pods Resources";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ShoppingApp/Pods-ShoppingApp-resources.sh\"\n";
- showEnvVarsInLog = 0;
- };
- 46929631E9EA9869C54951D5 /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Check Pods Manifest.lock";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
- showEnvVarsInLog = 0;
- };
- 4F16478B54A55C2CEC583E93 /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
- 67F5387A5ED81FE483AAE592 /* [CP] Copy Pods Resources */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Copy Pods Resources";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh\"\n";
- showEnvVarsInLog = 0;
- };
- 941D061A6589DD71F6753188 /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Check Pods Manifest.lock";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
- showEnvVarsInLog = 0;
- };
- B0775148E293186281F7BCC4 /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ShoppingApp/Pods-ShoppingApp-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
- E9C250881ED86145002D3B8E /* Swift Lint */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "Swift Lint";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\"";
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 7CAC59D91E364F6500CAE0C9 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 7CAC59F41E3659D200CAE0C9 /* ShoppingCartViewController.swift in Sources */,
- 7CAC59F51E3659D200CAE0C9 /* ConfirmationViewController.swift in Sources */,
- 7CAC59E11E364F6500CAE0C9 /* AppDelegate.swift in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- E9C250191ED85BF6002D3B8E /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- E9C2507F1ED85D72002D3B8E /* JsonReader.swift in Sources */,
- E9C250771ED85D72002D3B8E /* InputDetailsTests.swift in Sources */,
- E9C250721ED85D72002D3B8E /* CardValidatorTests.swift in Sources */,
- E9C2507B1ED85D72002D3B8E /* StringExtensionsTests.swift in Sources */,
- E9C250751ED85D72002D3B8E /* CurrencyTests.swift in Sources */,
- E9C2507D1ED85D72002D3B8E /* UIColorExtensionsTests.swift in Sources */,
- E9C2507C1ED85D72002D3B8E /* URLExtensionsTests.swift in Sources */,
- E9C250791ED85D72002D3B8E /* PaymentDetailsTests.swift in Sources */,
- E9C250761ED85D72002D3B8E /* DictionaryExtensionTests.swift in Sources */,
- E9C250731ED85D72002D3B8E /* ArrayExtensionTests.swift in Sources */,
- E9C2507A1ED85D72002D3B8E /* PaymentMethodTests.swift in Sources */,
- E9C250741ED85D72002D3B8E /* BoolExtensionsTests.swift in Sources */,
- E9C250781ED85D72002D3B8E /* InputSelectItemTests.swift in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
- E9C250231ED85BF6002D3B8E /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 7CAC59DC1E364F6500CAE0C9 /* ShoppingApp */;
- targetProxy = E9C250221ED85BF6002D3B8E /* PBXContainerItemProxy */;
- };
-/* End PBXTargetDependency section */
-
-/* Begin PBXVariantGroup section */
- 7CAC59E41E364F6500CAE0C9 /* Main.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 7CAC59E51E364F6500CAE0C9 /* Base */,
- );
- name = Main.storyboard;
- sourceTree = "";
- };
- 7CAC59E91E364F6500CAE0C9 /* LaunchScreen.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 7CAC59EA1E364F6500CAE0C9 /* Base */,
- );
- name = LaunchScreen.storyboard;
- sourceTree = "";
- };
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
- 7CAC59ED1E364F6500CAE0C9 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_TESTABILITY = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.2;
- MTL_ENABLE_DEBUG_INFO = YES;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = iphoneos;
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Debug;
- };
- 7CAC59EE1E364F6500CAE0C9 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.2;
- MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
- TARGETED_DEVICE_FAMILY = "1,2";
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
- 7CAC59F01E364F6500CAE0C9 /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 91B6B59168E978035AD7F41C /* Pods-ShoppingApp.debug.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- DEVELOPMENT_TEAM = B2NYSS5932;
- FRAMEWORK_SEARCH_PATHS = "$(inherited)";
- INFOPLIST_FILE = ShoppingApp/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- OTHER_LDFLAGS = "$(inherited)";
- PRODUCT_BUNDLE_IDENTIFIER = com.adyen.ShoppingApp;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
- };
- name = Debug;
- };
- 7CAC59F11E364F6500CAE0C9 /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 81A51A66751D4275B9DAEC27 /* Pods-ShoppingApp.release.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- DEVELOPMENT_TEAM = B2NYSS5932;
- FRAMEWORK_SEARCH_PATHS = "$(inherited)";
- INFOPLIST_FILE = ShoppingApp/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- OTHER_LDFLAGS = "$(inherited)";
- PRODUCT_BUNDLE_IDENTIFIER = com.adyen.ShoppingApp;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
- };
- name = Release;
- };
- E9C250251ED85BF6002D3B8E /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 3B20A497033B79B16FDFA04C /* Pods-UnitTests.debug.xcconfig */;
- buildSettings = {
- BUNDLE_LOADER = "$(TEST_HOST)";
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- DEVELOPMENT_TEAM = B2NYSS5932;
- INFOPLIST_FILE = ../../UnitTests/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 10.3;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.adyen.UnitTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShoppingApp.app/ShoppingApp";
- };
- name = Debug;
- };
- E9C250261ED85BF6002D3B8E /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 5D6D174E4A5200CA9327C23D /* Pods-UnitTests.release.xcconfig */;
- buildSettings = {
- BUNDLE_LOADER = "$(TEST_HOST)";
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- DEVELOPMENT_TEAM = B2NYSS5932;
- INFOPLIST_FILE = ../../UnitTests/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 10.3;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.adyen.UnitTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ShoppingApp.app/ShoppingApp";
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 7CAC59D81E364F6400CAE0C9 /* Build configuration list for PBXProject "ShoppingApp" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 7CAC59ED1E364F6500CAE0C9 /* Debug */,
- 7CAC59EE1E364F6500CAE0C9 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 7CAC59EF1E364F6500CAE0C9 /* Build configuration list for PBXNativeTarget "ShoppingApp" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 7CAC59F01E364F6500CAE0C9 /* Debug */,
- 7CAC59F11E364F6500CAE0C9 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- E9C250241ED85BF6002D3B8E /* Build configuration list for PBXNativeTarget "UnitTests" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- E9C250251ED85BF6002D3B8E /* Debug */,
- E9C250261ED85BF6002D3B8E /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 7CAC59D51E364F6400CAE0C9 /* Project object */;
-}
diff --git a/Example/2-custom-integration-example/Advanced.xcodeproj/project.pbxproj b/Example/2-custom-integration-example/Advanced.xcodeproj/project.pbxproj
deleted file mode 100644
index ca29a857c1..0000000000
--- a/Example/2-custom-integration-example/Advanced.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,409 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 46;
- objects = {
-
-/* Begin PBXBuildFile section */
- 55C47CBC28F88ACA60FB3DAB /* Pods_Advanced.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C393FC0180A63751097A92D1 /* Pods_Advanced.framework */; };
- 7C69B7B41E8BED2C003A6CB9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C69B7B31E8BED2C003A6CB9 /* AppDelegate.swift */; };
- 7C69B7B61E8BED2C003A6CB9 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C69B7B51E8BED2C003A6CB9 /* ViewController.swift */; };
- 7C69B7B91E8BED2C003A6CB9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7C69B7B71E8BED2C003A6CB9 /* Main.storyboard */; };
- 7C69B7BB1E8BED2C003A6CB9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7C69B7BA1E8BED2C003A6CB9 /* Assets.xcassets */; };
- 7C69B7BE1E8BED2C003A6CB9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7C69B7BC1E8BED2C003A6CB9 /* LaunchScreen.storyboard */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- 7CD290201E92AAE0009EAA09 /* Embed Frameworks */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- );
- name = "Embed Frameworks";
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
- 7C69B7B01E8BED2C003A6CB9 /* Advanced.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Advanced.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 7C69B7B31E8BED2C003A6CB9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
- 7C69B7B51E8BED2C003A6CB9 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
- 7C69B7B81E8BED2C003A6CB9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
- 7C69B7BA1E8BED2C003A6CB9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- 7C69B7BD1E8BED2C003A6CB9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
- 7C69B7BF1E8BED2C003A6CB9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 97AA4AC453465AE762D28657 /* Pods-Advanced.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Advanced.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Advanced/Pods-Advanced.debug.xcconfig"; sourceTree = ""; };
- C393FC0180A63751097A92D1 /* Pods_Advanced.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Advanced.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- E12E993AE6B1D220613B4E65 /* Pods-Advanced.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Advanced.release.xcconfig"; path = "Pods/Target Support Files/Pods-Advanced/Pods-Advanced.release.xcconfig"; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 7C69B7AD1E8BED2C003A6CB9 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 55C47CBC28F88ACA60FB3DAB /* Pods_Advanced.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 2455BF548E37BAC913FC0F5A /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- C393FC0180A63751097A92D1 /* Pods_Advanced.framework */,
- );
- name = Frameworks;
- sourceTree = "";
- };
- 7C69B7A71E8BED2C003A6CB9 = {
- isa = PBXGroup;
- children = (
- 7C69B7B21E8BED2C003A6CB9 /* Advanced */,
- 7C69B7B11E8BED2C003A6CB9 /* Products */,
- FE6CCF9140E3D3C51AE0126E /* Pods */,
- 2455BF548E37BAC913FC0F5A /* Frameworks */,
- );
- sourceTree = "";
- };
- 7C69B7B11E8BED2C003A6CB9 /* Products */ = {
- isa = PBXGroup;
- children = (
- 7C69B7B01E8BED2C003A6CB9 /* Advanced.app */,
- );
- name = Products;
- sourceTree = "";
- };
- 7C69B7B21E8BED2C003A6CB9 /* Advanced */ = {
- isa = PBXGroup;
- children = (
- 7C69B7B31E8BED2C003A6CB9 /* AppDelegate.swift */,
- 7C69B7B51E8BED2C003A6CB9 /* ViewController.swift */,
- 7C69B7B71E8BED2C003A6CB9 /* Main.storyboard */,
- 7C69B7BA1E8BED2C003A6CB9 /* Assets.xcassets */,
- 7C69B7BC1E8BED2C003A6CB9 /* LaunchScreen.storyboard */,
- 7C69B7BF1E8BED2C003A6CB9 /* Info.plist */,
- );
- path = Advanced;
- sourceTree = "";
- };
- FE6CCF9140E3D3C51AE0126E /* Pods */ = {
- isa = PBXGroup;
- children = (
- 97AA4AC453465AE762D28657 /* Pods-Advanced.debug.xcconfig */,
- E12E993AE6B1D220613B4E65 /* Pods-Advanced.release.xcconfig */,
- );
- name = Pods;
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 7C69B7AF1E8BED2C003A6CB9 /* Advanced */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 7C69B7C21E8BED2C003A6CB9 /* Build configuration list for PBXNativeTarget "Advanced" */;
- buildPhases = (
- 9547CE90CDBF0F3C7A4481FC /* [CP] Check Pods Manifest.lock */,
- 7C69B7AC1E8BED2C003A6CB9 /* Sources */,
- 7C69B7AD1E8BED2C003A6CB9 /* Frameworks */,
- 7C69B7AE1E8BED2C003A6CB9 /* Resources */,
- 7CD290201E92AAE0009EAA09 /* Embed Frameworks */,
- D8457078869B270E4A922061 /* [CP] Embed Pods Frameworks */,
- 5F1B6BBCB5D4C1C7FD7C5031 /* [CP] Copy Pods Resources */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = Advanced;
- productName = Advanced;
- productReference = 7C69B7B01E8BED2C003A6CB9 /* Advanced.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 7C69B7A81E8BED2C003A6CB9 /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastSwiftUpdateCheck = 0820;
- LastUpgradeCheck = 0820;
- ORGANIZATIONNAME = Adyen;
- TargetAttributes = {
- 7C69B7AF1E8BED2C003A6CB9 = {
- CreatedOnToolsVersion = 8.2.1;
- DevelopmentTeam = B2NYSS5932;
- ProvisioningStyle = Automatic;
- };
- };
- };
- buildConfigurationList = 7C69B7AB1E8BED2C003A6CB9 /* Build configuration list for PBXProject "Advanced" */;
- compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- Base,
- );
- mainGroup = 7C69B7A71E8BED2C003A6CB9;
- productRefGroup = 7C69B7B11E8BED2C003A6CB9 /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 7C69B7AF1E8BED2C003A6CB9 /* Advanced */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 7C69B7AE1E8BED2C003A6CB9 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 7C69B7BE1E8BED2C003A6CB9 /* LaunchScreen.storyboard in Resources */,
- 7C69B7BB1E8BED2C003A6CB9 /* Assets.xcassets in Resources */,
- 7C69B7B91E8BED2C003A6CB9 /* Main.storyboard in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
- 5F1B6BBCB5D4C1C7FD7C5031 /* [CP] Copy Pods Resources */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Copy Pods Resources";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Advanced/Pods-Advanced-resources.sh\"\n";
- showEnvVarsInLog = 0;
- };
- 9547CE90CDBF0F3C7A4481FC /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Check Pods Manifest.lock";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
- showEnvVarsInLog = 0;
- };
- D8457078869B270E4A922061 /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Advanced/Pods-Advanced-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 7C69B7AC1E8BED2C003A6CB9 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 7C69B7B61E8BED2C003A6CB9 /* ViewController.swift in Sources */,
- 7C69B7B41E8BED2C003A6CB9 /* AppDelegate.swift in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXVariantGroup section */
- 7C69B7B71E8BED2C003A6CB9 /* Main.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 7C69B7B81E8BED2C003A6CB9 /* Base */,
- );
- name = Main.storyboard;
- sourceTree = "";
- };
- 7C69B7BC1E8BED2C003A6CB9 /* LaunchScreen.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 7C69B7BD1E8BED2C003A6CB9 /* Base */,
- );
- name = LaunchScreen.storyboard;
- sourceTree = "";
- };
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
- 7C69B7C01E8BED2C003A6CB9 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_TESTABILITY = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.2;
- MTL_ENABLE_DEBUG_INFO = YES;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = iphoneos;
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Debug;
- };
- 7C69B7C11E8BED2C003A6CB9 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.2;
- MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
- TARGETED_DEVICE_FAMILY = "1,2";
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
- 7C69B7C31E8BED2C003A6CB9 /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 97AA4AC453465AE762D28657 /* Pods-Advanced.debug.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- DEVELOPMENT_TEAM = B2NYSS5932;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)",
- );
- INFOPLIST_FILE = Advanced/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.adyen.Advanced;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
- };
- name = Debug;
- };
- 7C69B7C41E8BED2C003A6CB9 /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = E12E993AE6B1D220613B4E65 /* Pods-Advanced.release.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- DEVELOPMENT_TEAM = B2NYSS5932;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)",
- );
- INFOPLIST_FILE = Advanced/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.adyen.Advanced;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 7C69B7AB1E8BED2C003A6CB9 /* Build configuration list for PBXProject "Advanced" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 7C69B7C01E8BED2C003A6CB9 /* Debug */,
- 7C69B7C11E8BED2C003A6CB9 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 7C69B7C21E8BED2C003A6CB9 /* Build configuration list for PBXNativeTarget "Advanced" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 7C69B7C31E8BED2C003A6CB9 /* Debug */,
- 7C69B7C41E8BED2C003A6CB9 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 7C69B7A81E8BED2C003A6CB9 /* Project object */;
-}
diff --git a/Example/2-custom-integration-example/Podfile b/Example/2-custom-integration-example/Podfile
deleted file mode 100644
index 550e609d9d..0000000000
--- a/Example/2-custom-integration-example/Podfile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Uncomment the next line to define a global platform for your project
-# platform :ios, '9.0'
-
-target 'Advanced' do
- # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
- use_frameworks!
-
- # Pods for Advanced
- pod 'Adyen/Core', :path => '../../'
- pod 'Adyen/Cards', :path => '../../'
-
-end
diff --git a/Examples/Advanced Integration Example/Advanced Integration Example.xcodeproj/project.pbxproj b/Examples/Advanced Integration Example/Advanced Integration Example.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..5f33ecaff6
--- /dev/null
+++ b/Examples/Advanced Integration Example/Advanced Integration Example.xcodeproj/project.pbxproj
@@ -0,0 +1,379 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ C0030EE11DA70722FF7B02B9 /* Pods_Advanced_Integration_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22671A00CE691613636A2017 /* Pods_Advanced_Integration_Example.framework */; };
+ E226F1301EFC0E73009E04C9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E226F12C1EFC0E73009E04C9 /* AppDelegate.swift */; };
+ E226F1311EFC0E73009E04C9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E226F12D1EFC0E73009E04C9 /* Assets.xcassets */; };
+ E226F1331EFC0E73009E04C9 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E226F12F1EFC0E73009E04C9 /* ViewController.swift */; };
+ E226F1361EFC0E7E009E04C9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E226F1341EFC0E7E009E04C9 /* LaunchScreen.storyboard */; };
+ E226F1371EFC0E7E009E04C9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E226F1351EFC0E7E009E04C9 /* Main.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 22671A00CE691613636A2017 /* Pods_Advanced_Integration_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Advanced_Integration_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5334F3A5F7A978D5EF6EDE7A /* Pods-Advanced Integration Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Advanced Integration Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Advanced Integration Example/Pods-Advanced Integration Example.debug.xcconfig"; sourceTree = ""; };
+ C1ACB96BD25D5E457D0C4269 /* Pods-Advanced Integration Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Advanced Integration Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Advanced Integration Example/Pods-Advanced Integration Example.release.xcconfig"; sourceTree = ""; };
+ E226F1171EFC0E4C009E04C9 /* Advanced Integration Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Advanced Integration Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ E226F12C1EFC0E73009E04C9 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ E226F12D1EFC0E73009E04C9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ E226F12E1EFC0E73009E04C9 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ E226F12F1EFC0E73009E04C9 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ E226F1341EFC0E7E009E04C9 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
+ E226F1351EFC0E7E009E04C9 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
+ E226F1381EFCEFB7009E04C9 /* Adyen.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Adyen.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ E226F13F1EFCEFE7009E04C9 /* AdyenCSE.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdyenCSE.framework; path = ../../Carthage/Build/iOS/AdyenCSE.framework; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ E226F1141EFC0E4C009E04C9 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C0030EE11DA70722FF7B02B9 /* Pods_Advanced_Integration_Example.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 3623DE877C30CE00C3762C46 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 5334F3A5F7A978D5EF6EDE7A /* Pods-Advanced Integration Example.debug.xcconfig */,
+ C1ACB96BD25D5E457D0C4269 /* Pods-Advanced Integration Example.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "";
+ };
+ E226F10E1EFC0E4C009E04C9 = {
+ isa = PBXGroup;
+ children = (
+ E226F1191EFC0E4C009E04C9 /* Advanced Integration Example */,
+ E226F1181EFC0E4C009E04C9 /* Products */,
+ E226F1421EFCEFEE009E04C9 /* Frameworks */,
+ 3623DE877C30CE00C3762C46 /* Pods */,
+ );
+ sourceTree = "";
+ };
+ E226F1181EFC0E4C009E04C9 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ E226F1171EFC0E4C009E04C9 /* Advanced Integration Example.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ E226F1191EFC0E4C009E04C9 /* Advanced Integration Example */ = {
+ isa = PBXGroup;
+ children = (
+ E226F12C1EFC0E73009E04C9 /* AppDelegate.swift */,
+ E226F12F1EFC0E73009E04C9 /* ViewController.swift */,
+ E226F1341EFC0E7E009E04C9 /* LaunchScreen.storyboard */,
+ E226F1351EFC0E7E009E04C9 /* Main.storyboard */,
+ E226F12D1EFC0E73009E04C9 /* Assets.xcassets */,
+ E226F12E1EFC0E73009E04C9 /* Info.plist */,
+ );
+ path = "Advanced Integration Example";
+ sourceTree = "";
+ };
+ E226F1421EFCEFEE009E04C9 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ E226F1381EFCEFB7009E04C9 /* Adyen.framework */,
+ E226F13F1EFCEFE7009E04C9 /* AdyenCSE.framework */,
+ 22671A00CE691613636A2017 /* Pods_Advanced_Integration_Example.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ E226F1161EFC0E4C009E04C9 /* Advanced Integration Example */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = E226F1291EFC0E4C009E04C9 /* Build configuration list for PBXNativeTarget "Advanced Integration Example" */;
+ buildPhases = (
+ 7742E875E2C4FA2D6F976FFE /* [CP] Check Pods Manifest.lock */,
+ E226F1131EFC0E4C009E04C9 /* Sources */,
+ E226F1141EFC0E4C009E04C9 /* Frameworks */,
+ E226F1151EFC0E4C009E04C9 /* Resources */,
+ F0F2B34CC0963E0ABE3557F1 /* [CP] Embed Pods Frameworks */,
+ DB88A7FA3D399B921DA0E2D3 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Advanced Integration Example";
+ productName = "Advanced Integration Example";
+ productReference = E226F1171EFC0E4C009E04C9 /* Advanced Integration Example.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ E226F10F1EFC0E4C009E04C9 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0830;
+ LastUpgradeCheck = 0830;
+ ORGANIZATIONNAME = Adyen;
+ TargetAttributes = {
+ E226F1161EFC0E4C009E04C9 = {
+ CreatedOnToolsVersion = 8.3.3;
+ LastSwiftMigration = 0830;
+ ProvisioningStyle = Manual;
+ };
+ };
+ };
+ buildConfigurationList = E226F1121EFC0E4C009E04C9 /* Build configuration list for PBXProject "Advanced Integration Example" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = E226F10E1EFC0E4C009E04C9;
+ productRefGroup = E226F1181EFC0E4C009E04C9 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ E226F1161EFC0E4C009E04C9 /* Advanced Integration Example */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ E226F1151EFC0E4C009E04C9 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E226F1371EFC0E7E009E04C9 /* Main.storyboard in Resources */,
+ E226F1311EFC0E73009E04C9 /* Assets.xcassets in Resources */,
+ E226F1361EFC0E7E009E04C9 /* LaunchScreen.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 7742E875E2C4FA2D6F976FFE /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ DB88A7FA3D399B921DA0E2D3 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Advanced Integration Example/Pods-Advanced Integration Example-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ F0F2B34CC0963E0ABE3557F1 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Advanced Integration Example/Pods-Advanced Integration Example-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ E226F1131EFC0E4C009E04C9 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E226F1331EFC0E73009E04C9 /* ViewController.swift in Sources */,
+ E226F1301EFC0E73009E04C9 /* AppDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ E226F1271EFC0E4C009E04C9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ E226F1281EFC0E4C009E04C9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ E226F12A1EFC0E4C009E04C9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 5334F3A5F7A978D5EF6EDE7A /* Pods-Advanced Integration Example.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = "Advanced Integration Example/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.Advanced;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ E226F12B1EFC0E4C009E04C9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = C1ACB96BD25D5E457D0C4269 /* Pods-Advanced Integration Example.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = "Advanced Integration Example/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.Advanced;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ E226F1121EFC0E4C009E04C9 /* Build configuration list for PBXProject "Advanced Integration Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E226F1271EFC0E4C009E04C9 /* Debug */,
+ E226F1281EFC0E4C009E04C9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ E226F1291EFC0E4C009E04C9 /* Build configuration list for PBXNativeTarget "Advanced Integration Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E226F12A1EFC0E4C009E04C9 /* Debug */,
+ E226F12B1EFC0E4C009E04C9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = E226F10F1EFC0E4C009E04C9 /* Project object */;
+}
diff --git a/Example/1-quick-integration-example/ShoppingApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Examples/Advanced Integration Example/Advanced Integration Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to Examples/Advanced Integration Example/Advanced Integration Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
diff --git a/Examples/Advanced Integration Example/Advanced Integration Example.xcworkspace/contents.xcworkspacedata b/Examples/Advanced Integration Example/Advanced Integration Example.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..03c725667a
--- /dev/null
+++ b/Examples/Advanced Integration Example/Advanced Integration Example.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/Example/2-custom-integration-example/Advanced/AppDelegate.swift b/Examples/Advanced Integration Example/Advanced Integration Example/AppDelegate.swift
similarity index 100%
rename from Example/2-custom-integration-example/Advanced/AppDelegate.swift
rename to Examples/Advanced Integration Example/Advanced Integration Example/AppDelegate.swift
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/Advanced Integration Example/Advanced Integration Example/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/AppIcon.appiconset/Contents.json
rename to Examples/Advanced Integration Example/Advanced Integration Example/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/Example/2-custom-integration-example/Advanced/Info.plist b/Examples/Advanced Integration Example/Advanced Integration Example/Info.plist
similarity index 100%
rename from Example/2-custom-integration-example/Advanced/Info.plist
rename to Examples/Advanced Integration Example/Advanced Integration Example/Info.plist
diff --git a/Example/2-custom-integration-example/Advanced/Base.lproj/LaunchScreen.storyboard b/Examples/Advanced Integration Example/Advanced Integration Example/LaunchScreen.storyboard
similarity index 100%
rename from Example/2-custom-integration-example/Advanced/Base.lproj/LaunchScreen.storyboard
rename to Examples/Advanced Integration Example/Advanced Integration Example/LaunchScreen.storyboard
diff --git a/Example/2-custom-integration-example/Advanced/Base.lproj/Main.storyboard b/Examples/Advanced Integration Example/Advanced Integration Example/Main.storyboard
similarity index 100%
rename from Example/2-custom-integration-example/Advanced/Base.lproj/Main.storyboard
rename to Examples/Advanced Integration Example/Advanced Integration Example/Main.storyboard
diff --git a/Example/2-custom-integration-example/Advanced/ViewController.swift b/Examples/Advanced Integration Example/Advanced Integration Example/ViewController.swift
similarity index 96%
rename from Example/2-custom-integration-example/Advanced/ViewController.swift
rename to Examples/Advanced Integration Example/Advanced Integration Example/ViewController.swift
index 2b51d1d761..352400ffd3 100644
--- a/Example/2-custom-integration-example/Advanced/ViewController.swift
+++ b/Examples/Advanced Integration Example/Advanced Integration Example/ViewController.swift
@@ -10,8 +10,8 @@ import AdyenCSE
class ViewController: UIViewController {
let url = URL(string: "https://checkoutshopper-test.adyen.com/checkoutshopper/demo/easy-integration/merchantserver/setup")!
- let appId = YOU_APP_ID // provide your app id
- let appSecretKey = YOUR_APP_SECRET_KEY // provide your app secret key (to use with Adyen Test Merchant Server)
+ let appId = "YOU_APP_ID" // provide your app id
+ let appSecretKey = "YOUR_APP_SECRET_KEY" // provide your app secret key (to use with Adyen Test Merchant Server)
@IBOutlet weak var statusLabel: UILabel!
diff --git a/Examples/Advanced Integration Example/Podfile b/Examples/Advanced Integration Example/Podfile
new file mode 100644
index 0000000000..417a2b165c
--- /dev/null
+++ b/Examples/Advanced Integration Example/Podfile
@@ -0,0 +1,10 @@
+platform :ios, '9.0'
+
+use_frameworks!
+
+target 'Advanced Integration Example' do
+
+ pod 'Adyen', :path => '../../'
+ pod 'Adyen/ApplePay', :path => '../../'
+
+end
diff --git a/Examples/Quick Integration Example/Podfile b/Examples/Quick Integration Example/Podfile
new file mode 100644
index 0000000000..c74e9f0bd9
--- /dev/null
+++ b/Examples/Quick Integration Example/Podfile
@@ -0,0 +1,10 @@
+platform :ios, '9.0'
+
+use_frameworks!
+
+target 'Quick Integration Example' do
+
+ pod 'Adyen', :path => '../../'
+ pod 'Adyen/ApplePay', :path => '../../'
+
+end
diff --git a/Examples/Quick Integration Example/Quick Integration Example.xcodeproj/project.pbxproj b/Examples/Quick Integration Example/Quick Integration Example.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..45dcd5077a
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example.xcodeproj/project.pbxproj
@@ -0,0 +1,419 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ C27E7952356F601029D68D5F /* Pods_Quick_Integration_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 891136C5E42625688BDF48CE /* Pods_Quick_Integration_Example.framework */; };
+ E20AD22C1EFBEE7D0065B70E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD2271EFBEE7D0065B70E /* AppDelegate.swift */; };
+ E20AD22D1EFBEE7D0065B70E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E20AD2281EFBEE7D0065B70E /* Assets.xcassets */; };
+ E20AD22E1EFBEE7D0065B70E /* ConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD2291EFBEE7D0065B70E /* ConfirmationViewController.swift */; };
+ E20AD2301EFBEE7D0065B70E /* ShoppingCartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20AD22B1EFBEE7D0065B70E /* ShoppingCartViewController.swift */; };
+ E20AD2331EFBEE8E0065B70E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E20AD2311EFBEE8E0065B70E /* LaunchScreen.storyboard */; };
+ E22312011F0D255E00FD0677 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E22312001F0D255E00FD0677 /* Configuration.swift */; };
+ E28ECE021F066AA4004FCEA6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E28ECE041F066AA4004FCEA6 /* Main.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 2A6421BAC3A94A53A8AC8C15 /* Pods-Quick Integration Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Quick Integration Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Quick Integration Example/Pods-Quick Integration Example.debug.xcconfig"; sourceTree = ""; };
+ 891136C5E42625688BDF48CE /* Pods_Quick_Integration_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Quick_Integration_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9A917D5EBCCD77052E5B7E65 /* Pods-Quick Integration Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Quick Integration Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Quick Integration Example/Pods-Quick Integration Example.release.xcconfig"; sourceTree = ""; };
+ E20AD2121EFBEE4A0065B70E /* Quick Integration Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Quick Integration Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ E20AD2271EFBEE7D0065B70E /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ E20AD2281EFBEE7D0065B70E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ E20AD2291EFBEE7D0065B70E /* ConfirmationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfirmationViewController.swift; sourceTree = ""; };
+ E20AD22A1EFBEE7D0065B70E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ E20AD22B1EFBEE7D0065B70E /* ShoppingCartViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShoppingCartViewController.swift; sourceTree = ""; };
+ E20AD2311EFBEE8E0065B70E /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
+ E20AD2381EFBEFBC0065B70E /* Adyen.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Adyen.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ E22312001F0D255E00FD0677 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; };
+ E226F0E11EFC08E6009E04C9 /* AdyenCSE.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdyenCSE.framework; path = ../../Carthage/Build/iOS/AdyenCSE.framework; sourceTree = ""; };
+ E28ECE061F066B75004FCEA6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ E2B620741F0E251D001D4C27 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = ""; };
+ E2B620751F0E2526001D4C27 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Main.strings; sourceTree = ""; };
+ E2B620761F0E2529001D4C27 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Main.strings; sourceTree = ""; };
+ E2B620771F0E252B001D4C27 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = ""; };
+ E2B620781F0E252E001D4C27 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Main.strings; sourceTree = ""; };
+ E2B620791F0E2532001D4C27 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Main.strings; sourceTree = ""; };
+ E2B6207A1F0E2534001D4C27 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Main.strings; sourceTree = ""; };
+ E2B6207B1F0E2539001D4C27 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Main.strings; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ E20AD20F1EFBEE4A0065B70E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C27E7952356F601029D68D5F /* Pods_Quick_Integration_Example.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 617BAB106F25E1942755DA35 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 2A6421BAC3A94A53A8AC8C15 /* Pods-Quick Integration Example.debug.xcconfig */,
+ 9A917D5EBCCD77052E5B7E65 /* Pods-Quick Integration Example.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "";
+ };
+ E20AD2091EFBEE4A0065B70E = {
+ isa = PBXGroup;
+ children = (
+ E20AD2141EFBEE4A0065B70E /* Quick Integration Example */,
+ E20AD2131EFBEE4A0065B70E /* Products */,
+ E20AD2351EFBEF810065B70E /* Frameworks */,
+ 617BAB106F25E1942755DA35 /* Pods */,
+ );
+ sourceTree = "";
+ };
+ E20AD2131EFBEE4A0065B70E /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD2121EFBEE4A0065B70E /* Quick Integration Example.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ E20AD2141EFBEE4A0065B70E /* Quick Integration Example */ = {
+ isa = PBXGroup;
+ children = (
+ E22312001F0D255E00FD0677 /* Configuration.swift */,
+ E20AD2271EFBEE7D0065B70E /* AppDelegate.swift */,
+ E20AD22B1EFBEE7D0065B70E /* ShoppingCartViewController.swift */,
+ E20AD2291EFBEE7D0065B70E /* ConfirmationViewController.swift */,
+ E20AD2311EFBEE8E0065B70E /* LaunchScreen.storyboard */,
+ E28ECE041F066AA4004FCEA6 /* Main.storyboard */,
+ E20AD2281EFBEE7D0065B70E /* Assets.xcassets */,
+ E20AD22A1EFBEE7D0065B70E /* Info.plist */,
+ );
+ path = "Quick Integration Example";
+ sourceTree = "";
+ };
+ E20AD2351EFBEF810065B70E /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ E20AD2381EFBEFBC0065B70E /* Adyen.framework */,
+ E226F0E11EFC08E6009E04C9 /* AdyenCSE.framework */,
+ 891136C5E42625688BDF48CE /* Pods_Quick_Integration_Example.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ E20AD2111EFBEE4A0065B70E /* Quick Integration Example */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = E20AD2241EFBEE4A0065B70E /* Build configuration list for PBXNativeTarget "Quick Integration Example" */;
+ buildPhases = (
+ B85BF2E55433107E1AED5D19 /* [CP] Check Pods Manifest.lock */,
+ E20AD20E1EFBEE4A0065B70E /* Sources */,
+ E20AD20F1EFBEE4A0065B70E /* Frameworks */,
+ E20AD2101EFBEE4A0065B70E /* Resources */,
+ F59DBB7FA9517381E270A9A3 /* [CP] Embed Pods Frameworks */,
+ 80A58B9E4649DC1C42CC8189 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Quick Integration Example";
+ productName = QuickIntegrationExample;
+ productReference = E20AD2121EFBEE4A0065B70E /* Quick Integration Example.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ E20AD20A1EFBEE4A0065B70E /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0830;
+ LastUpgradeCheck = 0830;
+ ORGANIZATIONNAME = Adyen;
+ TargetAttributes = {
+ E20AD2111EFBEE4A0065B70E = {
+ CreatedOnToolsVersion = 8.3.3;
+ LastSwiftMigration = 0830;
+ ProvisioningStyle = Manual;
+ };
+ };
+ };
+ buildConfigurationList = E20AD20D1EFBEE4A0065B70E /* Build configuration list for PBXProject "Quick Integration Example" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ nl,
+ Base,
+ );
+ mainGroup = E20AD2091EFBEE4A0065B70E;
+ productRefGroup = E20AD2131EFBEE4A0065B70E /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ E20AD2111EFBEE4A0065B70E /* Quick Integration Example */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ E20AD2101EFBEE4A0065B70E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E28ECE021F066AA4004FCEA6 /* Main.storyboard in Resources */,
+ E20AD22D1EFBEE7D0065B70E /* Assets.xcassets in Resources */,
+ E20AD2331EFBEE8E0065B70E /* LaunchScreen.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 80A58B9E4649DC1C42CC8189 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Quick Integration Example/Pods-Quick Integration Example-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ B85BF2E55433107E1AED5D19 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ F59DBB7FA9517381E270A9A3 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Quick Integration Example/Pods-Quick Integration Example-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ E20AD20E1EFBEE4A0065B70E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E20AD22E1EFBEE7D0065B70E /* ConfirmationViewController.swift in Sources */,
+ E20AD22C1EFBEE7D0065B70E /* AppDelegate.swift in Sources */,
+ E22312011F0D255E00FD0677 /* Configuration.swift in Sources */,
+ E20AD2301EFBEE7D0065B70E /* ShoppingCartViewController.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ E28ECE041F066AA4004FCEA6 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ E28ECE061F066B75004FCEA6 /* Base */,
+ E2B620741F0E251D001D4C27 /* en */,
+ E2B620751F0E2526001D4C27 /* nl */,
+ E2B620761F0E2529001D4C27 /* fr */,
+ E2B620771F0E252B001D4C27 /* de */,
+ E2B620781F0E252E001D4C27 /* es */,
+ E2B620791F0E2532001D4C27 /* pt */,
+ E2B6207A1F0E2534001D4C27 /* it */,
+ E2B6207B1F0E2539001D4C27 /* sv */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ E20AD2221EFBEE4A0065B70E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ E20AD2231EFBEE4A0065B70E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ E20AD2251EFBEE4A0065B70E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 2A6421BAC3A94A53A8AC8C15 /* Pods-Quick Integration Example.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = "$(SRCROOT)/Quick Integration Example/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.ShoppingApp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Debug;
+ };
+ E20AD2261EFBEE4A0065B70E /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9A917D5EBCCD77052E5B7E65 /* Pods-Quick Integration Example.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = "$(SRCROOT)/Quick Integration Example/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.adyen.ShoppingApp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 3.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ E20AD20D1EFBEE4A0065B70E /* Build configuration list for PBXProject "Quick Integration Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E20AD2221EFBEE4A0065B70E /* Debug */,
+ E20AD2231EFBEE4A0065B70E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ E20AD2241EFBEE4A0065B70E /* Build configuration list for PBXNativeTarget "Quick Integration Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E20AD2251EFBEE4A0065B70E /* Debug */,
+ E20AD2261EFBEE4A0065B70E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = E20AD20A1EFBEE4A0065B70E /* Project object */;
+}
diff --git a/Examples/Quick Integration Example/Quick Integration Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Examples/Quick Integration Example/Quick Integration Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..919434a625
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/Example/1-quick-integration-example/ShoppingApp.xcworkspace/contents.xcworkspacedata b/Examples/Quick Integration Example/Quick Integration Example.xcworkspace/contents.xcworkspacedata
similarity index 74%
rename from Example/1-quick-integration-example/ShoppingApp.xcworkspace/contents.xcworkspacedata
rename to Examples/Quick Integration Example/Quick Integration Example.xcworkspace/contents.xcworkspacedata
index d061a31cc5..20dd8b43b9 100644
--- a/Example/1-quick-integration-example/ShoppingApp.xcworkspace/contents.xcworkspacedata
+++ b/Examples/Quick Integration Example/Quick Integration Example.xcworkspace/contents.xcworkspacedata
@@ -2,7 +2,7 @@
+ location = "group:Quick Integration Example.xcodeproj">
diff --git a/Example/1-quick-integration-example/ShoppingApp/AppDelegate.swift b/Examples/Quick Integration Example/Quick Integration Example/AppDelegate.swift
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/AppDelegate.swift
rename to Examples/Quick Integration Example/Quick Integration Example/AppDelegate.swift
diff --git a/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..1d060ed288
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,93 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Background.imageset/Background.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Background.imageset/Background.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Background.imageset/Background.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Background.imageset/Background.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Background.imageset/Background@2x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Background.imageset/Background@2x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Background.imageset/Background@2x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Background.imageset/Background@2x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Background.imageset/Background@3x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Background.imageset/Background@3x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Background.imageset/Background@3x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Background.imageset/Background@3x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Background.imageset/Contents.json b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Background.imageset/Contents.json
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Background.imageset/Contents.json
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Background.imageset/Contents.json
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Btn_cta.imageset/Btn_cta.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Btn_cta.imageset/Btn_cta.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Btn_cta.imageset/Btn_cta.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Btn_cta.imageset/Btn_cta.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Btn_cta.imageset/Btn_cta@2x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Btn_cta.imageset/Btn_cta@2x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Btn_cta.imageset/Btn_cta@2x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Btn_cta.imageset/Btn_cta@2x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Btn_cta.imageset/Btn_cta@3x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Btn_cta.imageset/Btn_cta@3x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Btn_cta.imageset/Btn_cta@3x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Btn_cta.imageset/Btn_cta@3x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Btn_cta.imageset/Contents.json b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Btn_cta.imageset/Contents.json
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Btn_cta.imageset/Contents.json
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Btn_cta.imageset/Contents.json
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Checkout window.imageset/Checkout window.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Checkout window.imageset/Checkout window.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Checkout window.imageset/Checkout window.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Checkout window.imageset/Checkout window.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Checkout window.imageset/Checkout window@2x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Checkout window.imageset/Checkout window@2x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Checkout window.imageset/Checkout window@2x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Checkout window.imageset/Checkout window@2x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Checkout window.imageset/Checkout window@3x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Checkout window.imageset/Checkout window@3x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Checkout window.imageset/Checkout window@3x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Checkout window.imageset/Checkout window@3x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Checkout window.imageset/Contents.json b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Checkout window.imageset/Contents.json
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Checkout window.imageset/Contents.json
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Checkout window.imageset/Contents.json
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Contents.json b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Contents.json
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Contents.json
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Contents.json
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Failure.imageset/Contents.json b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Failure.imageset/Contents.json
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Failure.imageset/Contents.json
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Failure.imageset/Contents.json
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Failure.imageset/Failure.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Failure.imageset/Failure.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Failure.imageset/Failure.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Failure.imageset/Failure.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Failure.imageset/Failure@2x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Failure.imageset/Failure@2x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Failure.imageset/Failure@2x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Failure.imageset/Failure@2x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Failure.imageset/Failure@3x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Failure.imageset/Failure@3x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Failure.imageset/Failure@3x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Failure.imageset/Failure@3x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Success.imageset/Contents.json b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Success.imageset/Contents.json
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Success.imageset/Contents.json
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Success.imageset/Contents.json
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Success.imageset/Success.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Success.imageset/Success.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Success.imageset/Success.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Success.imageset/Success.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Success.imageset/Success@2x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Success.imageset/Success@2x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Success.imageset/Success@2x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Success.imageset/Success@2x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Success.imageset/Success@3x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Success.imageset/Success@3x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/Success.imageset/Success@3x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/Success.imageset/Success@3x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/back-to-shop.imageset/Contents.json b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/back-to-shop.imageset/Contents.json
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/back-to-shop.imageset/Contents.json
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/back-to-shop.imageset/Contents.json
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/back-to-shop.imageset/back-to-shop.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/back-to-shop.imageset/back-to-shop.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/back-to-shop.imageset/back-to-shop.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/back-to-shop.imageset/back-to-shop.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/back-to-shop.imageset/back-to-shop@2x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/back-to-shop.imageset/back-to-shop@2x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/back-to-shop.imageset/back-to-shop@2x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/back-to-shop.imageset/back-to-shop@2x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/back-to-shop.imageset/back-to-shop@3x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/back-to-shop.imageset/back-to-shop@3x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/back-to-shop.imageset/back-to-shop@3x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/back-to-shop.imageset/back-to-shop@3x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/try-again.imageset/Contents.json b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/try-again.imageset/Contents.json
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/try-again.imageset/Contents.json
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/try-again.imageset/Contents.json
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/try-again.imageset/try-again.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/try-again.imageset/try-again.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/try-again.imageset/try-again.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/try-again.imageset/try-again.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/try-again.imageset/try-again@2x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/try-again.imageset/try-again@2x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/try-again.imageset/try-again@2x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/try-again.imageset/try-again@2x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/try-again.imageset/try-again@3x.png b/Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/try-again.imageset/try-again@3x.png
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Assets.xcassets/try-again.imageset/try-again@3x.png
rename to Examples/Quick Integration Example/Quick Integration Example/Assets.xcassets/try-again.imageset/try-again@3x.png
diff --git a/Example/1-quick-integration-example/ShoppingApp/Base.lproj/Main.storyboard b/Examples/Quick Integration Example/Quick Integration Example/Base.lproj/Main.storyboard
similarity index 96%
rename from Example/1-quick-integration-example/ShoppingApp/Base.lproj/Main.storyboard
rename to Examples/Quick Integration Example/Quick Integration Example/Base.lproj/Main.storyboard
index d9a5d02c1c..0866171eab 100644
--- a/Example/1-quick-integration-example/ShoppingApp/Base.lproj/Main.storyboard
+++ b/Examples/Quick Integration Example/Quick Integration Example/Base.lproj/Main.storyboard
@@ -1,11 +1,11 @@
-
+
-
+
@@ -13,7 +13,7 @@
-
+
@@ -56,7 +56,7 @@
-
+
@@ -99,7 +99,7 @@
-
+
diff --git a/Examples/Quick Integration Example/Quick Integration Example/Configuration.swift b/Examples/Quick Integration Example/Quick Integration Example/Configuration.swift
new file mode 100644
index 0000000000..1f1752b89c
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/Configuration.swift
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 2017 Adyen B.V.
+//
+// This file is open source and available under the MIT license. See the LICENSE file for more info.
+//
+
+import Foundation
+
+// Fill in your app identifier and secret key here.
+struct Configuration {
+ static let appIdentifier = ""
+ static let appSecretKey = ""
+
+ static var isFilledIn: Bool {
+ guard
+ appIdentifier.characters.isEmpty == false,
+ appSecretKey.characters.isEmpty == false
+ else {
+ return false
+ }
+
+ return true
+ }
+}
diff --git a/Example/1-quick-integration-example/ShoppingApp/ConfirmationViewController.swift b/Examples/Quick Integration Example/Quick Integration Example/ConfirmationViewController.swift
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/ConfirmationViewController.swift
rename to Examples/Quick Integration Example/Quick Integration Example/ConfirmationViewController.swift
diff --git a/Example/1-quick-integration-example/ShoppingApp/Info.plist b/Examples/Quick Integration Example/Quick Integration Example/Info.plist
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Info.plist
rename to Examples/Quick Integration Example/Quick Integration Example/Info.plist
diff --git a/Example/1-quick-integration-example/ShoppingApp/Base.lproj/LaunchScreen.storyboard b/Examples/Quick Integration Example/Quick Integration Example/LaunchScreen.storyboard
similarity index 100%
rename from Example/1-quick-integration-example/ShoppingApp/Base.lproj/LaunchScreen.storyboard
rename to Examples/Quick Integration Example/Quick Integration Example/LaunchScreen.storyboard
diff --git a/Example/1-quick-integration-example/ShoppingApp/ShoppingCartViewController.swift b/Examples/Quick Integration Example/Quick Integration Example/ShoppingCartViewController.swift
similarity index 81%
rename from Example/1-quick-integration-example/ShoppingApp/ShoppingCartViewController.swift
rename to Examples/Quick Integration Example/Quick Integration Example/ShoppingCartViewController.swift
index b0818384e7..f16bdb8628 100644
--- a/Example/1-quick-integration-example/ShoppingApp/ShoppingCartViewController.swift
+++ b/Examples/Quick Integration Example/Quick Integration Example/ShoppingCartViewController.swift
@@ -9,20 +9,25 @@ import Adyen
class ShoppingCartViewController: UIViewController {
let url = URL(string: "https://checkoutshopper-test.adyen.com/checkoutshopper/demo/easy-integration/merchantserver/setup")!
- let appId = YOU_APP_ID // provide your app id
- let appSecretKey = YOUR_APP_SECRET_KEY // provide your app secret key (to use with Adyen Test Merchant Server)
var appUrlCompletion: URLCompletion?
- var checkoutViewController: CheckoutViewController?
- @IBAction func checkout(_ sender: Any) {
- checkoutViewController = CheckoutViewController(delegate: self)
+ override func viewDidLoad() {
+ super.viewDidLoad()
- if let vc = checkoutViewController {
- present(vc, animated: true, completion: nil)
+ guard
+ Configuration.appIdentifier.characters.isEmpty == false,
+ Configuration.appSecretKey.characters.isEmpty == false
+ else {
+ fatalError("Please fill in your app ID and secret key in the Configuration.swift file.")
}
}
+ @IBAction func checkout(_ sender: Any) {
+ let checkoutViewController = CheckoutViewController(delegate: self)
+ present(checkoutViewController, animated: true)
+ }
+
func presentSuccessScreen() {
presentScreen(withIdentifier: "SuccessScreen")
}
@@ -53,8 +58,8 @@ extension ShoppingCartViewController: CheckoutViewControllerDelegate {
request.httpBody = try? JSONSerialization.data(withJSONObject: paymentDetails, options: [])
request.allHTTPHeaderFields = [
"Content-Type": "application/json",
- "X-MerchantServer-App-Id": appId,
- "X-MerchantServer-App-SecretKey": appSecretKey
+ "X-MerchantServer-App-Id": Configuration.appIdentifier,
+ "X-MerchantServer-App-SecretKey": Configuration.appSecretKey
]
let session = URLSession(configuration: .default)
@@ -77,10 +82,7 @@ extension ShoppingCartViewController: CheckoutViewControllerDelegate {
switch result {
case let .payment(payment):
- if payment.status == .authorised {
- success = true
- }
-
+ success = (payment.status == .received || payment.status == .authorised)
case let .error(error):
switch error {
case .canceled:
diff --git a/Examples/Quick Integration Example/Quick Integration Example/de.lproj/Main.strings b/Examples/Quick Integration Example/Quick Integration Example/de.lproj/Main.strings
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/de.lproj/Main.strings
@@ -0,0 +1 @@
+
diff --git a/Examples/Quick Integration Example/Quick Integration Example/en.lproj/Main.strings b/Examples/Quick Integration Example/Quick Integration Example/en.lproj/Main.strings
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/en.lproj/Main.strings
@@ -0,0 +1 @@
+
diff --git a/Examples/Quick Integration Example/Quick Integration Example/es.lproj/Main.strings b/Examples/Quick Integration Example/Quick Integration Example/es.lproj/Main.strings
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/es.lproj/Main.strings
@@ -0,0 +1 @@
+
diff --git a/Examples/Quick Integration Example/Quick Integration Example/fr.lproj/Main.strings b/Examples/Quick Integration Example/Quick Integration Example/fr.lproj/Main.strings
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/fr.lproj/Main.strings
@@ -0,0 +1 @@
+
diff --git a/Examples/Quick Integration Example/Quick Integration Example/it.lproj/Main.strings b/Examples/Quick Integration Example/Quick Integration Example/it.lproj/Main.strings
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/it.lproj/Main.strings
@@ -0,0 +1 @@
+
diff --git a/Examples/Quick Integration Example/Quick Integration Example/nl.lproj/Main.strings b/Examples/Quick Integration Example/Quick Integration Example/nl.lproj/Main.strings
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/nl.lproj/Main.strings
@@ -0,0 +1 @@
+
diff --git a/Examples/Quick Integration Example/Quick Integration Example/pt.lproj/Main.strings b/Examples/Quick Integration Example/Quick Integration Example/pt.lproj/Main.strings
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/pt.lproj/Main.strings
@@ -0,0 +1 @@
+
diff --git a/Examples/Quick Integration Example/Quick Integration Example/sv.lproj/Main.strings b/Examples/Quick Integration Example/Quick Integration Example/sv.lproj/Main.strings
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/Examples/Quick Integration Example/Quick Integration Example/sv.lproj/Main.strings
@@ -0,0 +1 @@
+
diff --git a/Podfile b/Podfile
new file mode 100644
index 0000000000..9dc62ceccb
--- /dev/null
+++ b/Podfile
@@ -0,0 +1,26 @@
+platform :ios, '9.0'
+
+use_frameworks!
+
+def shared_pods
+ pod 'AdyenCSE', '~> 1.0.4'
+end
+
+target 'Adyen' do
+
+ shared_pods
+
+ pod 'SwiftLint', '~> 0.20.0'
+ pod 'SwiftFormat/CLI', '~> 0.28.6'
+
+ target 'AdyenTests' do
+ inherit! :search_paths
+ end
+
+end
+
+target 'AdyenUIHost' do
+
+ shared_pods
+
+end
diff --git a/README.md b/README.md
index 9eab2122df..b4a364d27b 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,16 @@
# Adyen SDK for iOS
-With Adyen SDK you can dynamically list all relevant payment methods for a specific transaction, so your shoppers can always pay with the method of their choice. The methods are listed based on the shopper's country, transaction currency, and amount.
+With Adyen SDK you can help your shoppers pay with a payment method of their choice, selected from a dynamically generated list of available payment methods. Method availability is based on shoppers’ location, transaction currency, and transaction amount.
+
+You can integrate the SDK in two ways: either make use of the default UI components and flows preconfigured by Adyen (Quick integration), or implement your own UI and checkout experience (Custom integration).
+
+
+![Alt text](https://docs.adyen.com/developers/files/28871718/28871719/1/1496836138365/iOS+SDK.png)
+
## Installation
-Adyen SDK can be integrated into your project using CocoaPods. For this, add the following line to your Podfile and run `pod install`.
+
+Use CocoaPods to integrate the Adyen SDK into your project. For this, add the following line to your Podfile and run `pod install`.
```
pod 'Adyen'
@@ -11,197 +18,58 @@ pod 'Adyen'
## Quick integration
-It is very easy to enable your app accepting all payment methods offered by Adyen. SDK provides UI components for payment method selection, entering payment details (credit card entry form, iDEAL issuer selection, and so on).
+If you want to quickly integrate with Adyen, use the default UI elements that we provide for selecting payment methods, entering payment details, and completing a payment.
-For quick integration, initiate `CheckoutViewController` and present it in your app:
+For this, instantiate `CheckoutViewController`, present it in your app, and implement the `CheckoutViewControllerDelegate` protocol for callbacks. All UI interactions are handled by Adyen.
```swift
-var viewController: CheckoutViewController?
-
-// ...
-
-func presentCheckoutViewController() {
- viewController = CheckoutViewController(delegate: self)
- present(viewController!, animated: true, completion: nil)
-}
+let viewController = CheckoutViewController(delegate: self)
+present(viewController!, animated: true)
```
-After you implement the `CheckoutViewControllerDelegate` protocol, all UI interactions will be handled by SDK. Keeping a reference to the `CheckoutViewController` instance will ensure that delegate callbacks are received.
-
+The following `CheckoutViewControllerDelegate` methods should be implemented:
##### - checkoutViewController:requiresPaymentDataForToken:completion:
+This method requires you to fetch payment data from your server and pass it to the `completion` handler. Upon receiving valid payment data, the SDK will present a list of available payment methods.
-This method will be called first. It indicates that your app should obtain payment data from your server using the provided SDK `token`. Your server should make an API call to Adyen to initiate a payment request. The response from Adyen should be passed to SDK. For your convenience, we offer a test merchant server. Always use your own implementation when testing before going live.
-
-Pass received payment data to SDK using `completion`. SDK will present the list of payment methods after you provide payment data.
-
-```swift
-func checkoutViewController(_ controller: CheckoutViewController, requiresPaymentDataForToken token: String, completion: @escaping DataCompletion) {
-
- let paymentDetails: [String: Any] = [
- "basketId": "#237867422",
- "customerId": "user349857934",
- "appUrl": "my-shopping-app://", // Your App URI Scheme.
- "sdkToken": token // Pass the `token` received from SDK.
- ]
-
- // For your convenience, we offer a test merchant server. Always use your own implementation when testing before going live.
- let url = URL(string: "https://shopper-test.adyen.com/demo/easy-integration/merchantserver/setup")!
-
- var request = URLRequest(url: url)
- request.httpMethod = "POST"
- request.httpBody = try? JSONSerialization.data(withJSONObject: paymentDetails, options: [])
- request.allHTTPHeaderFields = [
- "X-MerchantServer-App-Id": "my-shopping-app",
- "X-MerchantServer-App-SecretKey": "06000100304F8D207D33F280549E06CDAE006BA186050F8E8CA79598A5C9558100027B7D",
- "Content-Type": "application/json"
- ]
-
- let session = URLSession(configuration: .default)
- session.dataTask(with: request) { data, response, error in
- if let data = data {
- completion(data)
- }
- }.resume()
-}
-```
+For your convenience, we provide a [test merchant server](https://checkoutshopper-test.adyen.com/checkoutshopper/demo/easy-integration/merchantserver/). You can find information on setting up your own server [here](https://docs.adyen.com/developers/in-app-integration#checkoutapiimplementyourserver).
##### - checkoutViewController:requiresReturnURL:
-This method will be called if a selected payment method requires user authentication outside of your app environment (for example, in a web browser or native payment method app). After a user completes authorisation, your app will be opened using App URI Scheme. Use `completion` to provide SDK with the URL that was used to open your app.
-
-```swift
-func checkoutViewController(_ controller: CheckoutViewController, requiresReturnURL completion: @escaping URLCompletion) {
- // Call `completion` when you receive the app's `openURL`.
- let openURL = // Get the app's `openURL`.
- completion(openURL)
-}
-```
+This method will be called if a selected payment method requires user authentication outside of your app environment (in a web browser, native banking app, etc.). Upon payment authorisation, your app will be reopened using the `application(_:open:options:)` callback of `UIApplicationDelegate`. The URL used to open your app should be passed to the completion handler.
##### - checkoutViewController:didFinishWith:
-Finally, you need to handle `result` for your payment request. You will get a payment object with the status (`authorised`, `refused`, etc.). Use this object to verify integrity of the payment with your server. Present the confirmation screen to the user to confirm the purchase.
+This method will provide you with the result of the completed payment request (authorised, refused, etc.).
-```swift
-func checkoutViewController(_ controller: CheckoutViewController, didFinishWith result: PaymentRequestResult) {
- // Handle the result.
- // ...
-}
-```
+For implementation details, refer to the [Quick integration guide](https://docs.adyen.com/developers/in-app-integration?platform=inapp-ios).
-## Custom integration
-
-It is possible to have more control over the payment flow — presenting your own UI for specific payment methods, filtering a list of payment methods, or implementing your own unique checkout experience.
-
-For more control, start a payment request and implement the `PaymentRequestDelegate` protocol to get notified when your payment is authorized.
-
-```swift
-let request = PaymentRequest(delegate: self)
-request.start()
-```
-After you implement the `PaymentRequestDelegate` protocol, you will have full control over the payment flow.
-
-##### - paymentRequest:requiresPaymentDataForToken:completion:
-
-This method will be called first. It indicates that your app should obtain payment data from your server using the provided SDK `token`. Your server should make an API call to Adyen to initiate a payment request. The response from Adyen should be passed to SDK. For your convenience, we offer a test merchant server. Always use your own implementation when testing before going live.
-
-Pass received payment data to SDK using `completion`. In the next delegate call, SDK will provide the list of available payment methods for your payment request.
-
-```swift
-func paymentRequest(_ request: PaymentRequest, requiresPaymentDataForToken token: String, completion: @escaping DataCompletion) {
-
- let paymentDetails: [String: Any] = [
- "basketId": "#237867422",
- "customerId": "user349857934",
- "appUrl": "my-shopping-app://", // Your App URI Scheme.
- "sdkToken": token // Pass the `token` received from SDK.
- ]
-
- // For your convenience, we offer a test merchant server. Always use your own implementation when testing before going live.
- let url = URL(string: "https://checkoutshopper-test.adyen.com/checkoutshopper/demo/easy-integration/merchantserver/setup")!
-
- var request = URLRequest(url: url)
- request.httpMethod = "POST"
- request.httpBody = try? JSONSerialization.data(withJSONObject: paymentDetails, options: [])
- request.allHTTPHeaderFields = [
- "X-MerchantServer-App-Id": "my-shopping-app",
- "X-MerchantServer-App-SecretKey": "06000100304F8D207D33F280549E06CDAE006BA186050F8E8CA79598A5C9558100027B7D",
- "Content-Type": "application/json"
- ]
-
- let session = URLSession(configuration: .default)
- session.dataTask(with: request) { data, response, error in
- if let data = data {
- completion(data)
- }
- }.resume()
-}
-```
-
-##### paymentRequest:requiresPaymentMethodFrom:availableMethods:completion:
-
-This method will give you two lists of payment methods available for your payment request. `prefferedMethods` will contain `One-Click` enabled payment methods. Other payment options will be in the `availableMethods` list.
-
-Call `completion` with the selected payment method to indicate a shopper's choice.
-
-```swift
+## Custom integration
-func paymentRequest(_ request: PaymentRequest, requiresPaymentMethodFrom preferredMethods: [PaymentMethod]?, available availableMethods: [PaymentMethod], completion: @escaping MethodCompletion) {
- // Present the list of payment methods and call `completion` with a user's choice.
- // ...
-}
-```
+With custom integration you will have full control over the payment flow and will be able to implement your own unique checkout experience.
+This approach requires instantiating and starting a `PaymentRequest` and implementing the `PaymentRequestDelegate` protocol for callbacks. The `PaymentRequestDelegate` callbacks will provide you with a list of available payment methods, the URL for payment methods that require an external flow, and the result of payment processing.
-##### paymentRequest:requiresReturnURLFrom:completion:
+For implementation details, refer to the [Custom integration guide](https://docs.adyen.com/developers/in-app-integration/custom-integration).
-This method will be called if a selected payment method requires user authorisation outside of your app environment (for example, in a web browser or native payment method app). Use the provided `url` to start authorisation process. After a user completes authorisation, your app will be opened using App URI Scheme. Use `completion` to provide SDK with the URL that was used to open your app.
-```swift
-func paymentRequest(_ request: PaymentRequest, requiresReturnURLFrom url: URL, completion: @escaping URLCompletion) {
- // Open redirect URL (for example in `SFViewController`).
- // ...
-
- // Call `completion` when you receive the app's `openURL`.
- let openURL = // Get the app's `openURL`.
- completion(openURL)
-}
-```
+## Examples
+You can find examples of both quick and custom integrations in the Examples folder of this repository.
-##### paymentRequest:requiresPaymentDetails:completion:
-This method will be called when additional payment details input is required for the specific payment method. SDK will give you a list of parameters required to provide. Get requested parameters from the user by presenting your own UI and pass them to SDK using `completion`.
+## See also
-```swift
-func paymentRequest(_ request: PaymentRequest, requiresPaymentDetails details: PaymentDetails, completion: @escaping PaymentDetailsCompletion) {
- // Present payment details entry screen to the user.
- // ...
-
- // Pass received payment details to SDK.
- details.fill... // Get the user's input.
- completion(details)
-}
-```
+ * [Complete Documentation](https://docs.adyen.com/developers/in-app-integration?platform=inapp-ios)
-
-##### - paymentRequest:didFinishWith:
-
-Finally, you need to handle `result` for your payment request. You will get a payment object with the status (`authorized`, `refused`, etc.). Use this object to verify integrity of the payment with your server. Present confirmation screen to the user to confirm the purchase.
-
-```swift
-func paymentRequest(_ request: PaymentRequest, didFinishWith result: PaymentRequestResult) {
- // Handle the result.
- // ...
-}
-```
+ * [SDK Reference](https://adyen.github.io/adyen-ios/Docs/index.html)
## License
diff --git a/UnitTests/CoreUI/UIColorExtensionsTests.swift b/UnitTests/CoreUI/UIColorExtensionsTests.swift
deleted file mode 100644
index d5d191e158..0000000000
--- a/UnitTests/CoreUI/UIColorExtensionsTests.swift
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright (c) 2017 Adyen B.V.
-//
-// This file is open source and available under the MIT license. See the LICENSE file for more info.
-//
-
-import XCTest
-@testable import Adyen
-
-class UIColorExtensionsTests: XCTestCase {
-
- func test12bitHexToColorConversion() {
- let white = UIColor(hexString: "FFF")
- let black = UIColor(hexString: "000")
- let blue = UIColor(hexString: "00F")
- let green = UIColor(hexString: "0F0")
- let red = UIColor(hexString: "F00")
- let pink = UIColor(hexString: "E7A")
-
- XCTAssertEqual(white, UIColor(red: 1, green: 1, blue: 1, alpha: 1))
- XCTAssertEqual(black, UIColor(red: 0, green: 0, blue: 0, alpha: 1))
- XCTAssertEqual(blue, UIColor(red: 0, green: 0, blue: 1, alpha: 1))
- XCTAssertEqual(green, UIColor(red: 0, green: 1, blue: 0, alpha: 1))
- XCTAssertEqual(red, UIColor(red: 1, green: 0, blue: 0, alpha: 1))
- XCTAssertEqual(pink, UIColor(red: 238 / 255, green: 119 / 255, blue: 170 / 255, alpha: 1))
- }
-
- func test12bitHexToColorConversionWithAlpha() {
- let blueWithAlpha = UIColor(hexString: "00F", alpha: 0.5)
-
- XCTAssertEqual(blueWithAlpha, UIColor(red: 0, green: 0, blue: 1, alpha: 0.5))
- }
-
- func test24bitHexToColorConversion() {
- let white = UIColor(hexString: "FFFFFF")
- let black = UIColor(hexString: "000000")
- let blue = UIColor(hexString: "0000FF")
- let green = UIColor(hexString: "00FF00")
- let red = UIColor(hexString: "FF0000")
- let softPink = UIColor(hexString: "FFC0CB")
-
- XCTAssertEqual(white, UIColor(red: 1, green: 1, blue: 1, alpha: 1))
- XCTAssertEqual(black, UIColor(red: 0, green: 0, blue: 0, alpha: 1))
- XCTAssertEqual(blue, UIColor(red: 0, green: 0, blue: 1, alpha: 1))
- XCTAssertEqual(green, UIColor(red: 0, green: 1, blue: 0, alpha: 1))
- XCTAssertEqual(red, UIColor(red: 1, green: 0, blue: 0, alpha: 1))
- XCTAssertEqual(softPink, UIColor(red: 255 / 255, green: 192 / 255, blue: 203 / 255, alpha: 1))
- }
-
- func test24bitHexToColorConversionWithAlpha() {
- let blueWithAlpha = UIColor(hexString: "0000FF", alpha: 0.5)
-
- XCTAssertEqual(blueWithAlpha, UIColor(red: 0, green: 0, blue: 1, alpha: 0.5))
- }
-}
diff --git a/VERSION b/VERSION
deleted file mode 100644
index 3a3cd8cc8b..0000000000
--- a/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-1.3.1
diff --git a/format.sh b/format.sh
index e8395fde0e..8af63e9b95 100755
--- a/format.sh
+++ b/format.sh
@@ -2,8 +2,8 @@
echo "Formatting..."
-./Example/1-quick-integration-example/Pods/SwiftFormat/CommandLineTool/swiftformat Adyen/ Example/ \
- --disable blankLinesAtEndOfScope,unusedArguments \
+./Pods/SwiftFormat/CommandLineTool/swiftformat ./ \
+ --disable blankLinesAtEndOfScope,unusedArguments,redundantSelf \
--comments ignore \
--commas inline \
--ranges nospace \