diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
deleted file mode 100644
index 2542f7b..0000000
--- a/.github/workflows/main.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: Code Analysis
-on: [push]
-jobs:
- lint:
- name: Run PSScriptAnalyzer
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: Run PSScriptAnalyzer
- uses: devblackops/github-action-psscriptanalyzer@master
- with:
- sendComment: false
- failOnErrors: true
- failOnWarnings: true
- failOnInfos: true
diff --git a/.gitignore b/.gitignore
index 79d24ac..ca3507e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,11 @@
*.key
ENVELOPE_ID
TEMPLATE_ID
+FORM_GROUP_ID
+API_ACCOUNT_ID
+ds_access_token.txt
.vs/*
.vscode/*
debug.log
config/settings.json
+demo_documents/web-form-config.json
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 390a206..e769623 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License
-Copyright (c) 2018 DocuSign, Inc. (https://www.docusign.com)
+Copyright (c) 2018 Docusign, Inc. (https://www.docusign.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/OAuth/code_grant.ps1 b/OAuth/code_grant.ps1
index 7a63b45..70ed118 100644
--- a/OAuth/code_grant.ps1
+++ b/OAuth/code_grant.ps1
@@ -4,7 +4,10 @@ param(
[Parameter(Mandatory = $true)]
[string]$clientSecret,
[Parameter(Mandatory = $true)]
- [string]$apiVersion)
+ [string]$apiVersion,
+ [Parameter(Mandatory = $true)]
+ [string]$targetAccountId
+ )
$PORT = '8080'
$IP = 'localhost'
@@ -17,77 +20,136 @@ $state = [Convert]::ToString($(Get-Random -Maximum 1000000000), 16)
if($apiVersion -eq "rooms"){
$scopes = "signature%20dtr.rooms.read%20dtr.rooms.write%20dtr.documents.read%20dtr.documents.write%20dtr.profile.read%20dtr.profile.write%20dtr.company.read%20dtr.company.write%20room_forms"
}
-elseif ($apiVersion -eq "eSignature") {
+elseif (($apiVersion -eq "eSignature") -or ($apiVersion -eq "idEvidence")){
$scopes = "signature"
}
elseif ($apiVersion -eq "click") {
- $scopes = "click.manage"
+ $scopes = "click.manage%20click.send%20signature"
+}
+elseif ($apiVersion -eq "monitor") {
+ $scopes = "signature impersonation"
+}
+elseif ($apiVersion -eq "admin") {
+ $scopes = "signature%20organization_read%20group_read%20permission_read%20user_read%20user_write%20account_read%20domain_read%20identity_provider_read%20user_data_redact%20asset_group_account_read%20asset_group_account_clone_write%20asset_group_account_clone_read%20organization_sub_account_write%20organization_sub_account_read"
+}
+elseif ($apiVersion -eq "notary") {
+ $scopes = "signature%20organization_read%20notary_read%20notary_write"
+}
+elseif ($apiVersion -eq "maestro") {
+ $scopes = "signature%20aow_manage"
+}
+elseif ($apiVersion -eq "webForms") {
+ $scopes = "signature%20webforms_read%20webforms_instance_read%20webforms_instance_write"
+}
+elseif ($apiVersion -eq "navigator") {
+ $scopes = "signature%20adm_store_unified_repo_read"
+}
+elseif ($apiVersion -eq "connectedFields") {
+ $scopes = "signature adm_store_unified_repo_read"
+}
+elseif ($apiVersion -eq "workspaces") {
+ $scopes = "signature%20impersonation%20dtr.company.read%20dtr.rooms.read%20dtr.rooms.write%20dtr.documents.write"
+}
+
+function GenerateCodeVerifier {
+ return -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 43 | ForEach-Object {[char]$_})
+}
+function GenerateCodeChallenge($verifier) {
+ $sha256 = [System.Security.Cryptography.SHA256]::Create()
+ $hash = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($verifier))
+ return [Convert]::ToBase64String($hash).TrimEnd('=').Replace('+', '-').Replace('/', '_')
+}
+
+function StartHttpListenerAndAuthorize {
+ param (
+ [string]$authorizationURL,
+ [string]$redirectURI
+ )
+
+ $http = New-Object System.Net.HttpListener
+ $http.Prefixes.Add("$redirectURI/")
+
+ try {
+ $http.Start()
+ } catch {
+ Write-Error "OAuth listener failed. Is port 8080 in use by another program?" -ErrorAction Stop
+ return $null
+ }
+
+ if ($http.IsListening) {
+ # Notify the user to open the authorization URL
+ Write-Output "Open the following URL in a browser to continue: $authorizationURL"
+ Start-Process $authorizationURL
+ }
+
+ while ($http.IsListening) {
+ $context = $http.GetContext()
+
+ if ($context.Request.HttpMethod -eq 'GET' -and $context.Request.Url.LocalPath -match '/authorization-code/callback') {
+ # Prepare the HTML response
+ [string]$html = '
+
+
+
Candy bonbon pastry jujubes lollipop wafer biscuit biscuit. Topping brownie sesame snaps sweet roll pie. Croissant danish biscuit soufflé caramels jujubes jelly. Dragée danish caramels lemon drops dragée. Gummi bears cupcake biscuit tiramisu sugar plum pastry. Dragée gummies applicake pudding liquorice. Donut jujubes oat cake jelly-o. Dessert bear claw chocolate cake gummies lollipop sugar plum ice cream gummies cheesecake.
diff --git a/demo_documents/order_form.html b/demo_documents/order_form.html
index ae79998..5df418d 100644
--- a/demo_documents/order_form.html
+++ b/demo_documents/order_form.html
@@ -26,7 +26,7 @@
Xylophone
- /l2q/
+ /l2q/
$150
diff --git a/demo_documents/web-form-config.json b/demo_documents/web-form-config.json
new file mode 100644
index 0000000..047e90e
--- /dev/null
+++ b/demo_documents/web-form-config.json
@@ -0,0 +1,2 @@
+{ "id": "608a6c8a-16b2-4419-92f4-d06bc3af6e53", "accountId": "85443307-xxxx-xxxx-xxxx-87671e153075", "isPublished": true, "isEnabled": true, "hasDraftChanges": false, "formState": "active", "formProperties": { "name": "Web Form Example Template", "isPrivateAccess": false, "allowSending": true }, "formMetadata": { "source": "templates", "createdDateTime": "2025-08-19T21:15:03.323Z", "publishedSlug": "d12c1e15b310d55b4e530edfd64c1b63", "owner": { "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "userName": "Raileen Del Rosario" }, "lastModifiedDateTime": "2025-08-19T21:18:40.409Z", "lastModifiedBy": { "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "userName": "Raileen Del Rosario" }, "publishedComponentNames": { "signer_name": "TextBox", "signer_email": "Email", "FullName": "TextBox", "PhoneNumber": "TextBox", "Yes": "CheckboxGroup", "Company": "TextBox", "JobTitle": "TextBox", "$recipients": { "41f3109b-ff3a-4c48-a40c-eac994ad0988": { "components": { "signer_name": { "type": "TextBox" }, "signer_email": { "type": "Email" }, "FullName": { "type": "TextBox" }, "PhoneNumber": { "type": "TextBox" }, "Yes": { "type": "CheckboxGroup" }, "Company": { "type": "TextBox" }, "JobTitle": { "type": "TextBox" } } } } }, "admModelNamespace": "docusign.forms._85443307_664c_4c85_882f_87671e153075._608a6c8a_16b2_4419_92f4_d06bc3af6e53", "formContentModifiedBy": { "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "userName": "Raileen Del Rosario" }, "formContentModifiedDateTime": "2025-08-19T21:18:09.337Z", "admModelVersion": "1.0.0", "type": "hasEsignTemplate", "formPropertiesModifiedBy": { "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "userName": "Raileen Del Rosario" }, "formPropertiesModifiedDateTime": "2025-08-19T21:15:39.578Z", "sender": { "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "userName": "Raileen Del Rosario" }, "lastSenderConsentDateTime": "2025-08-19T21:18:34.468Z", "lastPublishedBy": { "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "userName": "Raileen Del Rosario" }, "lastPublishedDateTime": "2025-08-19T21:18:40.409Z", "lastEnabledBy": { "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "userName": "Raileen Del Rosario" }, "lastEnabledDateTime": "2025-08-19T21:18:40.409Z" }, "formContent": { "components": { "Root_Of_Journey": { "children": [ "View_41f3109b-ff3a-4c48-a40c-eac994ad0988" ], "componentKey": "Root_Of_Journey", "componentName": "Root_Of_Journey", "componentRules": {}, "componentType": "Root", "schemaVersion": 2, "text": "" }, "View_41f3109b-ff3a-4c48-a40c-eac994ad0988": { "children": [ "Welcome_qXWJJEvM", "Step_69uweXrH", "Summary_2KLFQRxQ", "ESignAction_7XmnXEcI", "Thankyou_feHjbCWS" ], "componentKey": "View_41f3109b-ff3a-4c48-a40c-eac994ad0988", "componentType": "View", "isEnabled": true, "isSender": false, "roleName": "signer" }, "Welcome_qXWJJEvM": { "startButtonText": "Start", "subText": "Part-Time Work Application", "text": "Welcome", "componentKey": "Welcome_qXWJJEvM", "componentType": "Welcome" }, "Step_69uweXrH": { "children": [ "TextBox_OWBHFHgL", "Email_cJoe6lNy", "TextBox_FPT2Gs29", "TextBox_BOTyRGju", "CheckboxGroup_MyyHfWle", "TextBox_mwg3Cl1O", "TextBox_AHodbvx_" ], "componentKey": "Step_69uweXrH", "componentName": "Step_69uweXrH", "componentType": "Step", "text": "Part-Time Work Application" }, "Summary_2KLFQRxQ": { "subText": "Please review the information you have entered:", "text": "Summary", "componentKey": "Summary_2KLFQRxQ", "componentType": "Summary" }, "ESignAction_7XmnXEcI": { "componentKey": "ESignAction_7XmnXEcI", "componentType": "ESignAction", "documentInfoMap": { "Document_fRTvNpa8": { "documentId": "1", "name": "World_Wide_Web_Form", "order": "1" } }, "enableDocumentFieldEditing": true, "primaryRecipientId": "1", "recipientInfoMap": { "1": { "emailComponentKey": "Email_cJoe6lNy", "emailFromTemplate": "", "nameComponentKey": "TextBox_OWBHFHgL", "nameFromTemplate": "", "recipientId": "1", "recipientType": "signer", "roleName": "signer", "routingOrder": "1", "recipientViewId": "41f3109b-ff3a-4c48-a40c-eac994ad0988" } }, "requireRemoteSigning": false, "tabInfoMap": { "c995df10-9141-4686-b9bf-f1dfc4121d33": { "componentKey": "TextBox_FPT2Gs29", "locked": "false", "recipientId": "1", "tabId": "c995df10-9141-4686-b9bf-f1dfc4121d33", "tabLabel": "FullName", "tabType": "text" }, "71ccfefa-5469-493e-b0c7-886c65b84742": { "componentKey": "TextBox_BOTyRGju", "locked": "false", "recipientId": "1", "tabId": "71ccfefa-5469-493e-b0c7-886c65b84742", "tabLabel": "PhoneNumber", "tabType": "text" }, "184f8a65-f2be-48b9-a30e-15592c59b335": { "componentKey": "TextBox_mwg3Cl1O", "locked": "false", "recipientId": "1", "tabId": "184f8a65-f2be-48b9-a30e-15592c59b335", "tabLabel": "Company", "tabType": "text" }, "e7d30733-ce70-4fee-93a0-ea10ecc014b1": { "componentKey": "TextBox_AHodbvx_", "locked": "false", "recipientId": "1", "tabId": "e7d30733-ce70-4fee-93a0-ea10ecc014b1", "tabLabel": "JobTitle", "tabType": "text" }, "0f1e242d-550d-4729-a141-de0dce1d1b6c": { "componentKey": "CheckboxGroup_MyyHfWle", "locked": "false", "name": "Yes", "recipientId": "1", "selected": "false", "tabId": "0f1e242d-550d-4729-a141-de0dce1d1b6c", "tabLabel": "Yes", "tabType": "checkbox" } }, "templateInfoMap": { "2230c545-1680-47aa-8581-7d2284093f46": { "lastModified": "2025-08-19T21:15:03.9670000Z", "name": "Web Form Copy - Web Form Example Template", "owner": { "userName": "Raileen Del Rosario", "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "email": "example@email.com" }, "templateId": "e8af8a0d-f7ab-4cd2-b6f5-c84d5ecc1bf8" } } }, "Thankyou_feHjbCWS": { "confirmationButtonText": "Done", "confirmationButtonUrl": "", "showConfirmationButton": false, "subText": "We've received your form.", "text": "Thank you", "componentKey": "Thankyou_feHjbCWS", "componentType": "Thankyou" }, "TextBox_OWBHFHgL": { "componentKey": "TextBox_OWBHFHgL", "componentName": "signer_name", "componentType": "TextBox", "description": "", "label": "Signer Name", "maxLength": 4000, "multiLine": false, "placeholder": "", "required": true }, "Email_cJoe6lNy": { "componentKey": "Email_cJoe6lNy", "componentName": "signer_email", "componentType": "Email", "description": "", "label": "Signer Email", "maxLength": 4000, "multiLine": false, "placeholder": "", "required": true }, "TextBox_FPT2Gs29": { "componentKey": "TextBox_FPT2Gs29", "componentName": "FullName", "componentType": "TextBox", "description": "", "label": "Full Name", "maxLength": 4000, "multiLine": false, "placeholder": "", "required": true }, "TextBox_BOTyRGju": { "componentKey": "TextBox_BOTyRGju", "componentName": "PhoneNumber", "componentType": "TextBox", "description": "", "label": "Phone Number", "maxLength": 4000, "multiLine": false, "placeholder": "", "required": true }, "CheckboxGroup_MyyHfWle": { "componentKey": "CheckboxGroup_MyyHfWle", "componentName": "Yes", "componentType": "CheckboxGroup", "description": "", "label": "I prefer to be contacted by text.", "options": [ { "label": "Yes", "optionKey": "i_BVfm2G", "selected": false, "value": "Yes" } ] }, "TextBox_mwg3Cl1O": { "componentKey": "TextBox_mwg3Cl1O", "componentName": "Company", "componentType": "TextBox", "description": "", "label": "Company", "maxLength": 4000, "multiLine": false, "placeholder": "", "required": true }, "TextBox_AHodbvx_": { "componentKey": "TextBox_AHodbvx_", "componentName": "JobTitle", "componentType": "TextBox", "description": "", "label": "Job Title", "maxLength": 4000, "multiLine": false, "placeholder": "", "required": true } }, "isStandalone": false, "templates": [ { "originalTemplateId": "e8af8a0d-f7ab-4cd2-b6f5-c84d5ecc1bf8", "clonedTemplateId": "e8af8a0d-f7ab-4cd2-b6f5-c84d5ecc1bf8", "importedDateTime": "2025-08-19T21:15:05.277Z", "recipientIds": [ "1" ] } ] }, "formLocale": "en", "versionId": 1, "eSignTemplates": [ { "templateId": "e8af8a0d-f7ab-4cd2-b6f5-c84d5ecc1bf8", "uri": "/templates/e8af8a0d-f7ab-4cd2-b6f5-c84d5ecc1bf8", "name": "Web Form Copy - Web Form Example Template", "shared": "false", "passwordProtected": "false", "description": "Example template created via the API", "created": "2025-08-19T21:15:03.7170000Z", "lastModified": "2025-08-19T21:18:40.2070000Z", "lastModifiedBy": { "userName": "Raileen Del Rosario", "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "email": "example@email.com", "uri": "/users/53d98270-xxxx-xxxx-xxxx-6d080391b538" }, "lastUsed": "2025-08-19T21:15:03.9830000Z", "owner": { "userName": "Raileen Del Rosario", "userId": "53d98270-xxxx-xxxx-xxxx-6d080391b538", "email": "example@email.com" }, "pageCount": "1", "folderId": "cf5522c4-cac6-4f81-9a57-d5fe179cae1c", "folderName": "Deleted Items", "folderIds": [ "cf5522c4-cac6-4f81-9a57-d5fe179cae1c" ], "autoMatch": "true", "autoMatchSpecifiedByUser": "false", "documents": [ { "documentId": "1", "uri": "/envelopes/2230c545-1680-47aa-8581-7d2284093f46/documents/1", "name": "World_Wide_Web_Form", "order": "1", "pages": "1", "documentBase64": "JVBERi0xLjUKJfv8/f4KOCAwIG9iago8PC9MZW5ndGggMTc+PnN0cmVhbQoKIFEgIHEgL1gxIERvCiBRIAplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKPDwvTGVuZ3RoIDQ+PnN0cmVhbQoKIHEgCmVuZHN0cmVhbQplbmRvYmoKOSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDEzMjU+PnN0cmVhbQp4nNVZ244cNRB9n6/oZ6Q4dbdLQkjZJJvnwErwziUSIiDC/0uUZ+ztzsy6u3fILpDJXmSvXVWnTt26cYL4vMD4lp2mHz8e/jykrMfV/jMWcaqfb99Np18+fTi8fMfTh78Odb+gTQhq06efD78c3p/dkCkhE4BMGZKqu5d6Y2wiqU6Js2m9+fOFWcLN3eHlrUxM090vB+zqxpVTssxIwjjd1fteMCQQKyHz7qfpawB+9c109+uBNGU/LkPb0FBHNVS6ja98/KO3dwNBRJJCiu6WZqlQqQe6NHldpcRXWZfEoAnrfVuSyGYTlPulY9zdE1yNO5aT0/wMfkwmYGEmWnIoxbq2mJNQDkO6tieAEUOAiEJeAHPc0UQljMs8+8ePG6F2YbJMO07YcSOnuD/+844T1GS4kuksQvHMSw8DQIAJxSrzN+wfCRLfJ4g4qaBv43zb5LAjZtlhqTbMCIpJWfjlRFSEhKhWbbw/Avt0LgGOk+9QursHDX3h6EbrUIGZAXLZ9rTOWjPnzOUBrccxgvx5cqqfY3DUz1lQ6MDsyIQR/LmA5W4uJ4/rAbDbe9N8oYE525wk+HXbQNWM6vcbdgofS+pUWOYT9qpB59ms6t03/LZtWC6Yzc9PWLjAC0k557yEUUq09PfpBGpEYgRvwRF7R5Dk0BslAn8bGm55wmrUg7vMWrzpBM6QTWgbGy27tEOiRBrM0231QHoaIw4+L2GVh+NrtN6y2wNoj9wgPVLjGqZywZqSvLCyln/i6hHIerMdPRRABjk2IyeypSSr//JZ5HCC7CcHnfDvuKM1SzJLTbiziTcNlCit4cSL6sGJjcXFzzc6K0bKRMGXLLUbGipFPaWKQSb2c4fkBAQCs7I9kDC0zeGQRbL1noWduNb8vlFuu7aXzdeq/pYj+UYJyGP9/aanCANzmLH78mhfbjwHeL6HtOJPRVrqaEUuF8FZ4VaKHoDxTd+IRqXgImBHwMs+Nkv0XWCRGh5P5rHPxw6RdW0vPdVyeHQA4CY+X3U1/z1gR8pkV/D/GR13CcV/1BG7YikK/VMVgH08j6wBFq0mj2+yESbNdEmORks63IOFkcN4UfPlbTuBkCUq7G54N8PVUljhtmbGqyY7+r7oms6ZuCXBKAWxqayUty3ybIkoENHA6yK0FZro4s3KY+JJLcahhd0zHgwRNdv15F52jByCC+fNN2kgJDu8Kvu8Gi1wAo/+0neAbhTj2IJrmffJMKgPDgruos7IQMjAi9kxU4OKPRgMFw1mhAx4DHTzTVen7ehZEkTjj9ek7dtB20KndhcpKUOBxTOg4ZE96Y6Bn7112E5SRMEVnlv6DM3EmHBM5OIZxwM92yj4hhXIyi5yamRKM/aVnhS67IKSdVdGGFa/YaYftpjdPqGCuBikWvAFhsyui6i8nuf1GQirFbmC6P8zkHbFEsOTtQ69StcHqojbYLUcvDkhcpTQKEMr2Zx7v4hCMQotHDWKvWFGHQ5SX3501EiHhAJ6BTX/VYt3Ec1KirYhiBbFgHlafg+ELhePBMyVgJHta2cRmryI7snr5seD0Wk5z4u/Hb5bU6DIk1WNUTUbgi/9RPGShRZt5KPnltYEXZ64moeyMq4+vgn4ghhgaSMaMtaOYnffv1a2h1y+pMkqarxWUqC/HgDMEGnvPNsHCEW4XnF9N3y9vzEQLaBXlcRnMOzz9JI5Ct3pjSb3lwYR11kSaX0H+v1X0+/xZ6WZd1qfD0XlTjEJbL1qePlDmd78EQLfH/4GqjsjiAplbmRzdHJlYW0KZW5kb2JqCjEzIDAgb2JqCjw8L1R5cGUvWE9iamVjdC9TdWJ0eXBlL0Zvcm0vRm9ybVR5cGUgMS9SZXNvdXJjZXM8PC9Gb250PDwvVGFsbF9GIDE3IDAgUj4+Pj4vQkJveFswIDAgNjEyLjAgNzkyLjBdL0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMjk2Pj5zdHJlYW0KeJyNUttKw0AQfd+vmB+omc1usgmEgGmrIAgq+yYiYbuRQguaFsG/d/bW2ObBBiZz9szlZGbD4Av4DfoHcAZOIV4kpFSeoNmz7HY8bofeHKFpMv3zaSF76j8stC10qyXLVvZ7a+zLfQfmwGI3uPQHw6JiUob9jMlVQjyB0bKBrR+X7JoJ8lmIPp+m/2cC6PRVC5qHNLXHSb2oc89uGL1GON/M5bA4bSbT/W73fgdVpPQArw2ilIjlQCYQVUFGvqzJFJlFdGKyCFiV5B02oYZS/Nnn1KGX6MNZ5NGon3Bx5ylXyODzDXlORj1FFXI85+LUWPJgnqtibRVqPKeiXtKpYq3TroOuLCNXtm+gH6YtLv6uEdYa3OXD81UXtODqBM//YWrwC7FVocgKZW5kc3RyZWFtCmVuZG9iagoxMiAwIG9iago8PC9UeXBlL1hPYmplY3QvU3VidHlwZS9JbWFnZS9XaWR0aCA4MC9IZWlnaHQgNzQvQ29sb3JTcGFjZS9EZXZpY2VSR0IvQml0c1BlckNvbXBvbmVudCA4L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggOTkzMj4+c3RyZWFtCnic1ZyHW1p5vv//p3ufu3N3N4klJrM7fZOZyZT0MjNJxp4YTUxM78VEjQXsgKBix46ICtJBEAUBsSC9n8Kp+PseSLKZ2ZnZOPfu3efH8/Y8h+Ph8H2dT/1yDmxv/1886O0klUxSdJKmgOhkkkiLZpRMvtrOKJlWchvo/8cHTdMURdE0lkzCFIVQFEaSOJkkSZrEKSCCoEkKiExQBEyTKNiBpnE6iYOzsb39d+bkTx//RqJfe6QHBnhJkoRw0uqPizRrrNHlWxxVUf302crxUw9FZx6P5FZNXW6cvc9TtIwtzS37NiMoQiUBfxKIpt8A0m+t/1t5mXentrcZJbcZT6TxJIVSNIFTiQCUGNdsXGdL/1bW8d8/tL13XvCH3L7/yhv+j/zx/8gf/c+Ckf8sGP6vwvH3Csb/kDf8Xu7gH8/2ZpwXHrk7/qBbPb/qR1CSIkiawsEfxQAzzBT97+RNvjZjSmBQOHBXmKDMW7GHHTOflbT9+Tz/D4Uj712Y+FPRxO6LU3tKJEC7S+Z2X5rZXTq9p2wqo2wqs0ycUTa5+9L4ny+Nvlcy/J/FI+/lDf7xe943N3qah7S+MEQSCeY0khgwOk2R/5bYTnNSKc5tEJ40DsIQpymLO3qtYfwvBe37Lg3uLhrefUGy6xLQVMYlaWbpDFhmXJrJLJPuKZ36Y/Hwny6K/lTY98e87v/O7cq6OJR5eWzX1en3Ls/tKp3LKpXuKh7KKuz47CL7WZfMFYBAqAM7J0GAU8T/vWO/4QVpdZvGEwS5CWHVQuXBUu5Hpf1/uTSYXczPLOw+9ED74bXZnMuT+ypm/npTtr9iJuuyeO/lqYySkT0XhzJKBnfldezO4+3O5YHlnoL+rFJZRrki48p0zuXR/ZdG95SM/bG4f1dx1xdl7W3jRj9CEAQOzms6osHj/wj1tRtTFEkxuZWcWtw4dqf747KhvRcGdud3Zudz9uQ37srnHLg3/8ldzUe3ZTnlwwceyj99IPvskeKz+/JP78u+rdZ/+Uzx+UPJX6727ysT7i8V5pR07i0dyLkqzSlXZJfNZ15R7CmXZ12eyCzu2F0gyMhtOXufb3C4CZIAJqZoJqZBqdv+VxsZuDCTmahtUFYIPIoSLwdUn5QLD9yR51zozSoS7M5v2ZXHyshryshvySru+PDa0Ok63Rf3xd88m/+2SnuswXy4Tn+43nCm1ZLbuX6+c/VU2+IXL2QHHk//7d74RzdHPrk/+/Fj3fv3dPtuKHOuy7MrZnaVje0u7Pxzcd+uou4P8tkD0kWUIEgKJEaKSZT/Yl7m8CBTgjNMUu54opwlPlguPnRPfejBzLHn2g/KRX/Kbcm80LavhPfBle7Pbo0cvC8+w1o432L+sd16vg1o5RzXksu3nWo0/MizlgxtXRzcLOxePfpSeaRK9u3zuZNs07HmlS9qTO/fnf74kfL924q9FfPZVyV7rkj+XDKSc0GYc77pGV8Go4AXp/71gQziNUnSGE6thhJ5z/o/vzH59aPlI5WW0zULp16aP78/k3FB8NeK3oN3h796LP62cu5wteLoS/Xxet2Jes33bN25loWirpUb476ygbWTLNWP/KWKcV/54OZ3bO2pesWZRu3F/s2C/q1z3etnONajbMvBZ8aP7hv231Ttujy999rs3svjf84X7stvu8MaDSJEAlR3kLT/BYGcfCPQCBBJVxg9+3Tg4G3x8af6ozX647WmH+rtPzQ5Pr0j/fj2xBdPpo68kB5/KT9Rrz7O0h1jGU4A1SovALqB1ct9tvtT/grR+veNipI+xwNp5OF0+Obw1g9szcl6Rfmou2zce3HEU9Tnyet2n25d+6bWcuCJcd9VaealseyyiaxCQQbID3m88pdDURihSKY+J1/nlf8tVHAGSSCmoUC9MTz3xeTBu+IjL7Snaq0n65bOsCy57avnWi0HHkx/9Ux2uEp5tFZ5vF51gqU+wdYA5O/Y6tpZb88i2mlC2w2ximFnHtf4TOx6MROtUUSrZL6XssgzSehqn+PhlO/RtP/OhOvy2GbxwEZu1+apVuc3z/V/uzuXVTKUeXHw/ZJeUKf+VCDIKmq91iJGEZTG4ihT/vFtpvf5X8Clt1PFhwadLx5JUA/apJ/fnPi2yniibvEHlu18k72Qt1be7zvNNnzzQgYi8Xid5ngDA3sSmIytOcbSft+k5RvREWtiwgqN2qGKAcuxemVRh/nBmOvh2FqzJtyiijTKA82KkHCJ6DRhTarYjZGNiz2OsxzbUdbyoecLn95XfnRHDnTwrmxPXteewp6Mws6cIk7DkI7AsFQLlhb9Pwxn4CUESMg0RhMJgqDappYPVAweq1o8Xr/yfdNKQZvjUufGtX7PTZH36Mv5Y7WKE/XKE8CyKd408vEGNdhY0KrhqAIza5jEEa2d9xxt0Bxr0JxukP/QIGuQh/kGSKDx9y2ERWakVxfnyEPVEn9ph+V0vf5wjeHAE/1nj3RfVJqO1K5817R69Llu78X+/aXDn92VZ14STixskSBhp0vU/w4vnqQTOEHqHIFPK/q+eqY99dJylmUtbLOXda7fHPI+mgw/m4mdbzeeZqtO1CtONije5j3ZAM6A8hhLd7pBeUNoHF2JnGPPAD8/1aA8xlYfrdN8V6e8N2gdssIic1SoCfHmAs1iT+2Y+8mQ60K79Xi1/pvnuq+eakF++LF9/Wyb41zL8tFKeUZxzyf35veUT3x0e2I9iIKJF0X9T2HTvKCNYzwZpXKrJr96ojrx0vwdy3quxXahc/WmaPPJdLhqHi7rsZ1mA0BgWWVKr3gZpXiPsoBja35oVnP1wVO10pMN6tN1WlCLv65WHHkuPVUtaVGGu3Rx7ny4WRpgi721o5svhjefjHiudtp/aFg4VWso4DoL+Rv5HWs/NJtzSoV7Cjs/uDaZfW1u19WZ8nYFmkikvDpFDHoE+neCM6ELJiokNThjOXhzClj2HHvlxzZ7oWD96pDr8bSvShG/J/adqJ//CeNPBLYrjzcogMBup19KjrPkRxpUR2o0RS26ynHHM5GpReoseD7MEm+1zYVaZwPNUl+jxNMw5a2b8j8ccBa2GHObTeW97tIe94WuzQLe6pcPZnbn8d8vFf31mnT3pZGP74yqVjbB7JNmPjV4NXv8HaTpvpGgEq4Y9v2DwaPPTefY6/mtzgsda9cG3I+m/LWKSIMu8V2T+kSjGuSo47+M/Ir3GDgnLMUJlvwwe/6rOtk31bKCRuXtbn23IVQ9YLzKnn7UbeTKgxxZgNFcoF0WZE/7aybcVzuWr/Ctd4e9Nwc95f2eC50bBe32D66I/lo2eOD6WFZR5/vXRy41jENgGkonkkmcAGXzd1k2Ff40RuLN4sUvH82erF8537RWyFkvF7oeTQQa5qPNuvitkbVjgKVR/9u8r9QA6pTi69q5LyqnDt4Z/rBceKJyvLhJWje12amOd6ujXcpIpyIsmA91zgc75EGA/HxotXJ448GA8+mY9+GI58ag95Jwq5jnLGp3fFdr/KC0Nye/JaOk58u7Q9OL6xioxWCyxtSSHbKm5/LMy8kwjJ54NPR1rfm7VnsBd7O023tn2P9yNtKmi/PNaHm/7Rhbe4QFeNW/yAs2HgOYLEbH6uaPvJj7/LH401sDh+8MvhjduM5TN0vXhJogX+YVqkK9mkiPOgxWhKoIYO+YDzdOuZtnQ/USf7XYVznuuzcauDbgLxO6L3Zs5LbYs4o7c3Kb9xQK/nZrtJQljoPJIjNN3tnsKfmaNzXvIvsV5s8fSE6xVn7g2IuErgqR/7Ek1KiG+ItQpxXN7TAeZRmO1ul+JXjVx1K8R+sZfV01+8WD8Q+vD310RXClcVaoDvHl3rR6teF+faRPF+7RBns0oV5tXKiOdasYc3NkoeaZYMN0sEbsfzrhvzXiu9rvvdTtKe7Y3HdRuDe3IyeP/5ey/kOPZxadPtAAgjDepoid8KZ7DOY8IXTyUuPM4ZfL5xsdRVxHad/W3fFAjTzabkC6zdCAPXFj0AJaqaMNuuOsn4fwm/Xj9cojNfKvKqWf3R/7oFz4wWVBjXirRx/v00U7ZB7enBuA9+kj/YZInz78SrpYrzYKJFSHBcoIRx5umQuzpaAuBx6N+28Ne6/0eUqEW5/dGNuXJ9iXL8gu7vrykbRJpEqkjJvcSX6mmYwOUjoT//YgfPCW+DhrDcRLaefa9WHfk+lQkxbuWkIHLPCEI9FpjJ58OX2EpT3B0vwjL/MUFN9q+ddPpz+9Pbz/ijCrsPVer6VXHwcG7dGEubNb3arggCHer48C3lcC7ODpa/VoogAZlKpWWYQ1E6wS++6PuitE7kt9m1/cnWJ48/gga31+X3KuahRiYpDYUTl6zYtjFN0rM3/1UH6m1VnSYS3rd9+dCr9UxLhGtNeKjtpRiQPpNQSu9RgPszQnG7UMY0qpssuY9SgI2GrZ108kn90ezintzCjm7DpXWze+OqQPDejCXcpAtyowYIi90kL0tSIDC+G/Sx9LIUd5ikjrXKBB6q+U+O5O+q6NeD6pGAb+DJRZKPjw+vChJxOL674kiVI74X1difAERd7qUJ9+aSpoXy3tclYMbT2dCbK1McES1G+Ljzric+vQpNnD17hP1MqON6mPNaqOspWMQE6uU518qThSKztUKf7k1uD+K72ZBZz9BY23+coeQ0SoD3Vrg33awKA+OGQIiQxh0UJUZIBeKyYCveVCGPwLaFAX6dPEQDgLlLF2WbhxNlAzHXg8Gbg94jlwYzC7gJOdx9tbKHj/quibF0r+lIn52GdHc4dXvGQ0QZ6rmv6+fgnk//Lezduj3ur5cJsRFloRkQOaXIPmN1GJPVY1tcq4Llt1lKUAOsZSHAHZuE55vEbxZaX041uDf73Ezyho23ehpWbC2a319xpCPfogkMgYGUlpGNAZIsOG+GtFwZbURnAqQkP6cL8u0quNdaljPEW4RRasmwk+lwQfjPk+vzmUld+2t6AjO5+/r6z3UKXqIXcWAyl6RxWYTs2H6ORaADn6SPJjk7VEsFYx6Ho0HWzQRHmL8KADHXdCsxuoYhMbX4Hq5zbKepdS5VVxkqUEKmmf5srXhoyRF0NLfHWkbsKdWyv9+ia/bxEaNIaHjGGRKSJajAwbI6OmKNDIK/DYa0XeFrD+AJPBot3aGF8V5ipCTfJw7Uz4mTjwxS1RVn57dj4vO78j50LHl5Wa4urxGEZQoAK/e4uV4qXobZ3Nf/SZMr/dXiZcuzmy9Wwu3GKAOpeQkVV0whmfXYNnHMiUHe7UrPN1Wyfr5GAKcJqlAsueBZfejajt8KwVmTAD54z0mRKHrrQNGOFhYwhodDGcUnRsMQZ4wfI3NGIMD4IoNkR69NEuUMKUobb5MEsWqZIEi9tM2QWvePcXtx+s1P7wbNwdQ0maenfeZOoSF/AJkcp5tEpfyF0t7924N+6ulofaTZBwBRldRaXriMqNz9ghg49WrsWMPuwiR3WKbTjONpxlzc5uIvPOuNQaGwcDBuYDbmmCiytFAplrdDE4Zg6PL0bHF+NviMbN8d/QsCk6ZIwOLkT7DFGhNixQhdoVIbY8VDMTvC1y7S/hZxVyMwt4WcXcQ09kxx6NLXtjzAd6784Lug2m86b50pWTdeYiHsP7aNJTpwxzl6CB1cTkOibfxJSuhM5Dmvyk0Y1YguTz0eXj9YbDdabCFsXMalxiCY4s+EcWY8PG+MhCfMwEg6gUGaIgQY2Z46/0z0gnlqDxJWjYDA2Z4oNGJoH36qKd6ghHGWqcD9bMBR5NBT6u6AWkGYW8PUX8bx9JDj8Wq9f8NIX9Dt7WicXTDcslnZs3hjxPJX6WJiawICInJtkgFC5c78YNHszowXQuZDFAVg7oz9Qoj77QfV8jF5ljQo2Hr/R1qMJdqjCA5U2v1/Tqq4R6kREdWURGgdXMjD+/C+/IEjxshkVM7Mf69SBRRztUkVZFuE4WeiIJHbgjyihs31PAzSjqPPRY+u3zmbmVLTpl33dETn38xfA2jxnPsKyl3Vugn6mUBhu1ULclMeLAZjdItYswunGzl+FVbcA6LyFzwZfbVUceSz6r6K+dWudroo1zwQ+KmksbZiaXUIAMJJC5L9WOvhxeGlqEh5fhdPwCKIYrTffW8tX2JWh0GRlZQgAysPKQId6njnWqohxllCULP5WGizhmwJtRwMss6v7yqezbeqXM7mWuML4zb6rfAAmObhpdONNoLetx3x7xP58JNeuQHmtibJWQbVJaF7nowZf92IIHkzshxSYq24iO2RMlzaqPSnkflTR9favnwDUhmLw0Sn09Kj8oryMmaMyMCPWBoSWoYdJxtIJTJzKBcpNGfsM4uQy/gU3zjlvQFDKwMiRagAa0YCYV46libDnD+3AydLpWvSufm1UsPPRCeazFNGf30+QOeKnUR5GgD22eMJ1sXr7U5741yvC2aOEeKzqxTsjclNaNGz3Eoo/QuzH5GiJfT8w4oQkrMAFSPeS41WX8tLw7K5//9Y1+riLIU/g71SEwCRo0gv4wPAYy/GJ8wBACaKDc/IxRbEHePAXrzFMLMrEMM4YG2cAEOrF4tz7O1cYalaHns+HbI4FLXVuf3Jncd7X/LM9xrGl5zhZI874LbJqXSl2aF8xaTjcvlfZ5bo74QPw2ayHQaQBeuZvSe8lFHyPlWlzmhOeciMQWF5nCQk2YNx/iznvZUt/hO8P7C1o+usD58nJ3o8QHUuvQQki8FAOSWEBCi0+mSIGmrChQmu5tvdmePgNMbVqMDy5AQgPE08WaVBHAe2PIW8RbqxgOnWk15wldx5uX5h3B9GW1d/dnxrwkMaJbP8VeKOndujXi/zvvBgnsq2OMS5p8hNwRnVuFpA7gkMB2QYHCy5v38RRbAqWvUxWvntj8oqL3L4UdDZKgUBsZMgQmzdGp5fjUcmzaCr+xZnqZXkkz/qPSyKNv8abte7XPdabeVD4UONNuye3ZPNygW/IhyVR+fldeZvZLgumRcjV4vE5zQei6AaZFEn9Tinf8FS8OYPVbqGw1OmOPTVqYLkio8nbIt3gKL0fj71B6u+WeLqWvWrz5fklrsyLcBfwZFKNldMgUe9qtfjlkrO7XTabsyDRai7G0KafSsqbBmRUxIzTt0m/sy2V4w1Wy6KVO5/csM7DvuU7nOeHmiWbDJoyDKcM/8qY/xvsFpfoNmiCdfvRMg6a4a+PqwNbDqWCdCuaBnLNOzm4ROh++ECBkzti0LTZhZbrEbq23Q+HmyX0d8yBgfTylp0PhEYAzoAo+EBrLWNNs8Ub9mG14CTl8q29vfmtOPicnr/nTy52Hbg58WMLLezE9sohOW9GZpejMYlhihSYs0KQVKDppRSZX0HELPLYMDS/G+43RLkO8XRtnq2JV8/AF3noxd/32mOfq0NpZoS+/WRPFQSyS9Ks7D9LmY/QbvHTqulgkQRe1qotA8zzkuTfhr5JHuSZItIrNunCNFwO88nVIbI2MmEEbEOCrPLx5IC/g5Su9fJW7U+0F6lIHBMogW+ysaJ7hyl3fXOVk/cjOLuRn5XKz8tqZ7hdMcJipE+/zMgFX4RfbiYllbHwZTZkVmliJTawgk7bEuBUZs4AUHe83pXh1EFsdfy6D8lttV3o89ya9FWNbZ7u3HvQaEaYZpt8m+me8gHWbougEST3u1xXw7NeG3HfHfc/nwhxjfNCOSjcxtRs1+HHVVgLwDhlD3WovVw7k4cjcgBpMWsHwmBEuQyJTdMAQ7tUGhGrf8BJ0+vFwVkF7ZgE/pwA0vZw0795CblZ+x95C/v6LbQeuCT6/JrzTaZyyEWJLPH2cCWDft3kX4hw9zFLFn83GcltNt0f9j6WRkhH397yVTrkjQRDM9VqAQL8TL0UnMTrJ3CJF4D1KW26bpbzfdXvU81QabNGF+1fg6Y0E4NX7Ma0Xn7CEe7RegcLdPudvnwM+7O3W+cctcbEVltgQ4JBTNmTKBk9a4xOWmNiBHn00sqegI6uoc18Bb28+Jw2bU8QDFgfKLGrNKGzNLOrYV9gqkLtBZhuzgilY4o19R0BDuxjrWoA4OrhBGQP2vT/puzfpezITO9e/caJJq1sPkxTGePRPeRmnpX5ZFJUEE+bUTQPUWhg583L+Qo/7zqjv6VSgQR3uAnlyHZt3Y8CltR5CsUkINd72WVf7jI8z6wVpGQwPRLRkBQaatiHM0goqTnx8BX7Up9/L9ELc7MKOnALuXqBCbpo3pxDM2XnZRe1ZhZysQl5OQdvzQcuQMTZhJ8fsyKQDm1hJjC7FRWaozwQJDHCbFq6djwGzPpj0P5kJP5wJne51FbfKoiRzNw9zJxsD8poozf6rvMx/SebWL8alr3do8ru2boi8TyYD1YpIO+hjHQmpi1C4cfUWIVsnRpdhhlfq5s56utWBSRs+bU9IVkBqBbzo9AoqtaDi5XjTtDOnoDYzr+2NTX9N4L/7izo+uMg9VNH5+ZW2+/2G63z1Lb6h1wj3L8K9RpSvR1o0SI2c4X0yFapTYzfFvpPdm43iJSSZTDADJ36GwxD9ul7tAAxNJUXatTzO0pX+zQfjvkpZmK2PC61gikTMuci5TVyyigJn619gPnzr00fGAJodn1pBGNLXktqYynJfqMsuYIGA/UXYtKHTygaTu8KuzIKOvWB7MSerqC0bvKQAtKm86ok1oQlp18UbNTAoRs+kkaqZMHuBKO5fO8NZUrtiKPBMMGoa+xkOw5Lc/kURr3mZ3UjaH8cKW9Wlfet3xn0PZ8I1yhjHiAzZ8Ik1YsKZGLfD4ysgi8LjVgy0uBM2FAQpiFyAKUlRS+zotCMxZcMvt8oyC5rfQP0jbzpRM8rn7CsQ7C0QZBUKMouAQLwLQDbbm99YI1kXmOA2PVSvij+fi1RJw006uEYN/di9XtGlj4DQTVIJ5gNK6u9Eb3i3t39ZyVenhbmHFRyBwJrlzjyB9fqw+8F0+MlMqFYe7DQhAyuJARssWoFGLbFxJpEmutUe0EJPOdBpkMPtibRxp8AZAAFow+52G/YVtgCuzLz27ELg0pyct6jf5gV57H0GGSRwHjORZ+KayWCnnw52LcY7jBBLE62aDz+dDTfMQ3wzcnNi63ynY2YlmCCwRJKAkttY8ic4wILEb/BuvzozCRC/NJ2gyI0Yks9bKO1zP5jwPZaG7o+7GrUodxHjL8aFoPNfjIMQBiVDbEtI7fiMDZ+xYzOOV5p2YBInNrUKlLhQM5iT15a6u4ybxdi6/ZdDuPC1wHko4mXmM8b9pJQr0Ee6TfEWA1SjgZ7JI0Bti4mu5Whxn/veyHIIGCaZTCk1/n/A+S3elBhYRiAeEr2atbwO+/Wx0IOp0JVe+8MJT+18pBX0dYa40BQXWZCxFRQ48zTgtRM/5wWwjgSw8pAp/EEB6DE69uQLsvJ/wat/Ia6LeFkFguzclhqxS7iY4C3EWdrYC2X8mSzEVkd7rFjTMl7c7dBsxRGKmeQD3l/DwVI4KEW95voFoUzkA148ksBudi9c7N26PRl9NB1/JIleG1i7KVpja2KdZrR3GRqyQKM2BnmKsfLfeYFmV/E3etqzsC+/eU9+B2g5sgu4aU/+zdwFPIG3P5/dvQB3GNEmPfxSFXuujNWqol1LKJiP14DaNLceJ3CUIn+b5V14E6ATJcgInURw1LARym9fvCoK3RVDj6VIpSzxcDryaMrTvgAJzPHepSiDvML0QpJ0WrYn0rxzq3hasw5syg4de9Cdkd+cWfSq2WCoX3vvG16QxplMXsDNyGvLKuTm1Yj7TVCbAa7TIlXKWJUa4iwTQgvWvIA8k6x4I2iCJJF/xosyl8NomKaQJP1rQpk9KSiZBEcDe7YpNwv5S9dA/zYdrZyJvJiP16mhRi3UvoDwzVDPEjyc6u3FoM2wI1I7OgvkSKQty/CuJqadcYkTeTlhPVDB3/NjW1Zex17QWxYCdbyVtUCT2ZqdL8jO68r4kfPXi81sRYBrQlj6WK0mXqeMcM1olw1tN0efz7nmN4IAFvghAgRY6F9nSS2hFMi7COwcxInqMXNx7+atqfizmUilLFaliNWp4k06hGOEBItI/zI6bE2M2ZAJOyJxMI4tdWDSVRxoxklImcQFzazGmfmyDfnwoiA7H5B2psR/mxdkb2Dc7IKWv93gPxyzcYwoWwdgw/VqP28Z6VqluRbqpdwzZFoPkRRKEjAJDMfg/Nb4U8sd8ZJYfCOGXe+3lvZv3ZsKPZbFniugGhXUoEWa9QhnAeUvJoTL2KANHbEnxuzYJOg9Uvl52olPrwERIFHPOeLy1eisE/7gAhfwgjoLeJlrIgXM9CHVgIFWk3fghvDRpL3DGms1wc0LMKhBLHWEtxTrWkW4KyRLFePMbwYwHMITKIm/O+9v+/PPBOPg+NRKCK0QGK6KPHenw0/n4WoVApDZGpBMEi0LiTZzonMZ6lsBPUlixI6NO7BJJyZew4Gm1gjJKiG1w1In0msOZOW2/CNv6voI5/2Lne0mmGOG20xQkwlmGeJsbVSwTPTYca4FZmtDHJndBZMxioxTjA+jZMqZf3vwFAWRjGCKfkdFqSRM0DBGWYL4nR7zlcGt29O+p/L4SwVRr0RZGogFOj0D1g5aegsiXMH6bMSgnRDZiL5ldMCS6F9CRUtIp8YnWIjeF9mywPzo57xtOUXAmdsucY0cM9FogOu1SL0ObluIdi9BQgfVvkI2aP0dSvsWQsA4CcYTo5IQlUSAff8ZCEQmgWI4FSfod1f6JTGcXI9j1aPWK12btyeRJ/NQjQKq08SAWDqsZQFpWwTWQXnLGM+MVU64noyuPR1bfzq6XjnqqJxwVE5uHnsszs7veIuXKU/Zhe37L3DuDq81L+BsfaJBB7H0oINC++xEjw3jLCN1Gl+PccOD4nGciOHJOL6zkb8e/A6Ufi1YAb4dQnD+rOtyz+pVceiZLAK8+qUartdhbD3aqIebFtAaRejmoO32gJPRoPPOoPOuyHlv2PFgdOPAjcGsPB6ATSPvLRRkFwk+vNKX37xQ3uNoMGBsA9JuigltyKgd6naQLctEnWx9yuoO4GQcA7xklEhGdzLyNO+OjPu24EQSQYggHpc4/LeEjqtDq/cloWdyuEoN12qQOi1ar0vcHFm7IDCXdFrLhLbLQvuV3tWyHueVXttFvplpnPIY+wJl5oImufNktfZCh6OQs3yBv9xiRAQreK+T6FtFuyzxNr2/Ydqy4IOieBLUWhgjwfij4LTvzDPTK8BkVCz12h0pAvoQYO4E8zHXGoyxVO5rfau3Rv33wZxiLvZ8Hq5RIbVq+MGU7/qIu0hgK+SvFHWu5gucBQLrV0/E2cUdWYA0v2P/ReGJ58rz7KVCjqOI57jU7bwzttVnR3tXcb4NbTJFa5Te0RWfDyWiGAVj4DzTMSwJBhDd4bAhggnDdDBGCDpMJnekUEqvngJ8klr0o01zrtvDm/ck8Scy5Lk8Bvy5Whl9LIfOcZfPclbO8RznufY8nv3zB+KMQk5mEffjG0Pn2xZ/5FmKu53lg1sVI75bk6HbU36OFWs1RWvla91LwZVwIoAnQ8R2mNiOpDDTihDUzsaM0EEIKAnkQ0gvSvx+Ibg/Ed9EYUeC0AThVp3n8bTrqSxSraNeqMlrI76z3OXveJbv+JZzvOXvWw37rnbuv9Jx8N5Yac9axbCnYtRTLvaUSrZKRzauDbsfScI1Mt+AObAawcIw6oVwD0x6EcqL0D6E9iPJtMD6jgYZQJNeQAoz8sI0ONrvFwyGwQzGDdNbMO1CCQdMzG9EeYr1F1OuAr71xy7bjwObucPe/GH/xbHgCY75W5amsN9zURQsGfIW969d6Fu/1GN7OGHtNG2ovFF3jPAjlC8NBVNv3sgDAyXfaEeDDGC0DwVKvtb27xeSDKFJ5gQmkp5EMpigAhjlSZAujF5FKXOMEDvDbPnanSHrlR7LtV7LzX7r7QHLjT7rw1Fn/Zy7xxKZ24KtMcKVoH0JCsxkQ8yS9ieAqLcH6UVp8BavtMMxR3A6iNEhLPk7lUiGE/QbgUMFcTIERJA+nPZg9CZMOcKY2Y/J1qISe3hyJSK2Q5JVeGYdnbRFJ6zh6VVkbh2fdkBSR2zaHpKthhfc6EqAWI9SANxPgJhl2IMoCd4rgm5Hke0wCt70lUJpvfOAmRyLUYD69ymKpfJkSmA9ihNhgvJhtBujVyIJkxcyemCzjzD6KbWHnF2DgQDXLOicVyPDCxsiw8aYyTu3Cs9vJJSbmMKFK9yEfAOWr0c1LmjRj9gj2AZM+PBkEEtGsO1YYjuOMssY9kpRZvsOBhx/lZ/JdEnascARcPC+oMlJi9yKocs+2OBGF3y4yU8ALQYIc4haDJKqjbhiLTrvjKjWYipnTG4PTS5sThg2Jxe2pEt+lRPSbCZULlS9hWjckMYDLUVoa5S2RciVYGIzTgBkUHljzDsm3xJ4uoMBowSF4CQQmlrfqWCmom3D5DZEJMMoafcjS1uxJS+6HMCtIXoFKExYQ+hSADG6oQV3nNFW3OSCgfRr0VnT5pzZM2f2zpo888t+tSW04IgvumCwz4IbsoZIZ5TeiCc3YuRqGHcEUA+MRUkqTr5qCxkRNLKTAeOpb5inRO1YBJUgaZTaBk2sK4xa3TGrH7MFidUwuRah1iP0epRej4CniNUbW/ZAVh+y4kdtAdTmTwA5goTBGdSs+DQ2P5Da6tNafSZ7yLwWtbihZXfcHsTWo+RmlACZ340kt2BwTHgjEgtheLr5BxMioB2Nmfn+8GsRqa9T70g4cJIE4YmiYFRrMcoVJdxx0gMxtckH0X4gmA6A8hEHfk64ojjYIb1Pajdq1Q8tbwYtrtAbWbfC6eVGOLEVY/ZhyhxI+6ls70+AKo/50UQ4gSKMjXY2WoK5Kzr5RhS9A6UvtcAoHoHQMIyHEkySByk6yiQuJtDiIKgTSQgDAt6+nQo9RmAlgqUEahZMboVgVwhyBVMKQVthmFEIdodhXwyLpvZnXptuX8EEAfSBOB7BMQjHsdT3b3ak5Otbuxm9vjT8jgKnK8FMkWgghNxGyGTiLWFEEgcikwS1jf9U6d+hAALhAKE4UAzBGMFYeiWe2gKWKEEnfnpYIGbOTlMo45/0jgbMXCX8Oe87KPXDAamVbZL55YhtIpkkX3+3/e87vPkxjfTR31yBpV9/2z/1dTBgIrBCkCQjgvm2J1gC4QSz5c3vFLwtHJyobeb3O0j6ncf8Wm/f25B8twf91nfWkm8d6tce73K7yD994U8G8A5v+muP/wdeG4eiCmVuZHN0cmVhbQplbmRvYmoKMTkgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyOTA+PnN0cmVhbQp4nF1R22qEMBB9z1fM4/Zh0fWydkGExbLgQy/U9gM0Gd1AjSHGB/++MeNaaCDCmTmXOBOU1UulpIXgw4y8RgudVMLgNM6GI7TYS8VOEQjJ7Yb8lw+NZoET18tkcahUN7I8Bwg+XXeyZoHDVYwtPrHg3Qg0UvVw+C5rh+tZ6x8cUFkIWVGAwM45vTb6rRkQAi87VsL1pV2OTvPH+Fo0QuTxiV7DR4GTbjiaRvXI8tCdAvKbOwVDJf71E1K1Hb83ZmVHpWOHYXIpPLoRKj2Krx6lmUcJMc8X77s5pA+/PT46e1qUkVNM2uyR4i0SKlJYGlORMtOUiuSSRVR8piLJs3R7AWWuP7kuY58gn41xw/Mb81Nb5yUV7kvVo15V6/0FL+SViQplbmRzdHJlYW0KZW5kb2JqCjIxIDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzAwPj5zdHJlYW0KeJxdkc9qwzAMxu9+Ch27Q0mTNskKIdA2BHLYH5b1AVJb6QyLYxz3kLefI3UdzGDDD+mzpE/Rqakaoz1E726ULXrotVEOp/HmJMIFr9qIOAGlpb8TvXLorIiCuJ0nj0Nj+lEUBUD0EaKTdzOsDmq84JOI3pxCp80VVudTG7i9WfuNAxoPG1GWoLAPP7109rUbECKSrRsV4trP66D5y/icLUJCHHM3clQ42U6i68wVRbEJp4SiDqcUaNS/eJiEZJdefnWO0nchPbxxuVByJEo3RNucKWc6EWWcuUuZtkx7ppQojZn2TBVTTZRxvZwrZFwhT5gOTDuifU2UVDTIveP4t//HvOkzN8mdZ8d7NscXB5ZNPeyVN+eCs7ROsnQxUxt8bNyOdlEt9wcECpr2CmVuZHN0cmVhbQplbmRvYmoKMjMgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAzNjI+PnN0cmVhbQp4nF2Sy26DMBBF93yFl+kiAgMGIiGklDQSiz5U2g8geEiRirEMWfD3Nb40lYoE6IzncS+MX1anSvUz89/M2NY0s65X0tA03kxL7ELXXnk8ZLJv543csx0a7fm2uF6mmYZKdaOX54z57/Z0ms3Cdkc5XujB81+NJNOrK9t9lrXl+qb1Nw2kZhZ4RcEkdbbTc6NfmoGY78r2lbTn/bzsbc1fxseiiYWOOdS0o6RJNy2ZRl3JywN7FSw/26vwSMl/5zxC2aVrvxrj0k82PQjiqHB0BsWOeAJKQE+go6Pw0ZEIHEWlo4Q7ilMQusQHkHAkMC85O7IpK6XokgYgzMugJcK8A+aFsLXpP/y6ubvnmUvjmBln0MpRGyJ4QnBrj5kC/mPoiQVEhgjCuECXBOoEJgjISkrY2YxDRIry5IggMlN8lBRa0givbHMFH+t/W/frvhTtzRi7D24J3SKsK9Aruu+pHvVatd4/cF2+1AplbmRzdHJlYW0KZW5kb2JqCjI3IDAgb2JqCjw8L0xlbmd0aDEgMTQ5NDgvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA4NDEyPj5zdHJlYW0KeJzFewt8VMX1/5n73t27m7ubze6GANllIYkGTEgIAUS5kGwSiIEQwGyQmAQICRYwvCRWVKr0D40K9vEDa221Dx+1v9Zly0+CVdD6AB/4xGdbpS0CVWLVYkuR7P2dM7uLidp/09/j87t35ztnHvfMzDlnZs5MABgAZCJIUFxdGakSlgkLAQQdcy+prp8zD7LADsCmYlqvnrdgxoqedV/HdBTTgTnzikqm3/btGqxP6UsvrayLXnnLBgnAeRuAfGTJyrYu4W2xE8tjWL5iyVXrgteqM+4DULoxr2tZV8fKma+/8y3sAKYVe0fb2i7wgw35I08wOlZcvezE5r+MAgi9iM19q3Ppyu5XHj+dAZC9GUC7pLO9bek7b5z/Y6x/GOtP7MSMjOuUTzBN7Y3uXLmuu+529WfYFwPzOldcuaTtuvarJwKIw7H8wZVt3V3ifuFpLOvCdHBV28p2X7TEg+XIj03punLtukQCrkf6VirvWtPedd64Ph+2fQIF9nMg2dn5S48IGghgALMspJNlPnzZirZ1q7As+VD+QqgDFWpB5vWLYAFK40OW/EpMVkt8Su1+yYPfqzcmJmMf/mTVW93afZzjwGchz5EB8q9//OKWjKmfQE6y8Z+37cmm+NlLzsu26vuPa/epN/Fess94g56ihdSoGORBPuJYfBn2tQhxCr4MqmEm4iX4MpgD8xAXwKWIUWhCZOIPUWoyaPLtcimyGZOMxbvgesGjCYJDEQV6pFS75566ecEgmFABV8nHEototOxAEODOARIQUz2VoBVjL8pQRLoS+3MJNMIyWA5dsBauQj0A8knmLsXcFbAG1luW9cfPv1+QYfop+J97GWOPpV9hLH9v/LJXXPCPXsmQa+SH6VVm8vdR9Tltpa3MTs9GRwjf/fpM3m8VrQClJOFcwpFvTNEMAphK0gK4UFtJWkQdF6doaUAdGYah/SZpBSmA+SjBdlgM62EJdCK1Di15HvJpx/y1KOErYRUEoQwuQH7F0Ialy7HmGsxfi2EZ1g9+CY8GxA5Mr8Av1nxJeZC38lOMSzjfiTzni5wrkFqDuidsw5xkfy7AkunIewXGDZjXgVzX4VdB3u5a3verEJdiTRw+bPoHtvB/+khPQ710AnZ8Pl+YAnvP1XF+sfwfPcpL4PyX+7AeaqVmmC58gvJMt18D9efoRbBD+QlskVow1MJ0rL+F8nG13SFelPwGy64V3wddPoZL1F7IxuCVinAOg3Ucw0kKNOvlx3ENnI/fTkL6FeQ9D+ODqTXpf/I5CIfw3QG78U0++zDvINwMd8H3UvJM5gDcjy89S+FauAFr7MA6afp78PLAfKGYTWQB9hP2GlQJATaW/RoXrtfgfXifvcSuZ/NZJouwTjYWbhHKWJM4TZaR3g2r8KvL2XPsOekNtNxV+MXL0MJOYVm38CK7VbweNgmbsIT6enfiRzgf9mJ7/+1Hg3+mj/RD+qCH9PG/8vwv6cO0z99/NzPvdmdV/aSX6fGS3B/2siwznpt75YHxoVUYVmJYgeErGK7AsBxDJ4YODMswtGNYimEJhsUY2jC0YmjBcDmGZgyLMFyGYSGGJgxRDI0YLsWwAMN8DPMwNGCYi6EewxwMszHUYbgEQy2GWRhmYqjBUI2hCkMEQyWGXlYev1LDaGJ8FUVl8ZUUTYivoKg0/hWKSuJXUDQ+vpyi4ngnRUXxDoouiC+jaFy8naKx8aUUFcaXUHR+fDFF58XbKCqIt1KUH2+hKC9+OUVj4s0UjY4voigcv4yiUfGFFIXiTRQF41GKcuONFI2MX0rRiPgCiobH51OUE59H0bB4A0XZ8bkUBeL1FPnjcyjyxWdTlBWvo8gbv4SizHgtRZ74LIrc8ZkUGfEaijLi1RS54lUUOeMRinTTqtRCyxvH50YxXIphbsP43KrK8bkRDHNmj8+twxDcWbzT3Fm/UyreyjJuZts337n5gc37N7+wWd7eeWfnA51i6/Ku5cL2y9j2hayrkW2vv7P+gfr99S/Uy9vn3jn3gbni9oY7Gx5oEKdtnLNRqL+m9Zqua8Su2axrOyve3rq9a7sI2xj+zG1d2wTYVrzN3Fa/rRUTitFldgmt61jrWtZVyaCgAM3Z49bM8oxpz/tYxo9yfyQEUOleDC4MTgw6BgcGOwYbBg2DikHBIGOQMIgYBAwMg7kREI8EtNBvvVroNZcWetWphQ7rWugVhxZ62a6FXrJpoRc1LfSCqoWeV7TQIVkLPSdpoWdFLfSMoIWeZlroIGihsCsySo+E7JGgFslVIiOlyAghMhwiw7SA5tO8mkczNJema3ZN0xRN0gQNtNpe1WqojWn1l0V3MbatKeaphdr5M/YCY9bXbyn8Lz5rZ7ARtbGcedHYjhFNtbESJGDELh/MaKoNYioc2zF3YTRWPKKpkEWWz5vBauujuzQsrViUjH1G18W7yssjy4MxmB+Nma1NlbuKoeuX5F9kdwW61vJn3bq1n3/+qx3+F551hcl1D31oetDPPa1ZuETbrX48Gzmss7gLEjpAR9TBaX2Ke7kLaRfHDDAQDXBjvhvxDHjAg3QmZCJ6wYs5WZCF6OPoBx9iAPyI2ZBt/R29vmGIOTAccTiMQByBeBpGwkjEXMhFDEIQMQQh628wCvGvEIZRSI+GMOIYGI05eZBnfYKnhzykCyAf8TzET+B8OA+xEM63TuGpohBxHIxDvIBjEVxg/YX8PMTxMB6xBEoQSxE/hglQan2EHuYEpCdCGWI5TESchPghTIZyxCmIH8GFMAVxKlxo/Rku4ngxXISl0+BipE0wEafDdOsDmMGxAmYgVnKMQIXVB1VQhVjNsQaqEWdynAU1uDPWwizrfTxbzEK6DmoRZyO+j2ehS6z30Cuag/RcmIvYAA3Wn9CDJZwP8xAXIL6HfvMCpBvhUusEnpoIm6ARcSHHy6AJ9+BFcBliM8fLYRFiC8dWaLaOoZfbgrgYWq130RtejPRSxHfRm11iHUWvuB2xA5ZhTid0IKL3i6edK6AT8SuwHHEFXIF1VsJXrD+gX0F4JaxA7IJVWLoa8Q/kU1u/R095NeI6WIO4HtYiXgXrrCOwAU9aR6Ab8R24GjYgfpXjNXA14kb4qvU27sPXIF4HGzHnesS30cu+1vodfA2uQ7yB442wCXEz4m/h63AD4v+DzYhb4OuYvxW2WL+Bb3Dsga2IN8E3rLdwdye8BXoQt8FNiNvhZutNuBW2If1NxDfhW7Ad8dtwq/UGfAe+ifhvHHfAtxF3wnes1+E2jt+FndZrcDvi6+hBfBfpO+B2xO9z/AHcgXgn4qvoaXwf8YfwA8QfIb4CP4Y7rcPwE7gL8W74IeI98GPMv5fjfXA34k/hHsT74V7rZfgZ/NR6Cf4d8WX4OdyP+AvEl+AB+HfEGPwCcRfHODxgvQi/5LgbdlkvwH9wfBDiiHvgl4i9iM+jN7jbOgQPwYNI/wp6ER+GvYiPwEPWc+g3/QpL98PDiI/CI4iPwT7rWfg1x8dhP9Z5guOT8BjmPAWPW8/AAcRn0d96AumnOT4DT1lPA+YhPsfxEDyN+DzHF+BZ6yC8CM8jvsTxZXgB8RXEA3AYXrSeglcRDwB6t4ivwyuY8wbik/AmHEZ8C/Ep+A28jvRv4Q3rCfgdvIn4NryFOe8gPgFH4DfW4/B7eBvxDxz/CO8gHuX4Lhyxfg3H4I+IxzmegKOIf0J8DN6DdxHfh2PWo3ASjiPdBycQP0DcD3+G9xA/hJNY+hH0IX4MH1j74C/wZ8RT8CHiJ4j74a/wkfUI/A3+gnia49/hFOIZjp/CX62H4SycRuznmIC/I1qIvzInzq8NzZpZU10VqayYMd2cdvFFUy+cMnlS+cSyogvGjS3IGzM6PCo34HUbGU6H3aapiiyJAoOxkXBVazCW1xqT8sI1NeMoHW7DjLYBGa2xIGZVDa4TC7byasHBNU2suexzNc1kTfNcTWYEp8LUcWODkXAwdqgyHOxlC+dGkb6lMtwUjPVxuo7TUh5PODERCuEXwUigszIYY63BSKzqqs6eSGsl8tvlsFeEK9rt48bCLrsDSQdSsYJw1y5WcDHjhFAQmbJLAM1JzcbEMZG2pbH6udFIZU4o1MTzoILziikVMZXzCi6nPsNNwV1jH+25udeAxa2F+tLw0rZF0ZjYhh/1iJGeni0xd2HsvHBl7LyvHg3gkNtjY8OVkVhhGJnVNpxrgMXkMUY42PMJYOfDfScH57SlcpQxxidAJA3xnJiwPE0D9g17iOMLhagvN/WasBgTsU1zo8l0EBbnxMEsKmyKCa1U8mi6JGsBlWxKl5z7vDUcIlVFWlO/qzoDsU2Lg+PGovT5bwz+sDwYE/NaFy/ppLitvSdcWZmUG3k8lUiYbamxRnYVF2H9tlYcxHISw9xorCjcFfOGZyQrYEaQdLB8XpR/kvos5q2IQeuS1Fexokgl9SsY6WmtTHaQeIXnRvfipn1k14Rgzi9LcQNvon7EfBWolLxIT3Tpslhua85StM9lwWhOKGY2ofiawtH2JtJS2IiddwSbC/EW+Vc4ts/VTlemkatjtGBUyBGbSFuYEaxCCM+YigUGqosnSaMzpgajLAfS1bCVVA2iBvHBhDimooaKRPq0oiYn1BRKPv+fLuWk+iSPiWkDeBmYca5PyXb+YdeStalD5wUj7ZUDOjiIqZzqYIrbl/dTIFmkGsYvNFJnTbpIHIMzF/MEZMOzSIsBdI7rg9Fwe7gpjDZk1kdpbCRrrt/aeeFa9LK5tlNzskcL187rodzwpGQWBHtmxgDNycSJM8kzIZlbhStPT09VOFjV09rT1mttWhwOGuGeXbW1PV2RVmo2iiLstR66KSdWdXNTzGjtZFOIf3jm0p7wvOjUHG6U9ecma0yomB9NdWhSykB5Aa4gM3aF2da5u0y2dd7C6F4DILh1fjQuMKGidUbTrtFYFt0bBDB5rkC5lEmJICWgluGqEBc0Xj9nrwmwiZdKPIOnl/Qy4HlaOo/Bkl4hmWek8wTMk5J5Js+jZxz39f0YFtk0eUhXJLJCKPA7/vSjDaogi/TnCBA0WZZBljDDbhsab4XzFgfxtg2qgOzSvJUkb4ddGRJvVSXEzwdUH3Shpyhp3gr2A7uuKPq/xFv8x7xVNclbtKlYF3mrslNXh8Rb01L9HlBdH1hBVWVeLjo4bwUzXEPlbfsnvDUtzRsP1cRbUzOcGgzlsaV5D6g+6NIXT+lJ3k7irRBvI2NovO32L/LOGNy4wo1IcmrYD+Jtc2fYYChPkrc8yPC+lLfssiFvVcMMzxB5Oxz/hLfdrqZ427EfqE67LdMY2rWzQ0/xHlDdGFQhxVsx7HYH9dtu87qHxlvnvJVBvN2DeDtUXq64HThGVKfDkZXpGBJvpzPFe0D1zEGNO7Qkb8OBY0SROxy+ofJ2/TPeeoq3R9c5b93h9+owlMeV5j2gundQ404bn1hqpjPJ2+kIDJU3Nwp1CLy9TpSfzQ5OPcfvGhJvgysOhz2gun9ghYwMOy/XfBnYD1RnhnNEdgYM5XF7UrwHVM8e1Ljh4OW2gGEYZLKGK5hjwFCeTC4A2yCjzhlYwePWebktx4390J3gNkLD3TCUx5vmPaD68EG8PUne9hyPx0Mm6zHGBDNhKI+PC9c+yPCCAytkeV3cQB25Xm8Wqd7rOX901pB4Zw8jxK4NqD56YAW/3+Dletjv95Pq/VkX5PthKM9wLgDnIOPIH1hhWLabl7vysrEfnkzI9qNbsIldLm6SLsfNToU80yffIX5fukNFJuW0/6l3MEwCFPX397GilmaMxhdnukPuMSF3aJMI/ZsEPKciCzyzIomOTL11XLpafhmyWIsZP57FcOFiYqPKhOsM9lUHy1KYuBVug/ugFw7iMf4ENqvqfj1fL9cl0IO6rtTqfiXi1g1DqHUrGRmIQYcD0dB1RI/Tiai7XEqtO0C1KQfRV45Hd0HYhq11Z7ANXia025hdXCheIYrnZ0zJEESHvpPdy/awA+x1dpwpwI7rjGkQgK0gUhe26DjgXutFM8PtVmrBq5sU6y6x1zqxm9pD4uPdhsGJE7szMjjx4W7qKOWYY6iz4kyvLUBlhEKtbabL5jXoI0Kh1ivCtMLCaX2FhUYfv781DtGvpbm5pbmkpdldilQzT7U0M+O19C1vH5ItzU81J0vHF/NiNS88SnB7PaUl5X4lFMT5A6ES6aKK1ucf+9OfH3n+ylW/SHyQ+H3iQTxq+v8s3/izqsTuxJkziae/9d2fsx+weayGxckx3IHb7m3y4zjNPazMHOs1Sc4BJ4tCN5ZqGVszhIxIp9qtCqTGLSorUJnqzcwUatVe6z0+fCQ+NB2kJdVOX/O0nzSl6qQjVSD5pehe65SZQTpT7ZUq87N8JjISKAkJiZO7iTUSpzhrJM6YDhIlk6gBTCd2E2ckPuBqQeIs1UBKpQYw/alZQg2wzIDRaXQbYqNzg1OABXq7vl4XF7qZmC8zIUtndr2GCTZ3jcQ0SYBp04y+klIMXPr0G6CBwsLm/sOf0VTax1XRzApDIffoUpI/c/tKSzy4jo1ijyTeZMPmsFK27OxTFUte/jAxbri81564KfHM2ROy/OleO7uQBQQNZ8xenDZfk/fidNu3F2TrUbOIy1ZmBTITKwNQAJOgBqLQCUonqoRmj6Ti9MHpVkAyQ5s9zGWGxFEuMyTeS8oMuMyAhEl6QeID00HSgyCJjqfdJDpgJDoYTmLD3CO7+RzotZ43Heg/1UK1BBojETHjr4P+/tDSvHpNXzPKgRWWukvdew/Ke89U46jQqsRTOCoZvmn6NCkgCQelN6QT0mlJArESpGoVktbDmzmZHsCp9ADOfG4ASaXzGqmen0oqHUTec0o7ee+rFbEm1dk+Zhz7rKvGMaMPuzu+mDoaytpxUNiBnf10N/bWaZ1UnsDe6qx9l0CnQ3O4ahdEWWI2yebAg5os6A67rKh2VRBcTrdnctGhQ8bv6IfN4OP2+CePL87Zpfw3PjYnVgsMakRWjb0vcNW4ul1bXQddMv2bKxwS65bYBmA1WIi+JlNVUVKqZEeV3mudNhfb7UqtJuMMKNer9Q26NEmukbtlUe8GuVvSu9l6ENdL1RJDPnCDTbpBEwTbeuSlavlaudao3YsnB61T6BYENhN7Yd8GwnZN3SYBjkHnY0j21eijl68/RTQHJmcXBSinuZmQCvtxjcIFqw/HmV1Eg6VFi08pWreaoaW5qUkOMxbGycF/0tlpiR8nHpqWKHmR5bEZVexiVviiV/z4rEs+dJaJ1llR7Edrr7X6xJPyMfSDstlI05djcsuoc2brddVO5gySBTnTKxISf01akFOjepTmUwCJo8kp4NTJfDD9h91kQUh8bC4jC3J6+ULlnb1FYZOUGkUARSNOyjDipAwjNgrfhxS+DykGVVd0+lYZNsZX5ov4xPPdU9yz3KIYFTtFwRdw4Dc+g7j4GkQ37RYuynI32GpsTHDZaSd5kO8fDhtOyj3E3abibj1tWiG+LShdvmMMXpUw0V84YFXqn2r00UwcU6bg1lA2AUpL/GjrIm4USpYRKplYLl6w5JGnz7DggXsu3bev5trvPsJax+HOPGcJC374EVswm310JkecuOJoLHHt5CDtDtOtk9JwqQLdwlHMMreM5lKP+pnYq7Ie9Xb1fvUh9Rn1LVURGmXWqXVrW7XbtPs0uUCbpNVoUe2zrF7toPaGpkNjYAMufKNISxrfI7UASVQbS2PWuCw1g2Sp5c6uHskEf6A8UB3oCGwJ7AzcG9gTOBCwBWiFItEj8TbXNxK/3U3MAkl9cuIwXzMCtCwSVyLMrxDnABs5m83eYrBJRo0RxT1CMgxiZ/A92uB6MoaTggwfsTC4QRhcw0Z4i7pTvVcVIV8ul6vlRlkS1IbztSnaLE0UG7UObYMmqppfE7Re69HdxERLdkUh4lGzjI9TH1lfzRpZB3dJZGAm3+JMvrOZfDNjcnQYG9bg5b3x0g5JhUSYfPH2cvv1dqCrM8u70CvI3EGSG3SHV6W1j2zF4M5Ds3tyEbeWPuNVMpPVSOF8XP2ZIeFE7jN+l05g8RPnyNXJvZDMioW8fh/3NlS0r/y8MqN8IlqYL8vLRqmKGpqQnyc5z57tuGz7j1fWj71szc3P3PL9H9765Ls3XJcYff2lDQ5hbs0cQX64PdryjbHB87+x02K2u7Z/beOhaWx5w+x1a+vm49o0HY3OwlmeBT/ZC34UYAZqxE9yG0eiXO9hYtYknDRRm2hzuHTVIdepdY66Gp2BLpD2dA/JSyfvgExVJ3m5STJ6kOSn+0h2mPuROYw7m15SjG5r0FwNGUJDpm7PUDJp2vGVbip6vZ/tdH0opKnGU8ZTzU+NL8Z1jBUWMj61vP7SrLAb37LSCSQR4ZkpJY2r5bfe2nfHHc/cM69Fnurd3J4z4q6zq8Xtdx16byTOq3rc9R+Tn8CDhBvefDCTqz8Th/kgn/nXiOmNDonT3LCROMMNG4m/m9xRFt0uvW6Dm4FbosXPzcfvdnGfOT1+N22u3HPutY4lFz6qoVD6tOkY4EH3Wq+ZfBa4Ndr83ZnOuQaQ4LlAYaPC+4iLnd1QyFd6rZCWpEEuEsqo/ymDL0h8HSpkJWgcaCt5ZRMmiiiekJvVjo9ExhdHKsu/zebKT0SKKTm+8sxUlMynL9EJYod1UlDRAjQ4sBfsaAE0NjvNJRoeEeb53Mm0++359nJ7tb3R3mHfYNdUxa/kK6Ii1CXdyteZBAMdyg/SDuXH5POccyglYoa5z5l+7k5y751lclfSx91I5GHmOBxI2fbIB2SB2bVhGs14SWlQHYyspW+wv56URNItKizMxDXY6yvNCu7Yt6Q+sZ0VSXs+XX7pkvtptFsAlBG4vuayXnNSyCRrD3EPXB2Op5NQZ0jID5WHGkM7QwdCMtSV57Jcg8aTq9FgcofTQHKpg34aTC5fSnMlUnMuVzOW9SXVnMuPIZhOmCNooLlaXTl68pybyk1HHUbc1HPcVM5N5dxUjbhhWd/ulBefMAPci1eIrWrUqW6/O9993C0BmRb37Nzcj+M2Zdhs3AbRa+O2ypm60w4fL+BKcdu51Wopkz1lzuPGyrcFd9A/PH94+XCRBfhCGTCpkcBY6kZ1oBH3iA0BCQIm3xlMF20LvgyvT2zI0Rt8uXbN7rbnqD7VoyRdmaQvg37YIVIX19kXrPmzzbWwuW9QgpSbXANC7gm4CKg4/yfkpYhSPy0DExF8WW655TeRbt++DYsnfy1n38Zpq+4+tij4i0X3PCjc079g4tkTwt/nXBYtO/ueVLTx1u0XNTwZ75+QtAvxDbQLPKyYgUy+66oZ/gyBbchkUOc2UuI9zBcJLnAuVi5HLlE7l+ZncnRzgQ/n0j23AHBdciK1BJwyDTJ0t1an2vy2fJsItnM6s3Gd2ciTohZsKRccKa4zW1rryQLql403byMr4KcMm0dqcLntNnRWXSokVTBQ5IMFTjtXSsahwaINut3isI6rp2/L23fD1MtfZa3ClT/7xuzJZ49KRT0/SMzvX572XOwoQQdksanmGL9JnfabtIvskRmb5Gfu2X6lXKlWOhRJkahUIXeCr3J4puTLp5J0HjiRdCcUcjG520dOCPf8yK+4int/+uwtsBPuhT1wAI6Dkj64SXSTRucavjYDv8+AID+Rcf8CuB8J3MiBexngu0Jk7TYmdrhYZyYTIq4FrnaXOCtzYeYVmaKL+wSuBlsmHbR9fO9oEFM3DsnbB0fqkiJ5N/Ef/LZC5XcP/OoBf81fPOSSP3l4gInTto/LF/mReKqF8CjIJC+yDA+4ynTmeOtYInH2yLsWHGQjvr4zcfSG7wnDTrPxid8kzib6E6+yCxgkVr7xK7btMOljS2KRNBb1kQE5rM70jeA2fXwE882utv/NLlTbd9oFO4mbOm0nKZOA7Gm529M7IhLHuNypjjmSpGV3u5lUx+r8AlMFv5AvbBGOC38TFBDoI7JdgZ8HSAcCt2IhZZNIceMVuKUK6TYEWt5KSWiCQE0JAjUjDI86O51Co9qBB7mIl83KZl6+Y6Z8tAZnNl0IUQ4Rpk652Q0qc4mKM11ChOnlJxOHyr9W+ddqWjs0KZLXQ1+8g0B3jPsgKSVhijQ0hqZF1kRSkheVlCe6fT6cI3zKsMi+fSu+ezRhwceV3/N51pWzxfftLVh3YSIkvxJdkTia+OBU4tlicWz/rTnj2a3PPjwpdXYnn98FD5gj7eg0kF8eMAqMg4Z0wPW6S3AptjqlrhN3j/T2qqa3V/Xc9qry7VWVUhdCH+xObSBn0xtI8jKNcswxXA4ZAzd0BWQ7X8ntQoOu4eFZV5Ne2aHCksELNfmufK+FlDuWFodfOHTxtPad+/Z1HiptFbsLH7qx/3ap6Gf7PeRnopdxFscYguNmYZjbopYbyBVUl98lFIRrwlvDIkzRWdkIJh50M7c8u2PEhhHCiPStExJHzIVkSiP84J+N/udO/V59j36crjEl7mOOOpHN8nMY3ZflZ7CCIBPah60fJohq9jDRK9Z4op5OT7fnoEf2ZJSz5GFgA7+fVPG8T+y97kyctQ1Bb4AIb0NG0JGh8msqMo8n0b1/spnuDlpS94JcKnQo5z4YOvFp1x2wqLC8HH33sgn5F4hl3ElVU66r35f00aZX3NkWu//GyypCj35vfXzi6jWVzeu3XrvmmV/+1Nzd+Z0rLpl68Zym0s3fmRVbaI7vKLt48rdW3Ur/mQ6utU6Kf5SKwAOfmvleLskNXmZHt1zVmF+rxvPQvZq0RdujHddETSeda+TLkoy0tP0QkZyfmo/rguTMD0romKWrfsgtR6PtJYsfp6DuhOe0R1A9fk++RwRPehv0EH9i5qFpHyZr9OjElv5shKgRZ49E3DwScfLw5YCa8WSKDS6b3eXQlJSf8PktatA94Oo1fX3Js5HbW4rna/T0wmUK93jd7MLXL78je9++4GOLYr+SivoXnF5RLXz46Uvfmbb8mYeE/SQ7HWX3jlQCCvSl7p1cksAcsiIoCp4rRQnHuoc6LkmaSncpheeujTwD7pvcgz9K1R1c1ews15hGvwI8mNOhnA7kqognsjn5fBtsVDYocoEwSagRokK3ICvXgnAtkyRYP4n1MiGflTOBScVZfqVWCjpQdr0S80v5UrnUIW2QZJBWM4eCnaAm6aIN3f8iXKEmX8RviPrRLo0+PE6OL+b3P3TzI9hKEmUvshwWOuCVqvo9wgcA/wnlv1r6CmVuZHN0cmVhbQplbmRvYmoKMjggMCBvYmoKPDwvTGVuZ3RoMSAxNjE3Mi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDgwNzI+PnN0cmVhbQp4nOWaCXhURbaAq+7tJb2lu5N0p7N2d246Wyfd2UlISJpsZCFsSUsCBLKwKpiYEEAUiDqIE0Uccd9Ax3Wi0mlQG0FBxV3UcXDfUHFBzYi7gyT9Tt3THROWmTcz75v3vu/dm3P/qlOn6ladU1W3WiSUEBJK+ghPWqc3OLNrb40aJITeANrWjhVtXZW2z+6H/C+Qv6Fj1UqLsyavhhC5hxBZyOKuJStu/7IMyjU+QhThS9p6uoiJCGD7NYhuyfLzF8975txLCTG+REjYgaWL2hYefbvtTWivFcrzl4IiVCHVQL4Y8olLV6xcU/az9HZCpJmEcH3LOzva7nry9nBIXwU2ZSva1nRpLuK2gO0JEMu5bSsWmdpyphLCH4LyeV2dPSv9MQTeR2NZeVf3oq5nj610EJIK9Q23EAqjVBAl0RK53w9PNvbtZCORkutBOKIjTgI9U3fQyWDJrMXLb2JtnuaC+jIyQugBucvv8KfLI8QWx17bUfPZoqFY/eoF2uIfSVSIWLDnqwtfYnxu3a55fsdIjzxC9jbYKqAXePH8m9xe6FWI9EZpDrwqHsm/Sh7lSAjhtHKOl0h4TtJHgv3Eq77BYiEWkmHRBfp2G5eEfQXD/dJQ5hmxBhXHCMMlEnIFMB7Gz8NcyCCTyQwym7SRDrKILCPnki7STVaSByw68Bo5pfwc0jmmvNv/lP9d/2GQj/1H/F/4h8B/P/p/8n93eMsp3iHi23+7WshCeN6GN63/H71fOP3NLQze/IxT7s/wlnjH31L5uHuT9HnZ5fIwuDeOvUOSxftudism/cfudtGTcjKHRVeigPRC8Cam0f+YZpPoukCaJxPJvEBaAiu4IpCWknTIYVoGKULKIerLIebtEPFlMBPKIPbL4Q1nwUzoJj2g64T5YiF5xEEy4baARS9omY2FZJFs0I1vwzLaRj3kOkDXCe10ksUwoyZC6ZmsWVm2+I68Ud19o7oJkDq1PdYam6td4rMNNNhfB5RMhhaWA2eBbglZCmU9Ym4RkI1tFTwXEockdPz0lbxNIk+7N/wfuCRlZPM/Yy93EfvJOv57MuUf1eObSfW498pJ7d+zpz/DnnGmtt4k66F8vexisl5SR9aL7dWPb3/cuwI27OLeGpN+5v9uXP7Vi+shRRCl2wgZ2TpGfRHct5AB8hB5lDxBXiB/Id9TJXzHNpJ95BPyJfmO/EoJlVMDjaWp/3O9GblEuoJo+P2wM4Cn/cf9R0fu8x+Fb3foGM1WyEVKkn7T+MP8QyfrRraO+EZelqmITqyr414E7TE65D/OlbK8P5/luU0sLdY4Jr9tZMfItnHdYd+oXrKGnE/WkgvIOpgJG8gl8N3eRC4jvwdfbID05fCd20yuJFvIVeQP5GqylVxDroVd8HpyA7mR3ERuBj/eCrvltkAZy7Nv0XViKSu5g9wNu8z9wD+SO8ld5B5yL+T/BN6/nzwIOtRg/gHQbCe3g/Zu0DIrptsBt4cMEi/ZSXZBzDAfzPnIfvIweQS4G6K5h+wlj5HHIY77IbJPijqmCebPbInPp8gB8jR5hjxLniPPw8x4kbxEDpKXySv/UsnToxqWe5X8mbwGc+0QeZ28Qd4kb5N3yQfkQ3KYfAyz7utTyt8Ci3fA5v2A1Udg9Sk5CpZDYIl2aPOeWPqF2MIhqHuYHKEh5EfKkV+JH1IseteJEbpRjCOLHovOnaKfWTx2QJ5F6J7R2DwAPn4A4slyLH1TIBoPgu0geDDov9N77eVAdNDfe8GG+YKVHAz44tlAJFg7j4/WfVEs84r1nhxt9TeP4ghfH+Od98b48FPymegZ9B6W/uY9ZnEEbJiXWRvjffsx1EXvs7pMP7YOK3sH8kdhd/gaPM34lRiJr8jno+nPA+VD5K/kG/Kj+DxGvoX95HvyA+R/As0xyJ2qPVnzM9y/kL+R4xDBE2R4TG74pJJhOLL6YbeilKM8Gfkt9ZtWFAmVUhnsaSFUQZVUTTU0lGqpDjTjS1SjJfpTStSnKVOImjAaTiNgv4ykJhpNY2DfjKPx1EytNGFMWdRoiQVKBJpIbYEyo1gzarSuGSwix9im0ky6Gp526qBOSGfRXJpHJ9BC0GRAPhvyE6EsU2QZnLbb4WxyXPoF9xK0HwG7yqCrasH8lnlz5zQ3uRsbZs2cMX1a/dS62prqKVWVFeVlk12lJZOKiyYWFkzIz3M6MtJTkmyJQoLZFKHXaTUqpSJELpPCjwdK0iuFqlaLJ6nVI0kSqqszWF5oA0XbGEWrxwKqqvE2HkuraGYZb+kCy8UnWbrQ0jVqSXWWYlKckW6pFCyegxWCxUfnzGyC9OYKodniGRLT9WJakiRmNJCxWqGGpdK0tMLioa2WSk/VqqX9la0V0N6gSlkulC9SZqSTQaUKkipIeVKErkGaUkLFBJdSOXEQTr0a9loPb6tsW+iZMbOpsiLGam0WdaRcbMsjK/fIxbYsy1ifyeWWwfT9/Vf4dKS91a5eKCxsm9fk4dugUj9f2d+/yaO3e1KFCk/q2iMmGPIiT7pQUemxC9BY3azRF1CP1KYTLP0/Eui8MPT1eE1bQCOz6X4kLMmGOOomKA+mCfQNegjjs1pZXy73uUg7ZDx9M5swbyHtMV7ictqbPVwrK9kfLDG4WUlfsGS0eqtgZaGqbA38rVpq8vS1WzLSwfvinw3+oNzi4ZNa2zuWMrYt6hcqKtBvjU0eVwUkXG2BsVYOZjrBvq0VBrGMuWFmk8cpdHkihDI0AIWFxWBZQ5NYJVDNE1HuIa0dgVoeZ2UF65elsr+1AjvI2hJmNu0mOf7Dg7mWmJ05JJc0s354jOUQlKTK/qaFiz3m1piFMD8XW5pirB5XM7ivWWha1MyiJOg8qYfhdVbxjWItGNtJ1kFjNnK5LcTSxMXwzSxaoLBUwUMoK4YCHYRLzLKIlhVbmmgMCZrBWwIWLDWuHcjwtvJqVsSzquXVMdZmK15/p0sxgT5JbZ6QMW3pQDHaJ3zPGbuG1qxDqZbKRRVjOjiuUWmgg4HWTt9Pjvki8GKoEcLCWR0s4m2wckHHQTOiikXRZPGQGZYmYZHQLMAccs1oYmNjvhbjW9cg1M2c0yRGOzBLGsflsLwAcx5iheJghiuHOVhljwmGVcxPEfOj2eqTimuCxZb+EKGuoZ81LgQaJBZYQTBoWVJN2+UFYbmwNKtgdxOq2gSLzlLV3+bz97X3D7pc/V2VrUsnsjaEmoX9QkNTcYzY11lN62LWsleFkTpa11iWkQ57T9mgQC+bOeiilzXMadoNZ1nLZY1NXo5y5a1lzYOJUNa020KIS9RyTMuULGNhGdbSLMiEiPYxu12E9ImlElEh5jt8lIi6kKCOkg4fhzpdUMeBToI6l6hjFwTJtBRcDNttpWUhC8+FzUv7W5vZ4iJGCCX8UQ8VSoiHE0oGKSdTe5TCojKPSihj+lKmL0W9jOnlMDHgWwjOYXtSf6sA+xRMqCYSQ3Eq8qxJi8/vb2yyHowZarbCVJsHMqfJo7DD3i+11YLdFCatoJ7i6etoY/0g7iZWV26r6WiGaRtsEExqPApoQRFoASyqxDpsOkKlDogNBFCs3wcZT1+zp9nOXtq0rFmczjoPqRYmQtixTWkSe5GzuT9MyBbXJiwFpW0TgwL6RhqaUBMDWXhZMzpJroaedwhQ1NFqAW9LSEcDTHXcS5UxqFkEW6IkaZEoyphAIWHD4m0qjdKjcECD8MfSKgdbklKbvLkZOy/mNgUM4N06jwp6lDTGlYEK4B0oqmF9gb9N0FVm+gRrZqaPzBLWwM7COi22JIdij8ZW0wabP9ZXgUYoCFYOYXuEKtDGAdTK2cjV4Hfe1ujz3yOcbx1zZaQL7OPAJiaJ2Q0TmzT3n6zwzLVnpIecrNWI6v7+EM3pK6C/QjSjBCX89IRfpT38u/ArkidyUkjqyTTSuJdo6K3wU3MifXFXRUVIhvxxyHLEQl8kIXCkvNUVLuE0MTGlQp7sCn6mvqZUfgXXSEqHP3j/GXgcDCt0HqTO94feGNINP6MvdA4dGsrKpHqrXpSIUE4ul8mEBAeXl5yUn5OTXcLl5SYJCaGcqMvNn1DC52THc3xEUFPCsTzl3z0xna8cTuTOtxY1ZEmp3RZpDg8J4c3xGluORVtXL+SnREslITJeGiJPzi8T3KtrE15WmpJj45JNSmBcLHD4SWno8e+kob/OllT8upf7orCpJFF2vkbFSRUht6bEGxKzYifVabQaaWhMZHSsPEQfqkyrbhu+MdoWqVRG2qJjbawt23AReCTSf1zylDSCJJAk8hEs43I3fGcT/V/sUmnpVMHn/8IVz1I2tUYwaYiRhhqTVEohQUksEoHqhSSbj6a54l0qoqZhvFqdHJcoCPFKjZEICSZ5WNysMLfUTUylpaVhkYUF+hw9eBbOsDnR9UPZNMo5vyXadDA7Z92mAweo6cD8FkxmZRK7PWZ8Nx5iiX/nbVmZdnuzzWjEuCXzVnkoLyQkJeVPoBisSLnAWyWDapmxICunMF4tmT0SPUuiicuzO3IjZGq6RaYTSnKKqpL1sifpI7SzPTHNIOUVOg2VDIeGqySyyDRBcqHeoOJ5lTH8meF3wLubwbs8zMxYkkr60LuDibI93FaiJ3HcEy4F0dtMon991L5TJlOzoQbGTO27XIaZanE8MAA7jGXITp2HhnRsMDEP/3MVszKb2bwVBH1wTupz83Os2fESaa6DqdkklvAVFz/Wt1wTn52clBOvzkqhWY6Glasb00eGMqvqU7tWlbrzY/mNK+7tKR7pUOqUMhk8JFc4nfLIkgUb2iua0lQjNQmT3PD5sfuPyyNgXhWTDThul8KpVJPizEx1to+rdymL1ZEmjU0Q1Ak+7lpXmMuknjArbVamoOJPimNpKUwU0yEYSVhhlLOwMKzQpDskpsMgXQiucGnPWBWGbWNxZhEX+ECKQtTzxZCH54QHgh9IwfyQSz+UGdLKcgorU8Kkr3AHpGHJ5RMmQkY28o6CiyrMcU6IVfKf0K8lGnN+RmahOVTyA/cJr4zNdaZnGXlFuSlOK5Vq40x87omXIuN0YlqyLDHVKOVVhvATVv6tcJNGKtGYIk6k8O/pIjVSqdFug9kyxX+UX8W/SXKIi6ai17yKyFwfN3cXSU4mE31cpUun5yPp95E00qfOpSdyaa7Pv9+lUGvo1Nxcx+Q0HzW5Yg4nUH5dwuYEzpUwI6E1gdcmmBM4tSQhQRLn8x92haphmsSZdLQ+7rijdhJb4wrITDriUtdLiMkpTprSIbsdV09Ly4KWIbaS7C3nDbWcR51DBwqdMAfR8//LvWHxjWBLOikpLy+wJbPNNiePzerRDblEwoJskDONIcKYk50/gV8VYU/LSNVP2HzWlNWzMyedv2v1bH3y5MzSjqk5OpVeJVPGVs3vLFp2bWv6z62TzsqPmlKa1+wwh+rkcl3olKIyW83y6mk9dYn5aaVpEbEJsaHRSZHmxDghPjzVfem8d8ISc6wFrvxc9i9u1f4veSv/BskjtwaiGkuSH+dWklBiomZiHt3oEn3U7A2vlTxKq0kWeFKlovVZ6eI6T/fRKq9LUQ9TO7p+2H7IPlQKzyEWDbYb7P23WxI9GSob87mSGSLErJAAqXiObRDiR83KS+WmibWzHUu2LZ9QvubO9pT68jyjQspH6PRJudXZ7Uujc+pzcusKkjQKtVziiRZM2khrtM61btfKS5/qKwk1xRu1JiFqohPcdv3V1efW2sxJZmVMGoE1UAtr4GFYA3aSS6XorZ3h4dZ0H1futedKfFy3S2nl08PTuZj0pyRsukVqaD2R6CTc1BmSVgm3XeKRcBJJrBNm0k4trWd0WcDGeSSp1vQTCdWFcno+VGFS03qFCQwUf3PFBp1hPwRTbCgw21rOm99iH5rfAj7Ofh82HCeb8Ir/7LvFbVsmWMf43zA+SpwhOV88esj5h1MThz+KKWqZXLawJlOrUIfwnCREM3HOyrLVO9cUlay67+yubYszf+DnLsic4ozi6HFHemHL5ITwyHB5mDXKaDZqQ02R+uK1j65bvW9jVVnv9vmWs89PnNTghLic4z9ON0unEQOxkkqMyz5i5PbBp83AtRIlMdMLHnJF6WqkU9nu+wasWorHJviQn1qGsy34IQoMJJzNtyQ4PsE+TNeq4zJttsw4dZDhJY3uoknuxuIEpVYplcKDX6vUqmQylVZJM6dOLKiZWlQIq229/zi/R9pFckl7sJ9Z0MMEooYnnBS4h3dmZBiVPu4RV6iLGBNU0pSa2Cr9VOwcfDcKC+ErK35unHD8yz7Cwq46ndmYQSRT/SnD0QcOFrCM5JQajfweVVx2SmqONUw+8ubJo6MhIRHWrCRbjlmt1Y78Sh1qlVWpVUgl7IDxxkhKcMxSQaljY9YpT3xLO9RholalTQgfeWskIyIOx0/XwvgNpDTw5dVqDBQ2AJWSaghVSYiPa33IpdRV4VCoU4yHuLe2xOwMqk8boVOjknBqx7APMgWs4hlkIHDqqQr3cQt2xsdng+MXeGeUJO+BaGQTXWC/0vlovbeuNtH32/5VD+GZXFtSlVFQkzE1aqzfg58EmGCFh4bY8bxQnGb/VmPjxyvuenL931EEPGIInCQCoZYp1LGZtqTMOJVeyLNlzMsHPyUyP+kT8hMd8/KCblNGp5otaZHK2q0zJjRVZutT6uvqkpvX1llG/cnpM2rz4qrKh3ecWcNfGEwtmTEj0l5ss5ckhxcv6a8ngXXwGsQgm1wUiEFaOHN6PFFBBEi8zuc/thM+CzrmJnXAbS6VK6M2LSqxZtRHYeihwMkz6Oh/puY/8Ox4Rxr419SxWYm2rFh1eGJhUmb7qS67sWHuuvqEUUfR4cl/zy3gjjbYv6r9RyUS8EY4SSbnBfeFCK4XfmLGw1NJogKTJcpHo10Kba1gCpymY70uKe7RwUkX2NX+uzWCR+8xe7Y0cDoJflclkuK1vgtWe1YWTFr7yAVrPD0FI8OG7IbSgsb8GGNWY0lhY340Pdq997LasvW+Vd2PbaqdvN53UVnnLEfq9M4pwIzUaZ0wyvUj10rYv6ankUnkusBZw5qvZGE3EDu3EX5wGJT5eVaJNDO4ODJ9tM6lSaqNqdFNLxRHUOijtWNHUApjgMN04KcHmwEP/6ttjHFF8mmmAC6ioHPkeqNRdA7Jab96fvLkScWW0bkQlWqOT41SJtdNa3C2989OGTmuTy3PjsrKyY/Pa83Nqkw30KHV+y6t1pod5pF5wZ1J8kFwYixLmZQaUX+pd3XhsllZ2oT8lJF3ymuyZy7GdcPtEU/hXYF1k6SFHdOlJtFapVnpVPIaXsk+8LAClD7a4FK67LVJWoOlxiDO++CesoCdHA4EVozyH9uP8Q2O/gz+kXF74KuuDImIig8zpGXAQjlpgQglBQWxmniLSSWVcHxdoiNaKQ+R6xOL04cPnbpEOrMnJ2l5uUKpNqTB6CP9X3NXSgbJRLIVR/+IXq8pSiVCBtu3IzUZwZhnwAlzp1AdpwkqNOzIGVmd5aNTvC55IPIQ9oPioskZzj6QrcdD1G6S8a80gvuIBH0iHhTwoB/0TuBby37iGoOHJe5KVZgAP9jqzq1OOCc8gg34bFUc7i9PMhdEhD/lKIqwROnlMpVMujbdGQ5HiqTpa2bR550T4lIilc/C5JFKYfI8q4xMiZvgHGmpqZEr5HJDIniriG7hCrgWoiV6L5GrdlMrkRAnnHwOZmWK5zY8zlhZTwqMppHWKKMxim5X69VS+vNEh7OwwKE0pZBBBe/j/uaNjzP7uF+88XbAz974dMBPiB8RP2DZ95j7DvEt4hjiG8Rf0XII8TUqv0J8iTiK+ALxOeIzxKeII954BeATzH2M+MgbFwY47I2LAnzojXMCPkC8j3gP8S6avIO5txFvId5EvIF4HXEI8RfEa4g/I15FvIJ4GTtxEPES4kXEC/ja59HyOcSziGcQTyMOIJ5CPIl4ArEfsQ/bfBzxGCr3IvYgHkXsRvgQjyAeRjyE2IXYifAiBr2x2QAPYoc3NgfwIOIBxP2IAcSfvLFZgPsQ92K9exB3I+5C3In4I+IOrH47YjtiG+I2xK2IW7DpmxE3YfUbETcgrkdch7gW612D2Iq4GvEHxFWILYgrsenNWP0KxOWIfsTvEZdhhU2ISxEbEb9DXIK42BuTC7gI0YfYgFiPWIe4EHEBYi3ifMQaxGrEKkQvYiWiB9GNOA/Rhej0RucBzkWsQCxHnIM4G7EMsRSxBLEYsQixENGBaEe0IVoRCxDzES2IeYi5iDmIZm/UBEATYjbiLIQb0YhoQMxCzETMQExHTEPUI6Yi6hC1iBpENWIKogpRiahAlCPKEJMRLkQpogQxCVGMKEJMRBR6TYWAAsQERD4iD5GLyEFkI7IQmSJ46jU5IOdEpQORgUhH2BFpiFRECiIZkYSweSOLAIkIwRvJJnSCN3IiwIpKC8KMiEfEIWIRMYhoRBTChIhEGBEGfEMEviEclWEIPUKH0CJCERqEGqFCKBEKbDMEIUelDCFFSBA8gkNQBBFB/YgRxDDiBOJXxHHE3xC/IH4WX0t/EkdEf0TlD4jvEd8hvkUcQ3yD+CtiCPE14ivEl4ijiC8Qn+P7PvMaBcCniCNeI0ww+gniY6+xAPAR4rDXWA740GusAHyAeB/xntdYCXjXa6wCvIN4G/EWNv0m4g1s7HVs7BDiL4jXsLE/Y71XEa8gXkYcRLyEeBHrvYBNP494Djv/LOIZfN/TXmMZ4ABWeApf9CT2+glsbD9iH+JxxGOIvYg9iEex6d3YtA+bfgSbfhjxEGIXvmgnwosYxNd6EDsQD2LTDyDuRwwg/oS4z2uAfZfe6zVMBtyDuNtrqAfc5TVMA9zpNUwH/NFrmAW4w2twAW5Hk+1osg1NbkOTW7HsFrS8GXM3oeWNiBuwwvWI67yGGYBrsfo1iK2Iq7FLf0DLq9ByC+JKr2EmYDNaXoG4HNHvjWgC/N4b0Qy4zBsxD7DJG9ECuNQbUQvY6I2YC/gdll2ClhejyUWuHcBj2krzN6HV5sPqaeYnQZ4A2Q+yT3WW2QsyCOIB2QHyIMgDIPeDDID8CeQ+kHtB7gG5G+QukDtB/ghyB8jtINtBtoHcplxqvgnkRpAbQK4HuQ7kWpBrQLaCXA3yB5CrFEvNW0CuBNkMcgXIZAV3gjtOziJm7lfgUmKmG7zhbDmu94axqbUS0ePVs6nVjTgP0YXoRJyLWIFYjjgHcTaiGFHk1TFMRBQiChATEPmIPEQuIgeR7dWyeZqFyESEIfQIHUKLCEVovBAUH1UjVAglQoEIQci9GhZqmWsu8K8gQyBfg3wF8iXIUQjnhyAfgLwP8h7IuyDvgLwNYXkL5E2Qx0EeA9kLsgfkUZBbIRS3gPhoH3p6rVfPpvz56Jw1iNWIVYheRDmiDP0wGeFClCJKEJNwyAZEBCKcYTfP85zXZb7zcZ4ju0AOgPA8wb5cgGjAqM/Cns1EzEBMR0xD1COmIuoQtYgaRDViCqIKUYmoQCQgrNh5C8KMiEfEIWIRMYhoRBTChMOMRBhdNwOHQU6A/ApyHORvEOBfQH4G+QnkR5AfQL6HqH4H8i3I5yCfgXwKcgTkE5CPQT6C6B4EeQnkRZAXQJ4HeQ7kWZBnQJ4GOQDyFIgP5BGI+MMgD4HsAtkJcjOLPjeMPl6HuBCxzKuHoxBdiliCblmMWIRYiOhAtCPaEK2IBYj5iBbEPMRcxBxEM6IJMRtxFsKNaEQ4EQ50dQYiHWFHpCFSESmIZEQSwoaxSUQICClCguARHILiiiSuO4B+kBGQL8Cxb4C8DnII5C8gr4H8GeRVkFdAXgZH7wbZyNvMv+Md5kuow3xxdZ/7ooE+94bqde71A+vcqnVF6+rW8ap1MYAL1g2se3ed7MLqte4LBta6JWsj1nLK86tXu9cMrHarVlP1quped2Pvkd4fevmI3sbehb0re6/pPQQK+Z29u3oP9PLsX6fCeguKqvp6r+rlIqCcI71Uy9TWXlVo1crqbnfPQLdb0p3bzRX90E0Pd1Mus5vO6G7t5sBqZ3diShWzzus2RlfpujO7Xd38edWd7q6BTvf0zs7ODZ3bOvd1Sjd0bunkdkCKc3UqNFXnVq9wf7iCkr2cn+hA9nN+L6/s3MONEEq+4UZcfnoOOOBscMQyxxL30oEl7sWOhe5FAwvdHY52d5uj1b3A0eKeP9DinueY4547MMfd7Ghyzwb7sxyNbvdAo7vBMdM9a2Cme7pjmnsa6Osdde6pA3XuWke1u2ag2j2jmk5xVLkr+XwzfEFIPPx1xffFH4uXqFrjuuK4rrjDccfi+K7YY7Hchhiqjd4QvSWa18KDw0eUOWpL1LaoHVFSrZjg1V1hfWFcl75Pz2XqXfpX9Yf1EqLfrue0W7TbtDu0/HTtAu03Wr9WskNLd4TuC30llJ8euiC0M5TXhrI8r3OFOrKqtBqzxjXFqeGLnZpSzXQNv0VDXRpHdpVLk5hcVaqerl6g5repqUudlFr1jdKv5FxKKPhG4VdwfgUlPLVQSqgOwIewGFGDuQrm404jlVI4Wgw2NtjtdT65f1adJ2TGXA+9zGNrYE/XzDke2WUe4p4zt2mQ0iub2X/aa/REsP/5Ucxv3LyZlMXVeeIamjzb45rrPH2QcLGEHxIkbtBIyprt83t6e3pW2nvs8ACZ3wOalb3wJ4LCE9i7kpWs7CFgYj/DxSx6GHpFo57eBb3QBhSAukdUs9x80eRMbfxHrzOO5D9x0f/Nl///vkwL5v8XeQlI6QplbmRzdHJlYW0KZW5kb2JqCjI5IDAgb2JqCjw8L0xlbmd0aDEgMjQ1MjAvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAxMjU5Mj4+c3RyZWFtCnic1XwHeFzF2e7MOdt7L1qtdlcr7UpaSatmNcvSqnfLKmtLtmVLllxxkXsv2GDAYEoowXQSugGv1jaWMQGTOAGSGBxCSQIhJiGhmkBCCM3S/ebMGVk2hpv/Pve5//139e77TjmzM9/55jvfOZKNMEJIh3YgHvW1dYbzGpavfxchfCvU9g0s6x+S/1b+Tyh/AeVDA+vWeGO3n3gZIfn1CEkTFwwtXPb5560ahDSPIqRMWNi/egglIj/0/QhgWLh044IbLrc+gVDJ7xBK/WTR/P7B9w/0n4Dx+qC9cBFUaE9Lk6BcBuWURcvWbNh1h24LjO1FiBtaumKgP2dx4CWE+HegT+my/g1DpgPcKej7DcC7vH/ZfMvVOVOgL3w/LhxasXrNmAvtBp1I2odWzR+65AA3ipD1eRjegDCsUolUyIzkY2NIj8ja70CXIyn6IYBDBhRG8xEyXo93Qk/SW3iNOciYF3nB8TI0ivAJeflYyVi17LQw4sTXHbTmb/PXPp05ba6+7F/IqRAajn245deEn996aPZYyehq2WnZL6CohFnQF88/i6+HWSmk+6T58FVJlPlTaDeHFIjTSzmOk/CchM7j3Ku10+tFEVjJRnFud3EB1oc/ItURywgrw8Ia4eQhCXoIOBHWz0MpjEpRDapDTWgqmoa6wCKL0RBahzaCzZDQWg2tDagVWjtRP1qAlqJVaAO0LkVRsBacn7FXxt4YexP4PcF+X4kzdIggL5vwjSmC1sK5cCAnSkJl8M21qB41oh40E81CvWgQLUSL0BJ0CcwBHA9qYdYSJehBtEHUdHSqOfDmJaLmUQ7MlmoJ1GeKWgqK9ZcJ9dNhlavQaljpCrQc7DMJZcOxOaCq0FqoXQrf5kW5KA/qqmHNS6FuHhyxGKywGA2AWgFHrwBbrIFv9F7Qh9TkCeNNQh3wTQthzKXQYxV6eLylCNS3xyIjrYCaIeGzH2roDLOhpRLGWArcAXXERmvgKK8w/mphNevgcxB6kte93/XGSfC++rz3Z/gz7ibuT+zN1wjvTyXXXPiWstfrsvLveJ85/y3frTDB+2HFw8qm8fdJ1ZPqcvWRC95fad7QLoX3VxPfuhvIW6/Sn9KfMrQY3mRv443GG01+05X/h+9T3/GGqCfRXXTnf+9LUgNnivBH6NHv6sM/Rtsk36BHYQ9/qx+3F3xdfMleR49KM757rPHvTT6/D3xHPf832Fv/hRf/Kpr9vd9RgPbx82AXUt0nHPM17NMLXtxKlMqfQJNIf/waxNjveUH7Ptkg2kf6CuMW0/G/6/vHv+OXMBcfahf048gHbTd9az13omSB16N0/m6q/1+9uBR07L/Sn7eTSCa/C6HRG89rmAYRbTVco3fAdWgvuhE9g96AyLIL1D50D3oAokgMPYteQK//35z96EbpMqThj0CENJMYPnZm9AHACFxBztXcCCWzxHuuZsww9vEFdR+P3jhmGB2RmZBKOFbLvQy1/8Rnx77iKkh5rJCUuStA64UjPpXfNXpg9MELbNAuXBFmg6/1wf6aB7FtEUQ+cmVYipZBTCSl5dC2ED4XQGku9BqAXgvE6wfttUKMpWsgBq+D95AQ92mJtK0UymvRenhvQBvRJrQZbUFbxc/1Qs0WaNkklDcAtqHtcGYuRTsFxZjW7EKXge/vRlegK9FV31u6alztQVeja+A8X4uu+06997zS9fC+Af0A/OEmdDO6Bd0KfnE75B7n1/5QqL8N3YXuBp8hbTdDzd2CIq1PoV+gw+hxdAA9IdhyAKxGLcLsskCw4RDYYAuscNeEGVP7rR+31jZYO1nbHnGlG6B+54Qj1ol2JD13QU86Cj0PZJStF1jielgD1edWREs3C+s/VzvRKt9Xy+xxxwTL3C6UiLqw9rv0LehO2IH3wiexKlE/Ak3V3YKeWH/XeN97hPKP0X3ofjgXDwqKMa15APSDkJc9jB5B+yGuPzpBT1SUH0ePCWcuhoZRHB1Eh+BMPoGOoBGh/vvaLlZ/UKyPj9ccRU9CLHsKPY2OQ6T5KbxZzU+g7hmx9oRQR8s/RT+DMulFS79Az0GE+iX6Ffo1egn9HEovCp/PQ+kUehn9Fr2OtaB+g96Hz7PolPQdyMwq4V7gSbDzHWgOmhOpH5w7p3f2rJk93dGuzo72aW1TW1uamxob6utqa6qrKiMV5VPKJpeWFBcVTgpnZ2WmBVJT/Mkeh8Vo0GvVKqVCLpNCxoxRZq2/rs8bC/TFJAF/Q0MWKfv7oaJ/QkVfzAtVdef3iXn7hG7e83tGoOeCC3pGaM/IeE9s8JahsqxMb63fGztZ4/eO4Jnt3aD31vh7vLEzgm4VtCQgFLRQ8PngCG+tY1GNN4b7vLWxunWL9tT21cB4w2pVtb96viorEw2r1CDVoGJp/qFhnFaOBcGl1ZYOw/2ClnxtjE+t7R+MTWvvrq1x+Xw9Qh2qFsaKyapjcmEs72IyZ3S1dzjz+J5rRgxoXl9IM+gf7J/dHeP74aA9fO2ePVfEjKFYur8mlr7pHQcseX4s019TGwv5YbDmjvEvwDFpqsHv3fMvBJP3n/no/Jp+sUaWavgXIpIscdxM0M40grnBDGF9Ph+Zy9UjETQPCrEd7d207EXzXHEUCYd6YlwfaTnOWqxR0rKDtYwf3uf3kVNV2yf+rFvkiO2Y583KBOsLP6nwA+3eGB/omzewiHD//D3+mhpqt67uWKQGRKRfXGvtcE4Y+vf3wSIWEzO0d8fC/qGYxV9FO0CFl5yDxZ3dwiHiYTFLdQxutsWjYuHaGjIvb+2evho6QTKWv737KMofOz1c4HUdzEcFqIfMI2arhpMSqN3TPbgg5ulzDYJ/LvB2u3yxSA+Yr8ffPb+HnCW/IZZ+Gr7OJ3yjcBSs7YLerDNZuTxV4e3mXHwPOVtQ4a2DD39VGTQY4HQJRXJGq8q83diFWDf4FrEHUeeNAwU+tbqBNPHk0OoGl6/HR1/fMyWXOCdpakwxYSwDVIzPiX7Pd06N9iYTSvfWzq+ZMMHzBpWKExRHu/g8OWIL8YvhCAU5nQ2siU+FnQt1HAwjVJGz6PDG0DRvt3++v8cPPhSZ1k3WRmwtnN/mTn9z+8xu4WyLXtJ1Xom2F9NSDPmgmRW4avDBupCLnVahXC+Ux4sNFzQ3smbvHoW/uXMPGdwvDoi8sINg0bJAY//VxaYC2Jp1EN38df1+r8Fbt6d/ZGzHvD3Dkcieodq+RaVkDH/j4B5/Z3eZS5hrR/dW1ybyVSbUjJu7qrIyIfZUDfvxle3DEXxl58zuowaEvFd2dcc5zFX3VfUMp0Bb91EvQhGhliO1pJIUvKRARuqAgkLo7zoaQWiH0CoRKoTywAhGQp2C1WE0MMLROgOr46BOQusiQh15wUlyLAITQ7it9Q6S07OlZ9Gevh6yuZANTiX84Bj2l6MY5y8fxpxME1P551fF1P4qUl9B6itovYzUy8ExsA2DcUhM2tPnhzgFDtWNXJi6Ik+G9I6MjXV1+066zvT4wNVmA2Z2x5QhiP3S1CboV0/QB9X1sR0D/WQeKNpNjpWnNg70gNuyAaFLY0wJIyjFEaBHnXAMcUc4aADODZxA4fgdUIjt6In1hMiXdi/uEdzZEEMN/lI47XRMaYB8Ubhnj8mfJ+xN2Aqq1CsIKWFuqLOb1rigCF/WQ40k18DMB/zQNNDnBWtL0EAnuDqNpSoXrZkPIVESmC9A5RIbEVkWn6rWqmLKbBgQfohWZ5MtKU2V9/TQyQulK8QO8N2GmBpmFJhgSvEAsA40NZK5wM8VMFXS9VkyTPsI6vBvgMhCJi2MJIfmmDa1sR+CPz1eDTX+YnawgsQItTjGCVorJyvXgN351K6RsQf9G30TXlmZfnJxII6JXEfBsVHPngsrYrNCWZmKC2u1QvWePQrtxQ+g9lJox5lUemvhqoFQXMl7R7jLDikduAnELiZ2MnEpEzuY2M7ENia2MrGFic1MbGJiIxMbmFjPxDom1jKxhonVTKxkYoiJFUwsZ2IZE0uZuISJJUwsZmIREwuZWMDEfCYGmRhgYh4T/Uz0MTGXiTlM9DIxm4lZTMxkooeJbiZmMDGdiSgTXUx0MtHBRDsT05hoY2IqE61MtDDRzEQTE41MNDBRz0QdE7VM1DBRzUQVE5VMRJioYKKciSlMlDExmYlSJkqYKGaiiIlCJiYxUcBEPhN5TOQykcNEmIlsJrKYyGQixEQGE+lMpDERZCLARCoTKUz4mUhmwseElwkPE0lMuJlIZMLFRAITTiYcTNiZsDFhZcLChJkJExNGJgxM6JnQMaFlQsOEmgkVE0omFEzImZAxIWVCwgTPBMcEZgKJAo8xMcrEWSa+YeJrJr5i4ksmvmDi30x8zsS/mPiMiX8y8Q8mPmXiEyb+zsTHTJxh4iMmPmTiAybeZ+I9Jt5l4m9M/JWJd5j4CxN/ZuJtJk4z8Scm3mLij0y8ycQbTPyBid8z8TsmXmfiNSZeZeIVJn7LxMtM/IaJU0y8xMSLTJxk4tdM/IqJXzLxAhPPM/EcE79g4udMnGDiZ0z8lIlnmTjOxDNMPM3ET5h4ioljTDzJxFEmRpg4wsQTTBxm4hATB5mIMzHMRIyJA0w8zsRjTDzKxH4mHmHiYSYeYuJBJh5g4n4m7mPix0z8iIl7mbiHibuZuIuJO5m4g4nbmbiNiX1M3MrED5m4hYmbmbiJiRuZ+AETNzBxPRPXMXEtE3uZuIaJq5nYw8RVTFzJxBVM7GbiciZY2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNZ2oNXMcHyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zyH8zSHszSHszSHsyyHcyyHcyyHcyyHcyyHcyyHcyyHcyyHcyyHVx9kAjImuNJ5R7ImeNJVqCdtHRpPKkUaActbae0LZ6kAdpKS1sobaa0idLGuLsSaEPcXQ20ntI6Smtp2xpaWk1pFa1cGXdXAQ1RWkFpOe2yjNJSSpfEE2uBllBaTGkRpYWUFsQTa4Dm09IgpQFK8yj1U+qjNJfSHHpcLy3NpjSL0kxKPZS6Kc2gNJ1SlFIXpU5KHZTaKU2j1EZpKqVWSi2Umik1xV2NQI2UGuKuJqB6SnVxVzNQbdzVAlRDqZpSFW2rpMdFKFXQ48opTaFURntOplRKDy+hVEypiFIhpUl0sAJK+XSUPEq5lHLoYGFK2fS4LEqZlEKUMiilU0qjFKRDByil0jFTKPkpJdOhfZS89DgPpSRKbkqJlFyUEuIJU4GclBzxhDYgOyUbrbRSstBKMyUTJSNtM1DS00odJS0lDW1TU1JRUtI2BSU5JVncOQ1IGne2A0ko8bSSoyVMCQmExyiNCl3wWVr6htLXlL6ibV/S0heU/k3pc0r/iju6gD6LOzqB/klL/6D0KaVPaNvfaeljSmcofUTbPqT0Aa18n9J7lN6l9Dfa5a+09A4t/YWW/kzpbUqnadufKL1FK/9I6U1Kb1D6A+3ye1r6HaXX4/YZQK/F7dOBXqX0Cq38LaWXKf2G0ina5SVKL9LKk5R+TelXlH5Ju7xA6Xla+RylX1D6OaUTlH5Ge/6Ulp6ldJzSM7TtaUo/oZVPUTpG6UlKRymN0J5HaOkJSocpHaJ0MG6rAIrHbbOAhinFKB2g9Dilxyg9Smk/pUfiNojX+GE6ykOUHqRtD1C6n9J9lH5M6UeU7qV0D6W76WB30VHupHQHbbud0m2U9lG6lR7wQ1q6hdLNlG6ibTfSUX5A6Qbadj2l6yhdS2kvpWtoz6tpaQ+lqyhdSekKSrvj1n6gy+PWeUCXUdoVty4A2knp0rg1CrQjboVgjLfHrYVA2yhtpYdvocdtprQpbh0E2kgP30BpPaV1lNZSWkNpNR16FT18JaWhuHUAaAUdbDntuYzSUkqXUFpCaTE9bhGlhXRmC+jh8ykN0p4DlOZR6qfUR2kupTl00b10ZrMpzaKLnkmH7qFf1E1pBp3udPpFUTpKF6VOSh2U2uOWCNC0uIV8Q1vcQtx7atyyC6g1bskCaqFdmik1xS2QF+BGWmqgVE8r6+KWbUC1ccsVQDVxy3ag6rhlB1BV3FQHVEkpQqmCUnncBNd3PIWWyuLGHqDJlErjRuIaJZSK48Z6oKK4sRuoMG6cCTSJthVQyo8bM4HyaM/cuJEsLCduJHszTCmbHp5FvyGTUogOlkEpnQ6WRilIKUApNW4kVkqh5KdjJtMxfXQwLx3FQymJHuemlEjJRSmBkjNu6AVyxA1zgOxxw1wgGyUrJQslMyUTPcBIDzDQSj0lHSUtJQ3tqaY9VbRSSUlBSU5JRntKaU8JreQpcZQwJRQZ08/zEIzqBzxn9YOeb0B/DfgK8CXUfQF1/wZ8DvgX4DOo/yfgH9D2KZQ/Afwd8DHgDNR/BPgQ2j6A8vuA9wDvAv6mW+j5q26R5x3AXwB/BrwNdaeB/wR4C/BHKL8J/AbgD4DfA36nvcTzujbX8xrwq9qlnle0Ac9vAS+D/o025DkFeAnwIrSfhLpfa5d5fgX6l6BfAP28donnOe1izy+0izw/1y70nIBjfwbj/RTwLCAydhw+nwE8DfiJZqXnKc0qzzHNas+TmjWeo4ARwBGofwJwGNoOQdtBqIsDhgExwAH1Rs/j6k2ex9RbPI+qt3r2q7d5HgE8DHgI8CDgAcD96izPfcA/BvwIjrkX+B71JZ67Qd8F+k7AHaBvh7Fug7H2wVi3Qt0PAbcAbgbcBLgR8AM47gYY73rVVM91qjbPtaqFnr2q+z3XqB70XM6nei7jiz27cLFnZ3RH9NL9O6Lbo1uj2/Zvjaq3YvVW19bmrZu37t/6xtaISabaEt0U3bx/U3RjdH10w/710Se53WgBd3mkLLpu/9qoZK1l7Zq1/Gdr8f61uGYtzlmLObTWsNa7ltesia6Krt6/KopWTVu1Y1VslWRybNXpVRxahVUjY8cPrnIl1QFHtqzSGupWRldEh/aviC5fsCy6BCa4uHhhdNH+hdEFxYPR+fsHowPF86L9xX3RucW90Tn7e6Ozi2dGZ+2fGe0p7o7OgP7Ti7ui0f1d0c7i9mjH/vZoW/HU6FSoby1ujrbsb442FTdEG/c3ROuL66K1sHiUaEj0JvIGMoGpiTAT5MJVOa6I67TrE5cEuWKu4y7epE/wJHDpeieubnPiFc7tzuucvN7xkoOLONIz6/T2l+x/sv/dLjFH7OnZdchmsHltvJWszdbaVSdwRQ3l3EnCWltt/kCd3or1Vo+Vq/VYMTKeNn5i5K3PGF4ycHo91uvH9FxED931Oo+OIx9jOj6iyy2q02s9Wo58jGl5W0QLNWTEoGZaV51e7VFz0Qp1m5qLqCuq6yLqrJw6xGMvxggbgHgFmQW2eupgXx+0YSmG6/lwV2co1DyiQB3NMcW0WTF8ZSy1k3xG2mfGZFfGUHTmrO5hjK/tGcZcdVfMQn5jK5Qv37sXVbmbY+7O7tg97p7m2A4QESLGQCD3sA1V9YTmrF67OhRaMwc+5qxeExJ+oITXklKIVJKf1WugTN5rhTIKfe+LdgOauxpea1jlmu8/6v/3F/7vnsD//NcwIn9kUDnGXYYGuV2AnYBLATsA2wHbAFsBWwCbAZsAGwEbAOsB6wBrAWsAqwErAUOAFYDlgGWApYBLAEsAiwGLAAsBCwDzAYOAAcA8QD+gDzAXMAfQC5gNmAWYCegBdANmAKYDooAuQCegA9AOmAZoA0wFtAJaAM2AJkAjoAFQD6gD1AJqANWAKkAlIAKoAJQDpgDKAJMBpYASQDGgCFAImAQoAOQD8gC5gBxAGJANyAJkAkKADEA6IA0QBAQAqYAUgB+QDPABvAAPIAngBiQCXIAEgBPgANgBNoAVYAGYASaAEWAA6AE6gBagAagBKoASoADIATKAFCCpHINPHsABMAChQQx1eBRwFvAN4GvAV4AvAV8A/g34HPAvwGeAfwL+AfgU8Ang74CPAWcAHwE+BHwAeB/wHuBdwN8AfwW8A/gL4M+AtwGnAX8CvAX4I+BNwBuAPwB+D/gd4HXAa4BXAa8Afgt4GfAbwCnAS4AXAScBvwb8CvBLwAuA5wHPAX4B+DngBOBngJ8CngUcBzwDeBrwE8BTgGOAJwFHASOAI4AnAIcBhwAHAXHAMCAGOAB4HPAY4FHAfsAjgIcBDwEeBDwAuB9wH+DHgB8B7gXcA7gbcBfgTsAdgNsBtwH2AW4F/BBwC+BmwE2AGwE/ANwAuB5wHeBawF7ANYCrAXsAVwGuBFwB2A24HA1W7sCw/zHsfwz7H8P+x7D/Mex/DPsfw/7HsP8x7H8M+x/D/sew/zHsfwz7H8P+x7D/Mex/vAoAMQBDDMAQAzDEAAwxAEMMwBADMMQADDEAQwzAEAMwxAAMMQBDDMAQAzDEAAwxAEMMwBADMMQADDEAQwzAEAMwxAAMMQBDDMAQAzDEAAwxAEMMwBADMMQADPsfw/7HsP8x7H0Mex/D3sew9zHsfQx7H8Pex7D3Mex9DHv/vzsO/w9/9fx3T+B/+Msxdw6SIjS6mn9ZqkM8kqMS1IqmollPIS24tA2V4sOHrTU1iiz50+CuHPKCwysQxtURvYTTHklIqPAfmSTbyxsb4eb9UIV8L4TyirNvnX0xfPatM6aS8Bkc/uPbb71t+PRFY0k4/+1X3s7NwUafUYBFx8nlFpk/OZubFAwU5ufnlXOTCgL+ZB0n1BUUFpXz+XlJHG9hNeUcKWP+5W9m8m1nZdw2f8X0fGlSgt6ilUm5RIcpqyzV0DkrtSzbLeflMl6qkKcVVSU3L61N/oPc6Lba3CaFwuS2Wd1G+dk3pLqv/iHVfV0tWfr1Tbxs8uyKFP5WlYKTyGQjSQ5nxmRf43S92SBRmw1Gm0JuMmrSamaf3W1NJGMkWq10rLOtCKP+sU8kGmkSWG/ewUQ0OTQy9t5BA24F/uSgXuCPDmoF/vigRuD3DqqBn4brtw45cBj5UABnxs2dkmM4A01COTh7WDkdTPnKGQIcfls4X4bXTuTmpFp0sgnmkFlF8xDDWS1JHLEjMZNEw0kVlsjczY3bfnVda+ctv9levGRmnUsh5SUKtUKX17aybfrewaJJA9fPal3dXqCXq2T8EYPDpLOkB11d9316573fHJht9Wa4dOYEkyXRrAyGg7W7n92y+SfbKwPhgMyYBA7xKEKS68B3TMiD1kfcFT5sdsDKzQZYttkCazabYMFmB6zWfAwyFYQSqG0SRNsIrBX4c2KbBNE2Cccgp1CCbTRxXbtrBAeGpV2o4kzFuC1eoZSb00s8ye9LDkwyFhTm+2Dl8gKwht9IDCG5bvr9nzww+rE9Pd2OUx967872wwUrHtl9YHjLI6tKuNse+vr+Dk9QsjPomfHj9/YtPnxZ0zfG8h3Pkn/z+ujYV3wXrCyIZg/LzeIZNYuzNouzNouzNouzNo9wxsNaN0pyy0ew5qDZ7JSN4LSDye3OKKqoEHdE+ISxhE4+D7aDMHkjmbaVSubtbDV8l0SllY8G8HG5ViURdERh8SY4ki2KdDtXJ9SeMCcaFaMNcoPLanYZlWf/KtfKpVL4kDwe9ICbiiuSTJNaUBiNHKrIxX6NuCiNuCiNuCiNuCiNuCgNLCqSaE9RkzOrJmdWbYBuahX0UZMzqx7hDBE7ilhxK4qYyYfBCFfACLQjO7mVhQbCT0CbPaMjZQRnRvTHNfiUBms0JneHKSol5qkA8/SuPFOBw3B2iXlEIxnGjdWbOm6ciXai/m6FOiYl0xQWnyPBa1GcPQjKSWylsCQ7nD6LgmsVrAcqQaEhRtIouPKzP2Va8gemzn7FyZgW7Ye7wX5WNO1Ihb3NfsDOI9GESDQhEk2IRBMi0YToSfBm1djxI2AJlaFDWC4sc9yFU7+1GNzN5q20+uzOibM9N0MyK/nYx/gdmFUa6j5K/iH1fzwdN0zHiFvdOn+H8hjOQ2bYbNnDUjHqgJuOTw/T2clYABYi9bmZvpNYs6IjsSg7WS2XcjzEFoXTn+1JzvEa6BLMSlzXumNmrlJv1GiMTpMNoq/epDdmt1fyd5H1SGA91L6yEOy4MvRoxNBXPlTOaXNy7OGwKtvhSBj5D8MG8dWklFyNRkW8VUW8VUW8VUW8VUW8VUUWj8aOR5zEEimF7WqHXRt25GbLPGntnihzxgqTvcSYD3Z4hfmhMd8wrowlU8L5+cb8886dH+t4ooLYf94uJmay43wMlzPBYrKQwuJx2n1mBTeaz6utbos1yaLmRusxeKbT4TXLM12LvDkpDiVeL8W71QmegHOZ3mXWnHOBhV/fJFfJeQkEbbh87RuvfyAjRZOQ5vpmBv9AUoZTrTS7reLO3yY1oino8oNBvd4iGlNgvchagT8hxrSIxrQIxkxSZWfnEWPmOfTkAzrmGTREQZc80sWAkoo7VNn6oMRJIp2sC1HzEeN9y3bhfOESBgFasFQgEPTbbNaL2CuJt+cHAuf8TLJNa03QFiUE/X7r6CJvZSLHcQqzx+HwmBSZCR3uoMdtxKXuwrxcB+YwtDhtXpOi3gLXa7U7L8idLtk6ueGWpm/+OR4aH0lLVtnTPWefLxjo6w237W/jnpZrlBKJEtyRXNvgCvAc+GMiSkcbhlNkotVkogvKRBeUiS4oE60mIyaxG93EZG7if26DRotb3F5oc5M/A0DG1BGsOiiTafwjWH3Q2q6ZcHGgBjOcf33wX3hRkEy4xPHPRdY/tuFGpdnnJGEiIwFbM1oXL2tJPzx5Rm/m3bdPXViXwt/Yf8fystHscT+BpcvtFbM3zmhbUqA7+2Va/QCJJfVjZ/gBqQ81onePosqx9w7pDbilUlynwAaRNQIL660c4TIjobyI2YJb8iIQUVLyUvI0Lgc51kW2nstgIB9wiIu4jOtJLpfsv4MuISAdP+gU2UL5CT25eGiyj+EgKkIqHIiojd4iXBRRa3CLkTxFVRFVZCwy2srgKnu40iVN77SN4HQheJ2By0jJGWNJCQSwUK/hjIEY9dzVxEQbLghtkvNCW8F4qLswuZLxA9Xr7+2tXDFjsl0NYUuhy5+2sqm4tzolr2Px8kUd+ZMX39AVmtFaZpZJOF6mlqvDNb2lhdMKEvI6lyxf0pmPL5l17UCezZvsSPVANipPTvMnFU3LL5o6OTe/vGtlW/v26Vl6p8esNjrMJsi5Ev1ud05VauHUsrz8KZ0r4RzpwStfB69MRvOPOCJgXoeRWO0QCfP/sYuSEGgcO34Y2owyE0lR3KIX5sFl6VPBOD8PGU6ExhOUcxdelnoKucnrEqVWMXoTu1aB0iqkUvjgL1NolWJe8vVd4343T2FMNJtp6kz22GzwuAr+lygfRVAs4tVXearCVbxaaS/QwHwLiPsUEKcpMBB3KhjB/45AShbUI6xBZG+hUtEbS8UYVioukbDgvqUjnCJiMdp/jgoMBdzk4wUYFeCCguzKjBHsiuhPJePkZIn7g+ymKW9qWiUoTHJMkoicMQrpyJxelnGeCM3pLQnTnZlXkpszByK/DDJxiFGTZOcy8vxJBdRdxBqJELzk1IFs+XmFRXyFIdGV4NFNvqG9fnV7VvmahxZvseVOLZnS35irUUAAkruqpi8o6L+yK3Df3prBKk/PtMoVUxwaDUQMzcyKutS6BZUtQ02pdQXTJrncfrfC4NQ73Ql+tzkzuq3rhD2rIr2us6oGrLsPrPuqdCXKIJH/MKQcKl+h6AqFomsUivYiZcFehSP4i4jLGiJ5e8hL7lqI/UMkmoUMws0Mp4ookVVVOMknkeaMYOkTgSZXnaGlBOSwtJXsQBLN7CXj0f+czXrF/cYFrd9O3+jdnlw0n9xoswnh7dX8get7Q411dUGFyWWFcC6Tm70OJ8T2tOaGhrR5V89Ie9xaMD3iLY/UBmu2VJd3Fznxu2uPXVZnDJSmLwfXk0jA9aTFCppqKM7+Nb3Yb5i6K7a2dufgFFNGVd7ovs4ZZQObYXfNBIt5+RfgFuyq4UQhKtF06rSYRr13iCQNQXGfBcV9FhRv7IKiMYE/IAcERzh1RBvWYZ3zXU9EpW3wQO7LHTI38R/mkj2r1DbkZo5g2bCylWRdoTPCBw73UrudoJeAb9/wyWhIkk283eO9nFTuLGvuDvffMn9S5cp9PaH2mkkOpYwzafXBsmjp+u2+SG9ZyfSKkIakDj8yOo1aZ6rbFNl8cO3lz2yabEhIdujMDlPQ40vzHXl8xq7uUErIrzAL+7QP7HKHdBkKwD3u1RFPxWSsdpWQ3VlC8qoSEuFLiHeUEGcpOYa/hDu9MLVaWDRWWDRWWNyxYdFYYeJQKrOvTl0SdEl0GeTX3Y4m2OqSg7pWaQsJSoI7VVxw5yf403jyNXEL5tns417FBwITb4yL+DvkxkQLuYmv3zdr4JoZaXnzbpjbtisit3iITykfqN5aUwEeBB5V6ZsSqQs6mQOtb53eumt43ppjl9XXVnNqlkWcrQXfmbclUrNzPvhSdS6xVi9Yax9EtRAqQI9HMsKFFYUrCnkz2U1mL7l9NPsyyfUwk1grk5gxU4hv4AtfHq4J3RfiyKODw2S3FUhE55OIPiaU1QLTACch9vP5Mp/bIblewh2X4FMSLJEkht8MNDk+6NMN6Tid8oNEwcF6xdi2chULanl/DFFng2rxZlrm901wK+v5zsdZg4WCQeX8vqDzbDypbqg9MtgY1sjVMp7j5erC6SsjKx5cVVq28p6BJTf3ZT3Ab1w/ZXZ5MiRrQV/zhunZ1gSrXOc0ac16jdrpMJdvGtm05uiltTWrb+8277wpu2V+EclEUse+4nZLN8C9wGDcZiAbUNh4LjFquVi0conhzCU6k4v8YV9ORurI2KmIidyFpqrOFNYnBM7kNHhbDA0kMT2TRx4ihE7kf0r3WP6J8TSAXuatdN2yiWkXhHkW3QU7SLjdEqlCJrcmpbtSC7y6FxRqpdSkf0EBoQkSeMV2g4GEmu3+hmVN/qoUjYKX6s12nVSpVjry20vnyY0J5hTvNx/C3ZKEPI7hrd4Uc4JR3jvniunpWr3G7CL/79Sk0Rv5q/jnUTmaiuaiUxGrKaue7LJ6BSy53msw45b6/IqRsS+ICSrE/QV8+gnSVCFvAxnR6k24pc0l0efw+XI58R6DYK/jES2IrHy5yyXPz5IQG0cKiJG7yVd0ew1wWHdGakQNnKrPkfPFTX/QdL5ntfYV8++XNWR4q35f3DTr9942RC+ZFcIV88xrNPSH8k8S49oh2yL5lhEqDSdD8BNiH8TqYGNI/gUrB4IyiGc2uz2Jt0544FcEl9eCQuGT7mxfng0XBMYvp+WcuSAQDOp4scRfZdZf6k/M690xtWjAZbJXFn5YPdSRXXDJAyuX7ZuXafDlenPDeamelILZl7ak13uwwWgcHZ3fm1Mfts+fldsQtnfObX/fm+5QXraueX65i1/j96TMCE/d0Jnptpmyk/zZnIrzTemZXD4UzU2N9BT4yovznc6WzCl9gdTeqtZNXVlKhW/009kLvcWNaT0LPEUNZ+eUVnAKZ1Z6mrWy2p1TTvx7H2Rx98CVOQ9tPFRRgDPOPUASHXvCkyXxSRNclu1J9KGL8PhFePIihA01aVPR5y1w12eAK8qRrKaUOmeLED6Fe4vx+3l6MS45/6GDcDWRX+SRSmEhjaL3KEz0muvIbswp31IDReFGlV2K669vnLm5xedk/szpW+fUpHRHz17NaiZef5sbpyy4qp9EysvHvsLt0jCyIh+65kiFv82/ws/bxFzOJtpAKJsFFpzXJnq6TTSa7Ri3Eu7SrNRSVvEoq9hqZSa1gpmeUHkicCT5E7dDTkOjYJ/XzoTEaCheWS7+RMZMLrvEGcELcfmFBjBnTi4NEYybgL+MPdvAOaUZ6SUA8czjcjjzVhQRniKtEJ4iXfwxDZs5Iv+cTWWoE6YrzvXiT42+NS/nt+0vzkJ6Cq5Q09AHEZfJoBaf0QYM5NYq6CCfQx247tvPN+k94ITnoB+Me2dSkg1kUlIefdYiPHURHrgITqqCyHxkGrk/nFYeFIedkC99ckE+JRgkeAx/AVvEgGXx5iZInWQRbWVTeV1WcWNWy7hzwx3dxOfCJeLzGmMJe4BFfF34Q5Xvc/jv2gFWugPsNDm1Sk/RjWBWWDJrsktW15KAb/eZ5bbM6uySNeP7QmZKtNvcBnnLdY3FPTU5hqz25vqUGesaPed2iL/kgh3y7Rq4iVIreV6pVqyPtiWEK9NyazLMsHVaWASBM5iHboro6RkkH2IwufAsfcfTapLqJ6kNBhZThIe7E57r4i+OiGGFBJWIKqspw5nSyExPYv6554SG86z9HwQX6/8uuIwb8Yet/5vgcp6hwEB9JLaQXP4tsJAZBdFDkcSKdJxmwulGHNDigAYHFDggxxk8TudwkpiiJokGSxJzriQx50oSDZZEUq2ksAqrLOR+yELMZSFZnYXcLVmIzSxPcirydOOIHrUOwWlykr/Q1Df5Ie8Xb45Ifi+ajCX6YDL2whOufRNvh1gCy79VuvqxVSvuX15YsvrR1cBFj7vKl7Q1Lq7xuSqWtDUsqfHivy4/uru5atuhVcBNwFsad84rKZi7s7VpZ39JwZyd5M5w9Cb+VbANuTPcQe4MfYUq0UtUopeoWPRRiatXCZcgK70pFG4PhWc89P7woneFjYa277wrvNhN4UV85LtvCn8wJ62mMpIywVksVpdJnt7S2p41bw+5KcwXbgrrgjWbqst7ihLw++ue2lVvSC7wj5azWCh5H3yG58F7NmaUp1tbLjuwtvbSwTJzenXu6G2d3WWDW8RoyT0oPKUYODQ0CQf0oon0omX0zFR60YZ6YiqT+MsQCHmI2AwlgAVTI8pQU0Bv9TZayR4SghcOn2DPpyaagy74O0wi4x7kZEqFwu5OsTpzJpX6L9w0qZWlJW6tL8WtkfCYn2dLMiqVSoUlu6XobOzb22ZXYU1QzytUKqXORVbcPnaGexFW3IhejGjCzRXNbc3bmw80Syc8DPxcfAgo7JhKcqtsvuAhofBwEL8Z8dAngsKzQBJcxAeCJF0nO8j1JP5ceCCvIg90NBHhV05QDMB4FZoDGk6T/cci1YfGacY+45CRpw/+3iBP/Zps71HXGn/kJz7w6yW/QZrwwO/cdf2/+sCPezF/zs6pOTNqc2wqCXmgF6qYXpxRk+cKRqZF2yPB9I7NHSkNpelWOc/zcpVMmVzYGM6IpFvTIh3RzkgQ62qXwvm2Oy0pHnOCQe7yukz+wtRAQZonOVQ+vWxSf2OmxmQ1aPQ2g9FpkNucNrM/JzE4Kc2bnFHWRc6Fb+zv3DLJY6gUzT6Ujoz+LNHmWeK5yBLPRZYYxbJEr8wiTqixa7PO+Bvc2jP2hly4px6W0yB0krhdvngnffIEfcwgufjNzvm3RDZ2a8gtUxi86dn2usGIe5veRJ76bWVpx7vkOZZJ/25RvT0l0aKQKqWSWe5kg04pS21ePZXT0bud19jj9tfo/dCoqneuUqWU6hxk3TeRZw78U3CF+0HEA9c1dZB4UJB4UFBBsgYhrwgahAQCf/kE3Wke0Soe0SrAXwh7kwhiFg/brB7RRyEZ/DKiNGc1BtVSZyOkGdJzDx7I/mSZxbhLXfTBw7mcWYjUhUXnHkHcITe5rXa3UdZ6i3Ahk1voTaI93JBTvrlWbvHAzjUpx69v66NTyxZeNY9LZrvz7Gdtc6tTu6PcWlZD7JMMGcBmsE8m+stR5B+D2EzSNo+CfKZ6cBIVSdgmrtMqsuVcMiewSWQjtEeKQBTBNdKIgwacJsXJaVAxJRmnJGMfkRU+nOLDXqHWi1O8OKjH63zYR264lUZrg88LuxZK70WU4Io+8rSDlMiZ8JHxNXCgL63Rp05oVNMAKPy+F14o1CtcB0P0B5OrIbU7lEMh4e9Fxn/Bdu4CaTfbi8ziH4psxhzPjZ6UaBPSkpLSnDrJ6IsSKflVkN3tNysloxL+a05l9rnsSUY5f7dEqdLIv3lYrVPwEoVOxc/QmJQ8pOscfCjPJmg03N+UcOPOKdTE2ulg7WawdhjtPopyITwZybMr4ofZxAMnZ2MHrO8J8qzage2ir9lYlQ0ryeozSFZPjilDuNiPC9VY7SXJl5ekXOrcnPRGv9robjSOJ1glFUYTpo9mECQHvcQY1B6hVJuFul6Q54lZAoHCIozhkyasZsEoNptMjvlqhTnoSfJb1ZLfvS5RW5MT3alGrMSO0X8rsDnodfstKsnJUxKV0eNyp5o45eiXmTqzRsrL1XI8f/R2IF6qMevwEfygzqyV8DKVfHQYt8nIbyDVFv3oHOKNkFFsAfukoI6jyAVrnUQ8yYXTXdgh3Fo4cEBXqOOCSpxAQnxpAnYWE8M5safRqTI3qpolbahZTOkrwBVC1AmIM/h4utQicyAQxIECcY043yw8FLBZ5Fz+BlluXoLXyMm2KA386DMKQ0pSUrJFKcWY/0JmTPYmphhlo4cNRqnGosMlEpOKn2116KS8Qq89m829ZlZLIe6YIDc6NvZvvJe/WcgbXcPIMsJtPqJK8kPWq29AFScrTpLAmXfuoRHzROMFZbxX6UzzeNMcSqUjzetJcyovLPNeb6ZLrXZlepOzCGedTfPRCp8vCxwwIYt4Hh59l1dJn4Y7RsWwQYrC4dwcO90HRVhMjx6SaC1uq9Nnksi4XonWnGSFICyRfqrVKyRyrVkr26zVK3m5xqL9XwljE2IKZW5kc3RyZWFtCmVuZG9iagoxIDAgb2JqCjw8L1R5cGUvQ2F0YWxvZy9QYWdlcyAzIDAgUi9NZXRhZGF0YSAzMCAwIFI+PgplbmRvYmoKMzAgMCBvYmoKPDwvVHlwZS9NZXRhZGF0YS9TdWJ0eXBlL1hNTC9MZW5ndGggMzE4OT4+c3RyZWFtCjw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+DQo8eDp4bXBtZXRhIHg6eG1wdGs9IlRhbGxDb21wb25lbnRzIFBERk9iamVjdHMgMS4wIiB4bWxuczp4PSJhZG9iZTpuczptZXRhLyI+DQogIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+DQogICAgPHJkZjpEZXNjcmlwdGlvbiB4bWxuczpwZGY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGRmLzEuMy8iIHJkZjphYm91dD0iIj4NCiAgICAgIDxwZGY6UHJvZHVjZXI+UERGS2l0Lk5FVCAxMi4zLjU2My4wIERNVjEwPC9wZGY6UHJvZHVjZXI+DQogICAgICA8cGRmOlBERlZlcnNpb24+MS41PC9wZGY6UERGVmVyc2lvbj4NCiAgICA8L3JkZjpEZXNjcmlwdGlvbj4NCiAgICA8cmRmOkRlc2NyaXB0aW9uIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgcmRmOmFib3V0PSIiPg0KICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMjUtMDgtMTlUMTQ6MTg6NDAtMDc6MDA8L3htcDpDcmVhdGVEYXRlPg0KICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMjUtMDgtMTlUMTQ6MTg6NDAtMDc6MDA8L3htcDpNb2RpZnlEYXRlPg0KICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAyNS0wOC0xOVQxNDoxODo0MC0wNzowMDwveG1wOk1ldGFkYXRhRGF0ZT4NCiAgICA8L3JkZjpEZXNjcmlwdGlvbj4NCiAgICA8cmRmOkRlc2NyaXB0aW9uIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgcmRmOmFib3V0PSIiPg0KICAgICAgPGRjOmNyZWF0b3I+DQogICAgICAgIDxyZGY6U2VxIC8+DQogICAgICA8L2RjOmNyZWF0b3I+DQogICAgICA8ZGM6dGl0bGU+DQogICAgICAgIDxyZGY6QWx0Pg0KICAgICAgICAgIDxyZGY6bGkgeG1sOmxhbmc9IngtZGVmYXVsdCI+V29ybGRfV2lkZV9Db3JwX1dlYl9Gb3JtPC9yZGY6bGk+DQogICAgICAgIDwvcmRmOkFsdD4NCiAgICAgIDwvZGM6dGl0bGU+DQogICAgICA8ZGM6Zm9ybWF0PmFwcGxpY2F0aW9uL3BkZjwvZGM6Zm9ybWF0Pg0KICAgIDwvcmRmOkRlc2NyaXB0aW9uPg0KICA8L3JkZjpSREY+DQo8L3g6eG1wbWV0YT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/PgplbmRzdHJlYW0KZW5kb2JqCjM2IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGgxIDIxNzA0L0xlbmd0aCAxNDAzNT4+c3RyZWFtCnicpXwJfBTV/fh7b2Z2dmev2U32zGZ3NptsIBuuJBACkUyAgBruI2YxKUFAbjmCigoSFAEjCtp6Uat444FsDiAcllRRK0qhxdqKB7SiojVCW4oXyf6/7+3Osmnt79PP57+b73vfee877/yeb2aDMELIgJoQh+T5c2fNWf5p//ug5DGAIfOhwF6sPwv4ewC5i5fOnoU4Xzvg3wE0LZm1apmw1fA4QngVXCuzb1qpvLjhoxvg+hGEdDOWrZi77N5gVyVC4gWEjF/MW3zL9Yu+8PAIZXyE0NCX5y9ZuWrdINOzCI3bBPevvn7ZvCVvHzwpIDQeaMTfsLHpPv2T6Y6mm2day/+lz9Kjf//8sKt7noz0k9ksMLsD0VQc0TMBjZKh/odbZZQsv/wJJPPFSYA5EZgTD6Q6uNZvR0g6jpAJyqwlAKdhzNC5I4aQ04SQG+i9boSydiDk+wVC2XCP/zBCwXEIhVYilAfzy4c5912NUATm1q8ToQHvIlQyGpa1kM6djShAdqNydASJiCAZDUBRGMEh4WskICLsRx4Ar/A88vBhBH3FvwA4S/OeBfGztJ7m5CtopyMJCO1AO/ECtBMdQq/h83DXLrQP5vZb5EKjYU9Xo1+gjUiHZkDJ3WgKfAUo/wX2xNuh9yeBB55ER4H2GnQ72o+c2B3/Eq1Fd3En4K67kBnloEo0CS1F9+Jx8RtRHTrF34lK0Th0A1qGm+K18fviD8SfQc+ifdxv493IiLxoNnyPxr8R/hz/CPWDOx5Ej6JT+AHDbqRCL01A+Su0Am3j6nkcnxf/AUYQRDfDGHg0Hh3FnSQCrc9FX2A3Xs2Nglaejsfih4HKh+rRfLQN7ceD8VgSFOri4+NHkRP6WAWtPopa0R74dqBX0UlsEs7Hn4mfRx5UiK6C+bSj3+FOrqd7XU8FrJgAq9QXlUHNUvRr9BY6jkP4N2SpYBKKBFW4Nf4eykSD0HQY7fNw5+f4W3I7fNdyb/Jj4iORBdblfrra6A30F+zFA/BEXEP6kqXkcW4F0kOPg+A7By2A9X4EWv8ER/AeYiLHuKf5l/gfddk9p+MW2JEw+iX6FfoNNsNMFdyI78Dv40/JKDKT/JL8lfsF/wL/B3EWzPpnaAm6F72EvsV2PBRPxtfi+Xg13ojvx4/io/g4PksqyTSyiJzj5nPLuVf5kfCdyjfydwobhHt0Z3tqew73/L7n23hRfAOaDPywDkb/IHocZrYPHUMfwPcU+isWsBFb4KvgIJ6Ob4Pv7fhe/BTegV/A7dDLcfxX/CX+B/4X/pEA6xIdySJBkgPfEFlBbia/II+RY/A9Tr4m33MuLoeLcIO5ci7KLYVRbeS2wnc39xfeyx/j47DORcJDwhPCDuEl4TXhvM4k3qFH+ncvPd1d0P1JD+rZ1PNQT2tPe/wvyAF76IVVCIDUTEaz4LsQ9vsh4Lhd6AQ2wdp5cQEegcfByszEC/FyvApWcj3ehp9lY38FH4RV+hM+B2M2Ex8bc38ymIwkE+H7MzKXLCdbyQOknbxPfuBEzshZOQdXwI3l6rm53EruFu4hLsa9y33M/ZW7yF2Cb5yX+ACfw4f5CD+Wn8nfyD/Of8F/IdQJ7wif6STdEt0GXYfu7+IQcYQ4SZws1otbxD3ie/oG4M7X0W60N10p4dPcOq6K243uI8W8h/yO/A74eSaaw40nwKlkB95E1uB2kius0g0nw/EEdJ4Pw1q/SZ4gF8lwbjyuxlPRQjIo0Zouk38RsnL+ddTFH4S5/Q5aXqUz4dvJOZ0JtWJEyqDPN7iBfIR7B53kTmGRfxJ9yEvYhbvI89wk4IJX+RFCLQpyj6FXuOV4DdpNqkAz/qjfDHw8Ab8IemEaLsLfcXHEkQnARaXcp+hOtIj8GXWBHG9CD+M5/Dx0HyrGq9EX6DmQir7CDboCnQO/TRbwzSQDtyPCvwCzK8O5mBMy0Xpcz23TnSMfoBvRMV5Cn3Avw+iPkVe48fx5YQqeDxKwBm1Ay+Pr0C1CLf8HPA9xuAbl8adBu63mivgg5GtBq9SBTtsD0r0f9EAlNx5K3MA544AvpoOG2AbfR0BP8MBBC0DGrwEt9jvUrptGOtA8wYJB64A2fqdnCpoRfw49Gp+Hbog/gPqBPtgYXw0t7kCfoS1oB76r5za0DPlBcj7B44Qx5JgwJt6PNJMPyFTyUO/9hdXOw270FXxfgYsRwgHUzP8JTUUV8c3xPwJ39wEN+yi6Dl2NzsAsv4EeruQ6UXHPBNISH8Mtg/meQpPjz8cDWELz44vRRHQQPSsKaJYYgT2O4T/AfG9Dc8mU+Epubs8CWIctsAoqrNaNoH/u5pfzd/LfI1RpQtO4QvolOSgbBUA6C0CiAlxBqy470MH1aQu7A8cPcn3RaQDC9W2NZAf2cflcduvwgNrBhdrsjiJrZT9OASs2gKUKpEsBdgEcAuDRTM4P5TKkawGaAHYBHAI4DqBDCFJaqwAsBXgC4DSt4bI5X6sSkCvzOQ/c6wEFY+Vc6BxAHICDcbqgVxeaCDATYAvAEwA6RkdLlgKsBTgEcJ7VqJyr9YFiGLur9R6WtS1cXMQuZyUu6+rZZds10UQ+fnIiH31VgmxYgmxQSaK4/8hEnl+YyO15RU00l8xFnZVOzgmTdMLAl0GKyWFkxRhYbzvnQDEAwumSJSpnb8sNFz1xiOMR5giHwVQE4p0cbjXbiiolEifnkB3chG9IV6KGdLVZbEVPVF5N/op2ARwC4Mhf4fsX8he0lpymaw5pBcATAIcAjgGcA9CR0/A9Bd9PyCfISj5GAwAqAGYCPAFwCOAcgEg+hlQmH1EvhaUUrwAg5CNIZfIhTOtDSK3kJGAnyUkY2onW0rKifQyJDEgigbwk4spKInZnUQf5Q+v3fYGjwrDTwFEHuBw0AhVzOa15g4D93K3lCwId5NM2JRLYXjmQvIdiAARG8h70/B5SACYBNAAsA9AB9j5g76MmgK0A2wFiAMBlkMoACjkC8C7A+2gggAowCUBPjrdCNx3kWGt4ZKDSCUr3LXCAAuQo+S3L3yVvsvwd8gbL34bcD/kR8marP4AqjVCP4B4ZchnyAVAvkN+05doD8UobOQRrF4B0AEAFwESAmQBbAHTkEMlpnROwQyMH0BE99Qdb0Zcsfw49pUfqwoAaHgUMqNAkPOwKwCB5QnkiTNTwQ4/CJU3C9z0AGE3C6zcDRpPwresAo0l48U2A0SQ8ZyFgNAnPmAkYTcITpwEGSQd5fG9ufqB04iKsVFrJzbBKN8Mq3QyrdDPiwabDF33P07H9srWgAFZsmxrpWxBo2o+bDuKmKbjpKdw0FzfdjpvW4aZy3PQz3BTBTT7c5MdNKm46gIfCUjRhtb3XZZnqxk1HcNNO3NSIm8K4KQ835eImBZeqHSTYelUxy6pY1lZJhQ7yK0aA9rGSIKxoEHg+CDrhEKTHAOLsSgUiJSdB7PHTPKetoCJx3X9Y0VIQn9fhxtdhG15HpwB42KDXgY1eh0ZehwaskFYAzAToBDgHEAfQAXUODHwLS62QDgCoAJgJsBbgHICODeccAEFLk0PcxQZGBz0gOfCJADx5Hb7UcQqSoJot++SIfCW3xYetfjzRH/eTUuR0gqmw2/S2Dmze8635u2/NyFBpIPeRLVR1g7uSyLe0fg+qGz/SGj4QqHTgh5GfB87DZSiM8yAfihrZ9WDk09O8BPnIS5AXtfpq4DZra7gwsB9b6F17At/7zgS+9HUQQM/6DgT+pHTwuDXwRyh5aU/gPd/dgbcHdOih5GC4A0O2X2Gk+3xDAzuPMNJ1ULGtNXA7zfYE1vjGBhb5WMXcRMXPGuFKtQamhGcEroT2RvuuC6iN0OaeQIXvZ4HyBNVges+ewEAYQiSBFsBg+/pYpyE/a3B6aQeerxaKD4m14kTwsorEQjEoBsRsMUvM1Nv1st6iN+klvV6v0/N6An5lZkf8tBqhEWGmjgWGOp6mPMNlQlOSCCEJ1hMwxbEMrppUTx2Jq2Ods1H1dUrs4tRQB5Ymz4gJoZE4Zq9G1dNGxoZGqjvE+JRYaaQ6Jk66trYF4/uiUBojmzowmlbbgeO06K6smH1U7T6Ese2ue7No3ueue6NR5HbeVOGusI+wlY0Z/RNJQzKNXP64e+HZsYeqp9bGXsyOxoooEs+OVsd+PlWpq90Hjvr5qtH78N9pFq3dx43A/6iaQsu5EaOj0eoOXMPokIL/DnTAMX9ndHowzpQOKXp/gm5bgi4P7ge6XJoBncGA8hhdnsHA6HhM6Voac6tGt+TmMhqXghoZTaNLSac5kgc0eXmMxtmEjjCaI84mShMbwUh8PiDx+xgJBu+fkfiwl5HUXCYZkCS5O0VyN+uJw5dpfAka82mNxnwaaCL/62fuyEgEtw2Pzq6rmhuqaghVzQVoiN1z03x3rOk6RWmZHaUVSowLN1w3ez7NZ82NRUNzR8dmh0YrLcPrfqK6jlYPD41uQXVV02pb6tS5o1uHq8OrQrNGR9vGTiop7dXX3am+Sib9RGOTaGMltK+xpT9RXUqrx9K+SmlfpbSvsepY1hdiPD6ptkWPRkZH1SXyNmKUgF8bsoLRkU552QjGvMOD7tuz9oPHsgMZI9GYKTQyZgagVf0q+1XSKpApWmWBYmuyyn378GDWfrwjWSVDsS00EkVW3th4I3JXLRid+GuEDxStvJEueCKNNP63D9RVxdRZoxtXIlQdK5haHauYPKO2RRShtIFOKTZMKzMaqzrinYnC/lA4jBZyXIqQlpXTMoMhSfif+39jMh9FpaCJHGjDqh+vRI1RLuavnkZAFUybAXOtm1G7H/wpaiIaozDBRgiWGrU2ksOORFDiGtE5a7DyxiSWXIuVyTxxJ9zSqC1J6kMXK5JasZWsWbacEarB2AGHAM42EtHIdoLP6MQO8qiagQT+DIckkT+DkUevE84Q7iAEjgb8KO6P3BH5Ynl3+QT5Qvn47nJUAbh8CZJBA4O2oC0PEtCX6JLCdV5SBfQjUvhOqjArcQdZSJZAX4WqZxlZxpHxeDwhOISIV1gGBB5+2b3uyAT5TL38ORowvmvQQLQc12cMDjoqSV/csXs3DZEImh7/grcJnUhG2fjjFkJGTatVJa+fFzL9ZrPL0BE/2261kukUUT1mM2A2ZKIlyGkyQWqiZWgArMNRSI6iiq4K6CqrRfefLV2AlnS0pc/bzWaGfKN6jEYdbVKmJUg2mWhKy1JNXm5TncDrNpJNxk3Wty2CQTS6SVXGOMfVnlFZ0zLqHHWeKVmLxEXG2RmLHYs8DVm3kJt1NxlvtW7UPSI+JL/tPkne171v/NDqTQ2pUo5fQCZkwiqqQa74P5ARGZP4d8iMzFhVbTWuRoMaDJUMNGBkkA3EUCnBTRqhIX42Qbi3xrA1YDOZTB3gc9XYLEZjAtGbzYC01dgaEbC5aoKWFAgRCdJIkT5JihKke2rQVv9b91CmgKnXR7ogpWj9coYmlwLXL0f1MTIqpk6qbdcpHtnXET/fShTjr+OnkRPADmAFGEo/GCAajWbI9iHFRU6n3SETXSgnP5whO4uLhtjkcChH1E1fdGL7Ta0rRy488eR7t9y/74XVq1944fbVV9eTE5jHV7w8s60nfrKnp+f1nY/sxb/qefjceTwfL/xmwQbKi6eAkX4EHpLQ121SamYaImmrgTRESsw1NWk1WMOpZlvJIn4t2UIe1fMv89iAdALhDAI2EXxEYqsn0X1AmEbA4Fa0yzIwXkf8K9XG2NHH2NHC2BFWQ/VQZtM4inGX1ySoZmuJQNuy0LYErAiqQASPcT8ux3ehhLgsT6w4+8BFQiorXGXYVkZXHtVHcKIyGLLpdOLgIUNKi8mP7ZUnpj381wEr+dtGrA68MvbITBhlOUK8COvix98m5cFgk83ujAzddDMVB5uNId+oBlkGzJ8p+KmYuSiB309r/T4L1PhNdPz+DnJANRHJ5YJ43UaIErDZywa8d5SmR9EAyh6RCpoeLqICSFIdmux2wjpUDVYb0fo5rRrtGWS6P5OW0bZboWkq7kYjmQ7I1ypby5/qjcok7Y/2xjpTxw4XhusOCId0B8S39G/7xKtMUdM0yyLTHMut9lsz7rYftH/m/SzrvNd0yLg3g/glWa/THfF5M30+r97n5TDRe32c2S93kGfaJtowuN/u3XSciA6sDROT1EtYpTRhlVLCaq6RGl0ngCGpwOIDZB1SkIyHqibb7goykywlawlP9pNc8MS3tDARq7/QBVtdLl9IyBZo3Yqu7vozNjvdbUg2WvpHLGvkw3ABe58UONWQBaFDtuyXdb+On0ciiJkecgOAJm1Do6ge16+IRvMcwXApMMiQIYNLQMx0Yv4QKoOOTGAc+OPFS6XElff0tnM7Hr3tjsfwvozvfn/i4pXPv/ZUnX/nzsry2Z23H/7s+kU/f6w549gHX+2sffHgM5tmDWIOc038c94JvBXBrcmtNnrcKt0xtw9hyuIRE1zgviHJbDVZ/ZLU1+H38f6+PqGvOWQ2uT0Y2RWZCo0ihum+U/LwAKpzjw6gX2Qvq6iQu+Qu2PGuN+U37WXy4UgRBbrjAwWz01xl3mDmq2zX2G7K4qY4F8sLM+c4bzTfkrnB3Jx5d9azZsloMlt4EUN/mG6tCgM/gOkjADMe3G4yOXj3fvIM8pD5qgFGJ8DwzPZeO21P22l7mlq2N85UlipEcVPJUJrEXjeJaTeJaTeJjWGmy8MYheUwgVlf2EvvD2/t5+7AQ1s9J/B+CN4QLJ4xpam3FnbgB5LsEuliDJNUxhci9Smd3H2GCkaXzLgnwTwphmkVFA7kDRgjStUHXh7NKHVS1ct4QixNoRp7UP4QaYpCOeGa9sCDi9buempN8bhMu7GxY8PCBZsz24NfvbLqyKLr59yxtefs+7+J4zvdj26M3bH6yczHyao1s+9Yv17Z/da81jkzH+vvf/W+zp5/fU5tvZc+cxP2g542438eRKb4D4kla68x65LKWtC0tk5DDCk9riGCpsd1GmJIaXYNEfVJYr2GiJql0+tTNEkzoNcQQUN0GmLQkKTNUEtr7LWm+aZtphdMb5uEcdw48y94zg4KBJl0nChIRk4Ey2M2H+H4TI7jOTMiJjMvcgfIAaQHH227KiGeBxJ0ROI7yPV7BUFSswMlkmZSpIR/wpBvmKMideBS1SyqOaESsSk4WNxqJVS+jObMEkRkohCO0JvpPYCc2UPvIbstHXgzY5uvqR2nFuUC1dDl8ucyMyjg710st5VRXikr29g/woOesVqtYGKYw2uOf9JqLwOt/Z5qLC7jcvqVcXx2djltIgpMBDRqpkk1lpmaJpWZ1HCZKccHeb8yZpmi+CfiKRQBX3IwLrYVO0I2zobJQ93rya9+/uab7T2D8cxnuT2Xrn6250lQkQ92L0o816W+YVB4DuzX620Z2u7bNSTDlNxHu4ZkmJKbZQdkHxW/hGqCwBvWy0wXCPsskt/h8NmpMTNaed7vM1swEt1gyJmjyRCmxqiZoWqIihfIVvdhUD1U85TYmTm0srTae0t2c/ZDGc9nvG563/Rhlt6Q4bYUeLkMyWHPyDhisWZaMjItVjNoHzWDdq1atluIxWJVHTg5jL1WHp+gmgmMjmqjA7LNlJfKa+UtMi//z5rFzTSLGyO37CZuTbO4tyr2g3gwsuIHgXJoq2X3T2mYQG8N00vH1AOvUJvE1qDeBgAq+cxGff+IAAyD0g1Tu2GgMNC4H+wRx7QN1TfL64EbEvufrnRA02QEHUEOtA1yZIrgDoanv+p4dPEd7Ts3X7O5zwv3kQ+6905cf38n1q+898Jvu3GT3HzP4ae2tU6scJK/v9xzU13Pxd+/dX/raRZDjAc+cYAtykYFKWsUsOIAnok5nNXHr5qx2QxOR5aQ4880S36M8mTqjrB4Qva7ZLrxLmaLXCyecCWd/6PvHZXf0Bigvks+XE8ZoN8iDx4tqo7RntHKDPs0ZRE3R5yjX2ifo6zU3+i7S7/B977+PadNVOgO5CdEUzc9RF2eLIoFWQUd1iQzgYFl4RPUW+ugVkgbJKb2AO3O67X7eWm7n5e2+3mNMtt9GSMZVAjM7fxe6nfKWwtBdwxt82si49fUox+02QHWjh+XqeYK10zXUtdaF++SkwSwGkzdWWpcTtqUy0nH7OoguW2RVHiQsD/p3NKVMEbMCMGCpVhjH3VT2vOVkBLs0HiDNkDtURSL4XwWA+hEan7s1DsJ5SCbXEqNEc5MYxvuxzZ34VWLaiqnX0cqD85r7775+Pq/9Jz51d1nd37cXTrxvgkrnnnqtltf5KdaFg4cP3DENx/Nbuj59g/NXbfjarwav/CbHa9d+rj+xWjH44/s2pXQMbPAJjmF52Etl6mWw2bMwx/R8wZQ3FRFDCSYN5jMjRxH6BJPZH4cR7xWfaPhb2gicNhMwlVAthSvhUDFY0mKEoTT9cvLx1/omiBfpD68DCtD/bsyW1nCmQPJoLGwDnE6MTTEbi+dxe3e3NNVPcS6j7vjn3fzP+zc/GCPvefHjg934q/wW4/RqH4q8LkH+NyFQmgg+XmC09tNKMvfnxoE8NvJ9P797UG/Tujjt5v91HSy0PnCHhY5R6zAGUzLWTVHmyKs0urmaCW1QJxGxaWEhMt1mCi5g7XoYELiuBwh9w6/qYfeVVaWisL3soHotIHoEgM5w6Jxq2awkv3TMkAuqTm0kHZL73QwXetgM708P60z6AsPSA5AAyqn4wc7cV/nVc6rwp+bvhwoGAbiNWgNXs2v1C83rjDdaL7VdQ9qxpv5Dfp1xvWmDeZ7Xe/a3sywm5DfjUzQ0/b+OG0xe0miP00S/Zok7qnxNx4yYEOlncxDkTTqSBp1JE1uI41WVQG5tWJkla3E2oHvby9ya8Lq1oTVrYXm7sYYh7kOMq8tVyPK1YhytVA/t9GhBZiKQ3UQx9ZBb2m6nSl0FtJfSOn3lAtpL6tnS0n9gTTBzYmfbvUpXhDbVkUZQLN+Cniup1v6KkyOE3q+fsVytDwaxeHw4JJkhKF5kAhKMjLTZDhdoPHCZYs/P9T51aIlG+/tufjBBz0X779uw6L5d919/bxNw67aOnXdjp13rH2ey+r7yMLtJ09tv/7hvoWHNx2MI4w7t/wGT5u//s6ZszeuvxQfv3Xic013vLgjdaZE5cSPCkgoyYPGANjGPBtYxouMyaiJZHrZTYP1PpTL3DbGZjYWs9vctsKIsY/faglYJlo4iyUTTcKYBTZmGSJjTA11Dg0R6dodjtQXMY1XxJYPOJCKhEztx8dvpKLhtEFcdjbUAuZt2Jhk/Zdee/f1b10NSO9IHTvMO86phq51XhO6nlvsXOKdF7rVu8a/2XuPf5vzBe9B71fOz5WLSsYVzsedO53csL5zdKSPf6JlJvVKfLQTfGJSwhq1024DlflpnBxI4+SAxskUx2XImEZnjF9M0RnT6IwQDtt6uypbC6mt2w22TuPpPI2n8zSezmu0pXjaptqIbWukF0+DCUryc5KbUw7LZRN0AOWDZxKKn24LKjpFi5KX4/poMhwaQQaX5FPLAzkCFrbb2DlVGDNGdTAOXrbTuXrW1DWThuAhB5bsuYTFN7d03Xbr3596+SR559mVq1pfWL3mSTxVvvWGcWv/vMzkrlmE9X8+heVtPZ/2/KPni562Vw5xJb/cc/ixzWB+CNoHBmgDH2bntUNVhReQTjQQXTnPlWMdL5FycD4RoedNT+qffMTNpJbaEYiJ2d4zQc0YXOzgAPYdPXqUix49eun5o0cRiXcjJEQh1hKRhcyuzAYP+Lu044tLKdyQVi6k4byGp4VQOj4VS5lMv07e8kNio4FMZzT+OnnvBa2QmLRCfLlQJ2kRmFM7mtNceKMWCEqSFu1piMGiDUMrERMle2uwxSqz4Ocf7UnkOybbhBqwKLM9zI4ILB0gD5Tn6ecbGuRN3Fb5beFNXad8XjbqhSiuIZPk+caY/E/TP83/tBh4E2/mLZxRMgg8bzJb9DpRNAGu15lEjBB0o1rZsZ8imjKhinAcLXPQMk7hTZlwl8EvCHq/jtN1kGWqAelNX6oEE7IfG0GJGVW7SUFzRW7KJP4Yf4rntvKY78BYNU4ydYqnTNxWEzbRa9kqHhPJWrFJJOLPre//KcEMHgD4cwNDeD1yVxdyV5R7uyrOlMtd8LdR6B+JgJO+sb+b5YxnIOLbKB8+bDl8eKOQyMEXqY4Zp1bH/JNnJGRlRm07b+X04v74eQgVvkto+BXUlf/vnxAuxiEuyGUEuXC+TuRI8e9J7ccvdf/yyQ/w3x8dk+MrFvb/MAYf7BlNZuCH9t187z0J/+v6+BfCTcIJ8N27d88mC7MJTrgmOnqKeladSTEFFZlno2VoZXYTWp+9FW0TXuKeNe/j2s1vmY+jM9n/zLZZ7Nm27GyuQNfHVuBTAmPNNZnXOGo884VF2bfZ77Fv4x61bPPtwM+QHbY/WjJQJvLKmbKXBwb5pLVPGVPrSp8y2Yown5XhN3FZft4gh61Xo7AC+tcbcJEkz7k05eSSEh6yVOMKK3oMEsEuzTV6Ex2z3uOfXcf8QHCTx1O1BJ4gIEkX2UbPZyBKrqcn6eAHr8AuHR/KyQXdY88tLuJdYphqHeLItFO9w7e/dkXP65919fzpl7vwqNc+woXDDxW/9vMXPq1b8vmGp/9KyKBzP/4G3/CHz/D0ltPv9Nv+wFM95+4/0PNl80FqDx8HXTADdIEVZeN+ql0J4FF6X7Yf2NAm+61IT59E9PyXJxEXoZx6KwE6TQMOsCM+g0L9RIPEnsy4WQmVtISX5w1ky9oiyVIyIpcTyh3iCVlhJ+hK8vj8IjOEDEkenf/QzkSqI/5tOzs8pxIlsQP0ev/wOnfqcLy+vJudZyQu6y8fobKHV6NuUYdwWaJepxf0vJ7XedxeN9EZJZNkljidw5npzHByuizOFcR2CyRuvS+InZItiCL0fL0APutwfbEtWORyupwQkxALCeUFi5JnqRCwBB/H37804/boysYJt95/9K6eFlx2/7ODqsY/vHjCzp53hf2O7HHX9Rw7/HxPzwuzinYOGVT15XOff1tA35N7CmIO+k63Ef1adegEv14viojj6YZIBr8R6UXKj5myvUScxl2tSIqZSF4zbyApTaide0lalGb4n1f1h3aDIVWiSzyrSC6vafi1SY5NLvB4tsKMcS+cuby6YFjLZbrIsDyOYBKe4nMvPc5FLv2RWy/s39lT8XKPeSeMCDwy/i6YqwG9rOawuW4RcWq6MNXHFKIYCfEa/z/npxoTzwOTqqPnP2YnDa/7r7M7k4jOqMfw7zPbwX186TMS655EZzVsZ/f1Cb11CJJ1MC8OV7QRbeCchhAxOQMOkEpz0gB+n5IrpOFAKpgSIsIBkiL9MSF2jDSJ76mh60Xo46O2oVewx0htxSWJvN/ARN6nbyIP5SXybH8id3sTj50KzHKJImwVdgkcp4AF24K2oxjiByAVTUKn0Hkk2BUo3Io4IXHESBfXnVz0r7VF/0Zb9IuqnDB/bNGf4t+PponnqLra1iawcfXR5SvKu1PGg549MtWnfYptxbZDr1HrQNd1Uvws18WPQF4y4CCon/OaEyJpTohBQ6waImuIDZC0Yz+1xLLWiq10xSeB9eAQb/cZRbePN2KLQ9RbLGS6yCJZkfneokwjXJE67pGj773J1LQMzjYF5lkbTDjgG5UxyjU1Y6qrIaPB9UvyS26b+Rn5Ga9Jb/ZIC8kCbqFwo2mZucn8nGm3YY+022RymjaYPiWcJWemdal1rZWz4g7yohoeyFa8AYa1FbbgNKy8AVmtRnR5jD4YOnvYq+llq6aXVWuNNdeip1xtycmiz+LTyVD8mxQZyjVGAhjDJmDVEmFrhNWkRsZqctXwEMarqgJFdB/B2ZAhvZLKD/bSXvBVPod2Du7QvHRHQkjVYI0j95iIA2IFuCYW2oAo0QZEO21A1I5kxcR9e2rEQVklh1NsAg5tJO15Z6R+RfXUUPXkGYkz26FRqF1xgXr1K7Ro31Y2QK4/A3+DBjL3fbl22AwWlB0blbDHzEkDmnDbufKW7HOvnOz5dsWXd+/8KLDLs3bGphefWb/wPnyXa+8xnI2llzFZt+vJrEWLXz/x/mt3gM2sjp/l/cCHDrCZB1RXAPkc4NPVC/WG6ca53CJhqWGuUe+gxxgsZgREnUKxbB879bN/IPyQedHLD7IP8wzyVdrHeyt9k+11nim+WfYl3lm+VbpVjovkoltGTmw1u1yTnA3OZU7O6bNulbfLRJb5LJ8kov3kRboO7FiGOSkWurQy7OeDGcAj1HCf/79fIWircanmjvhHTGTN2iMFM41A6f6YaaOG/IKSmBmbvQGqK/LCJTTf64cgLYADzgMQLSTPN5zFKVm7bOKTD0YyauRcUc0tKKGcMFHkRI1RkiygRmpEhUmYm0mbj0legmF8jFXYEaPo8ZeUpuvpSH2EKeozULY8Erm4nJaNT8V5UJGI9Mq7l5cno6LkY3JgieUrNK6QIaRDtkwxyA4fcJAdOeq4n+0v/Gbflz3ncOZHf8QWfOms1HrX7M3dJ8lk09Cau1e/gGtcT7fjAOawCffp+aTne1nZtX8+fnDDqPnPsbOGkT2Tua+AT/yoAH+hNhiNQmahMS9znLEqU2fI9mQXGsOZhaEy45DMq41jMmvEWuN84w/SvxyW/qHC/BGhEfnj8rcWbi8UhwSH9K0oHGMcE6zqOy04re8CcXZwdt+GwqbCk/lng9+EzuXbXE6do4O0tPfxZYhMi8gKGsh0SBPqRMch1Osga1RZ8PmsUlWOzyQ5HcV5xfTJdfrT6n+khYHaUVRujZTndh93YdmluhpcTS6+EMwpmV7IvD2XnbKfi3p47FUHl46qTnoizEq/Aq0Bm0ip6AkxcBg7MO6IX2Ks5gLt9EMaj/6Q7NNU41ppxXkoJ6BxUkDTMYGks+iqCeQesh6znrLGrXzAWmGdCPpTYyurnGCr/jVWxlZWL2Uraw47zPTRESWe0NBySD2RwpXBkkkQCU24zFnLxyePD7rTQ5n65eWs4MxF+uzjTPI04UxFefLFl+Uu6hIWU1cwP3FcQDWOa3CxjR1ch9MPu67fZSwatXLNJrcF3xT78PwNv7/34K3Pzf1w+6+/evS5Nat37Lx11Y5a7+S8ojkzSmP34PKPH8F48yNNlxZ+d2zVS1zB7zsPvfv6m69TPtsExrGc+htIxP9oI1oEzWnI5ZgakEpP0o24lOZxXMaFNJzXcPBEjJoboyE6DREBSTXanWZrutMOD7rTDg+6NbtN+OSmchqi0xARkLSRmlMOz2VcSMN5DVdLawxD6JZPNGw1bDfEDJ2GU4bzBhEZAoZlhibDE8mi04a4QQoYwPyJPOEMOu5AvDPZQkENdztGOkHHSzoxT0D8E/x2PsZ38qd5XSd/nieIV/jjcMXz9CyB8j9PfUwX5XwI6oHTeIkOgc+knMZTdUrZn6eOJ+U6np5hS5Tz+An6sZPc6SaOukPUCyqv6IokYnJ2kEPPUP9reM1OecBR2tTe3s7/7dixHx18+MeTYPvvBL4oZX7ost5ckXIlf4IH/m2vU6Q/sbP/toNprf7Hfu2tEdi2MI+zdGjC8ywZnMgHDkrkOQnPVM1zuEqsQkB4Qjgl8BMhOS9wAWGZ0CTEBR48U4lwefQ9K9YSe/3KUTy45AmEO8FXIggpoPBOIx5p28NCgGy6PYhtD2Lbg9j2ID3dG6TtDSBxLTpIbhKawPfeJLpL4Kt2J71VdvXvH+q43tnOHFeMNiLEfQ52wIkPqxkCp8sgO+QO+VPui4zz3MUMHU8DkRyjueQWGT8iH3efdsfdvKLPtGQ67T5BxDqnWTJbTBZQ1pdPSy1pituiuXiqr8aS61bpnN0qnaOxD8WNmXTuRvrelI2qQCNbBWMOo6CqmylpYyZdCbj+nvr2gEn0LNxIPXnmrhnV4iElcSOGP+MEN111b8mQkpj7vJssc293x9ydbt7NkWKHU9PVTk17OzXF7GT7drHdZkuGmantcf3H9vDJaO0HalkAI2wz+OQudap2GM55+nq+tt0TXOyoN/VJnAFcKJehsFdFJHEWXC7TV1orKrpsZZg6BqNuUZ06m0HSS6LE6eSwTWfJwlbJnoURC/vXUQ0Pm0/fUmCvwricDlvIVpJwJm0bn7rx44YnJ8lSe8GiKxuf58MP76paNr5oTXcj2XDDksoH3u0+CMw5GnzHfOAFM/LgT/Y42DtCGfRYi9kjeqw1l2IeVmEXJY9prO5KfY0uqp+nW6DXl8jD7MOcg91VcrW92lnlrhPqDFPkenu9c4p7ibDEMEdeYl/inOO+GTsMOsF8LTdNmCZda1rMzRXmSotNksvHizawgJm9LH9mWoyQmbL8ck1mbhaz8lmMmcTUC40iO9dJBkX00Rzz1CjC3DTtYR1DmPvG3NPcvJKBIkaiLCrgAh6APpOuozjoVBbOYkEldSwBt2gsZNE4x5IMKSqBw5HJQoNNO4s0WXyGfIxlmMdI37OE1MTkmj2gRip0HaDn5UgLOS6/5Jo4Xd5TgwZ5qXOZfLc1nU/Atay/GKmv78092uuuy+vRcvrGi2GqMNVwnXCdgYeolr3SncEeUqPkI+t0yz/6mbvf+BA7b/vbPad6uva1btzQ2nbXxlaSgfPvu6nnL91H/3YH9mPzu++8+/s33jmSeBd6Y88CPgh8Y0d+/KK60iT3k6+Qq2W+QokpJKD0NYWyixxF2SOzlylbFf0w17Csq11XZ0X115rqXHVZC/WLTAvkJa5FWZ3KicyP3R97T/jPZJ7xn1biijPER+SIYzA/TB7DXy3PkD8z/i27RzbaLBBy+HRU//gsRmTx9GIZTxrLeFIs46vx5B6XsCypUoPUJPEKYxxFTb6z9LlqpOwjuZPXiYMn9jIT3TlJew9bonJgpVsnrcQZxaTYrvGD3ZJ6sSfhB3pq7HkIdWK8FW/HMXwe8wFcgSeCU04VOFP6WGZv97DjCMx4FrOTIEw1EYtnKamTdozZMSW2s8jWExhb6sbp4Qazz+OZA3jhzGXHMBGo0ocvTJlQXULfsVy+Ai3PoLoi+d4ce2KUb+PSGGHjM8MemL/p+MIbT902Y0t/23M3rXrp+ZWNLT0LhFebJ0/eHH/k6Z4f7xk3rPtH7pmjh9/54ztH/kTPQSriZ7kW4IWB3OdtqTPn1CNhDyCVpWxj+qRtUvqjunCvF0cu47lpeCgNz0nDg2m4kjI8q2v4nMycYYarDaNza3Lm5qw23GdYn/tcxkuFr3Fmg8vrdg2sLnzfJWSR6YTIRVhy1+nrDHVSnbHOVGdeqF9oWCgtNC40LTS3h9vzrfnh3PzcvkNyZ0hR45zwnD4rQytzm3J/Lj1meqDPw4UPDnxGesH0dP4zfdrCb4SdfbTHtTkaEtKQXA1hNHRvczQkpCG5GpLdEf9EtfvLZujz80wS71XCDt7YP9tLw6kcTyFlnICnwjPRM9Ozy3PMo7N6Ap6lnlMePuDZ4iGeV0EBOUBUWVSuZlJyGauYyPg4JgjLmD6+6GzLdJawaF222Eow7l+XvTibZPscIk+HwdxG+pJf0mH8XM2gbMn7+hsDXuzN9agZ7pIiensRFSSPO5FS/vaw3zx4FHqnR6F3edjDag8LnWltpSEhreTay++KtdWIuQXQ3m5f2fECXEC7ps0UaL+tYAhtpiDx7hsgB7RNb6sp8LKxBPMLShqKOotIRVFTESmiRxC5iA0q+Xa7ktgG0AQUoSOkyF46SCWp1501Sq6VCaeVTcSqsGCNmv9M9laKhYVqibAt8SBQtdVYc04hXIEmgoL0DEqeDUDkdiFNT4Nui3StmMCcAFa4nJ4QXBZpqETs1fSKruXs/XHqz4Fwswy878uvzIJ/oOb384cgig/bZLucIXO6HLOShQx9xCws9IPEnwmXQUsoC+WEzCZ9XykL98k3SLoIn4UCcjb1JCIy+B2JhB1OFUTWrVuH0jQM9fXrLxdQotTrcfnh/P4QU9IHDcwB0Q6yaNDp8pOEqQlXtFrvvm31qsF5P3/z0YmVQwvun7rm1Rm2mKlxweqFTueArPWHHq5Z8OaaYx/gK3yLVswdfUXInVd01boJY2/pE4hceds895S6KaUhX3aGlFtcubpuxhPXvMzOte8EvXOa/g8a/NA+5KWHQ+CoEyXDWWJlv2qwZ5ZEMnCuPsNpwhlOow5JNh9nRMXOXp6rM82KONM8V2ee20VdTC/zX13Mc3XZ2XEC9VzZebOLOYiulM/qykweLHyX8FldJspTLuqzmim/xF2404VdE7yUTZ3UXfWe95Jl3u3emDfu5enZbMKumDTtaUrYlbYaU56BiSn1MukPbBTDcYgaeYMWVFBEtdHhGdigDBL7uRDtmpkSA/NXDYS91DTB0yuESL6Q8J+OKXNZz1DXoqK8LPk2GLCdl5ctZquZ6BLPrMA55U1ZyKy3ZSHqmhYUrAN7A3cGB9PtD+eHB0P4AUxBmWYIxbmK1X/82dMTZWO70XbD5Mn3DW9/rP3KJRMHN5IHutvuHTR28tQtm0gZBI1sn70Qr5yFfZbI+INIr20XRHuWVOiI4l+lNlSv4UDhTIWBKM1O6C+f1RO59zm8S9AjSa/DOgkJBr2AiZBLxV0YEPn4qPzxUVtxMdjVCroOWXsHCxjl2MokqqfNtjIDhEclepoQUE5tkONkDhR/Vg3+YAnqAwnzJgwQXCInJHB1Ur29T/8SpEBiNfVFfQxhqQwNlq5EY6UaXEOi+lrD9fh6skC/wLAK3YxvJrfoVxluljbijWQDd7e4Sd9s+BV6xHC/9DJ6SnoV7RVbpLfRG9JJ9Efpa/Sp9CO6IBXCdCQ3ckp9UFgqlSYiVTIIqt1ZIgCjlmi/uIH50Kkj6vioVvY+N2Iajq4FLWOOCF0VVkoEwWSkb09+HIG1ATgaORpBAyoqGJ9kqaWSqNfnGaRMg0FCHCEQbGViDAORkGTQ6wnBOlEycAgLA0zYlKNXVdXQZCCGDpy1W4XomgiAqQaFqDjH+NUfKMN2eT3d9d31XnfXmfrkayUQM1HtVVFuK6NvEWxcw14igCwKbg89V+31LgB9h1PDg7g4w+kaUppRjPErPYt/fSYv4I58va/nBj7cvX7e0mk3kU0/ntShxP+jATtayTei6QCnAMoBagC8ybLxALMAptJroN8n1MS7hbfQ9QCPCzXoKf5TtAPKD/EITQKaaoCR+C20CeBOwDcCjGY5QhWQ3wm5Vx1Te03N9GmVasWIK8qHDysbWjq4pLho0MAB/fsVRgr69skP5+WGcoJKwJ/ty/J63BAAZmbYbbLVYjYZYYlFncBzBKPCqtCYBiUWbojx4dCVV/aj16FZUDArraAhpkDRmN40MaWBkSm9KVWgvP7fKNUEpZqixLJSjsr7FSpVISV2dHRI6cAzJtcCfu/oUFSJdTF8PMO3MtwMeDAINyhV7vmjlRhuUKpiY26a31zVMBqaazFKo0Kj5kr9ClGLZATUCFjMFVrWgl0jMEOIq2pYC0F6Mwwq5g2Nrop5QqPpCGJcXtWsObFJk2urRmcFg9F+hTE8anbouhiiPwSOMBI0inUT042KiawbZQGdDbpHaSnsbN7cIaPrGiKmOaE5s+pqY9ysKO3DFoF+R8dct55xX76Exu2jajem12ZxzVXuBQq9bG7eqMS2T65Nrw3SNBqFNuBekjemoXkMdL0ZFrGa/kY8Ru6K1sbwXdClQmdCZ5WYX+KX1HkNC5WYITQyNL95YQNsjbc5hqbcEmz1etV98dPIW6U0T6sNBWMVWaHorNG+lkzUPOWWNo+qeHrX9CtskW2JhW2xWJOIyZyOzE3VMYyRU6x6SmplMR1R6CpgiJgyW4GR1IZgTkNpMncoap49FMjgE8VwV2wO7MiCmGFUQ7M8jJbT+2NCnhxSmv+FgANCXV/3LpmVLNHlyf9CFKV8kmI1qNfwWCQSKyigLCKOgj2FMY5g14P7Fd7UQUKhZbICGSwfmgRrOys6bAAsfzBIN/ieDhVdBxexpsm1iWsFXZfVitQBkWiMNNCaTq3GMZ3WNGk1qdsbQsDJ7ey/6Tli+nDqzyo7M6rmD4th5/9RPTdRn3y+qFQ1NyTXtnpar6tE/dBUXRKLZYyq5bJIEiNZHKtN/ABcI4GLWlOMz4M/HWPqOR2iHriSlWBlTExuuDKRRqVg8H+8CdwuehfLLt+WHGZsWKT39fBe172GZ2rmYMB8mFRPm9HcLPWqA1ZLdHhVMgOOR9Nqg8qoGJoOkpkHf+AqDaUQzYqpsGSjKAHwX6IoedmLMCuJR+FDubNf4RhQdM3NY0LKmOaG5lkd8abrQoocat5HXiOvNS+ratAYpyO+/56s2JjNUVir+XgYCAVBI1tCeNPkFhVvmjqjdp+MkLJpWm0rwWRUw8hoSy7U1e5TEFJZKaGltJBeKPQCVWOYZCvRM/qsfSpCTayWZwXsenYHRqxMr5VhNLuDJMrkREdh1hH93czsDj5Ro2rUPJTpE2VNCeo+SWo91Mi0Zj/7nT6rTHyocgJHIZ3tmCzTimsitSbSXD0VNo1WSkOzpLRqhd4Yw6HYzNCqYAu0GasJ3RKEwlBMAQUHRC1orC/a3KzANwTdz66pTaS0Chf6oKUo/fcSSdosXzSUdmmCW9lWtPmo2KV6u03rbQX0RpFmrbvY7J/sDUYfw9fSlP2x4bcMQaFE/2DYEp021zXPCAVBb2bTjpPjgEuLL8pagJE8QkcC0v3/AJiiPAIKZW5kc3RyZWFtCmVuZG9iagozNSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDIxND4+c3RyZWFtCnic7c43DgIwEEXBT845x/sfk5U7CiignZGepbW3cP7V+fjSbWcv/QwyzCjjTDLNLPMs3vaW1SrrbLJt8+6HX+yrQ3WsTu3mXF1yza1N9+qRZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAvXu1JAdIKZW5kc3RyZWFtCmVuZG9iagozMiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDE2NDg+PnN0cmVhbQp4nG3YzWoluQEF4H0/xV3OLIZuqaSSBE1DmBDoRX5IJw8gqaTBkHYbt2fRbx/b32SSGXLBNnWuyxy+czGF3v748Y8f7++ebm//9vhlflpPt313fz2ur19+fpzrNtZPd/dvQrxdd/Ppl6vX7/Nzf3jzcvOnb1+f1ueP9/vLm/fvb2///vzm16fHb7fv/nB9Gev7N2//+nitx7v7n27f/fPHT9/f3n76+eHhX+vzun+6vbt9+HC71n7+Q3/uD3/pn9ft7ettP3y8nt+/e/r2w/M9//2Nf3x7WLf4eh2UmV+u9fWhz/XY739ab96/e359uL3/0/Prw5t1f/3u/fDunfvG/u0N797t/frj+eo5DMIgDMIojMIoPISH8BAmYRImYRZmYRaewlN4CouwCIuwCquwCpuwCZuwC7uwC4dwCIdwCqdwCi/hJbyES7iES7iFW7hfw8Az8Aw8A8/AM/AMPAPPwDPwDDwDz8Az8Aw8A8/AM/AMPAPPwDPwDDwDz8Az8Aw8A8/AM/AMPAPPwDPwDDwDz8Az8Aw8A8/AM/AMPAPPwDPwDDwDz8gz8ow8I8/IM/KMPCPPyDPyjDwjz8gz8ow8I8/IM/KMPCPPyDPyjDwjz8gz8ow8I8/IM/KMPCPPyDPyjDwjz8gz8ow8I8/IM/KMPCPPyDPyjDwjz4PnwfPgefA8eB48D54Hz4PnwfPgefA8eB48D54Hz4PnwfPgefA8eB48D54Hz4PnwfPgefA8eB48D54Hz4PnwfPgefA8eB48D54Hz4PnwfPgefA8eB48D54Hz8Qz8Uw8E8/EM/FMPBPPxDPxTDwTz8Qz8Uw8E8/EM/FMPBPPxDPxTDwTz8Qz8Uw8E8/EM/FMPBPPxDPxTDwTz8Qz8Uw8E8/EM/FMPBPPxDPxTDwTz8wz88w8M8/MM/PMPDPPzDPzzDwzz8wz88w8M8/MM/PMPDPPzDPzzDwzz8wz88w8M8/MM/PMPDPPzDPzzDwzz8wz88w8M8/MM/PMPDPPzDPzzDwzz5PnyfPkefI8eZ48T54nz5PnyfPk+Xr18ljxn8eH//NAccI+YZ+wT9gn7BP2CfuEfcI+YZ+wT9gn7BP2CfuEfcI+YZ+wT9gn7BP2CfuEfcI+YZ+wT9gn7BP2CfuEfcI+YZ+wT9gFdoFdYBfYBXaBXWAX2AV2gV1gFx/ewrPwLDwLz8Kz8Cw8C8/Cs/AsPAvPwrPwLDwLz8Kz8Cw8C8/Cs/AsPAvPwrPwLDwLz8Kz8Cw8C8/Cs/AsPAvPyrPyrDwrz8qz8qw8K8/Ks/KsPCvPyrPyrDwrz8qz8qw8K8/Ks/KsPCvPyrPyrDwrz8qz8qw8K8/Ks/KsPCvPyrPyrDwrz8qz8qw8K8/Ks/KsPCvPxrPxbDwbz8az8Ww8G8/Gs/FsPBvPxrPxbDwbz8az8Ww8G8/Gs/FsPBvPxrPxbDwbz8az8Ww8G8/Gs/FsPBvPxrPxbDwbz8az8Ww8G8/Gs/FsPBvPzrPz7Dw7z86z8+w8O8/Os/PsPDvPzrPz7Dw7z86z8+w8O8/Os/PsPDvPzrPz7Dw7z86z8+w8O8/Os/PsPDvPzrPz7Dw7z86z8+w8O8/Os/PsPDvPwXPwHDwHz8Fz8Bw8B8/Bc/AcPAfPwXPwHDwHz8Fz8Bw8B8/Bc/AcPAfPwXPwHDwHz8Fz8Bw8B8/Bc/AcPAfPwXPwHDwHz8Fz8Bw8B8/Bc/AcPAfPyXPynDwnz8lz8pw8J8/Jc/KcPCfPyXPynDwnz8lz8pw8J8/Jc/KcPF+vfvNAkervnicm68l6sp6sJ+vJerKerCfryXqynqwn68l6sp6sJ+vJerKerCfryXqynqwv1hfri/XF+mJ9sb5YX6wv1hfri/XF+mJ9sb5YX6wv1hfri/XF+mJ9sb5YXz67S8+l59Jz6bn0XHouPZeeS8+l59Jz6bn0XHouPZeeS8+l59Jz6bn0XHouPdcvPe2+7L7svuy+7L7svuy+7L7svuy+7L7svuy+7L7svuy+7L7svuy+7L7svuy+7L7svnlunpvn5rl5bp6b5+a5eW6em+fmuXlunpvn5rl5bp6b5+a5eW6em+fmuXlunpvn5rl5bp6b5+a5eW6em+fmuXlunpvn5rl5bp6b5+a5eW6em+fr1f/+L3g5vnw5Zf31bHT+/Pi47p9ej2Jfz0NfTkLv7tevp7UPXx5e7nr5+jfBSz5eCmVuZHN0cmVhbQplbmRvYmoKNSAwIG9iago8PC9UeXBlL09ialN0bS9OIDE5L0ZpcnN0IDEzNy9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDE1NDI+PnN0cmVhbQp4nMVXa08bRxT9zq+YbwFFzM77UUVIYAdCExIU3EBlWWixp2Qr40XrRUr+fc8dL7A4LqGq1Fp+7DzuY+655861YYJ5JkVkiimn8MSMlAxvowWThpkQmbTMCcekY14ZJgML2jOFZaUDUxByFmODRw89Fo+RtOEdLdNMhYi92BGxpiXTAuJa49dgbPCG5jdvitH321Scltep+JyW9V0zTUv4Jtjn4iTNqvKg/jYWGDqpmI9qUgzqRZsW7XLsaBOL+TvQ96Q4a5u7aXtaNrSBiWL1BGewurcHY6dNPT1L7bg4HR6yYpS+taw4voHxg+530P0eT4q339qjs7ZsE+SONMWInDryFKasr7j4dPVnmrZYvwgIS16/QBg7e8UhXMXioaGQ0uKhpajmpxzYvC07NqraeWLb53Uzn12eV7N0Oaib28vzdHV5WDc3O+T57G6aGrYN199XLf/4dgSbXHPrNBdsePJFip1i0KSyrerFEH6z7eEvSigrgozSyGDErvCvhHi1U5zUs+d3ZKemJZPFwUnxER6U8zw12MdUnv8wQIA//Epf50xyTa/i5APiVJztMwCR1kQz0BSS4uzuqqUBzYjioFymPL2fX69HTbq6m35N7clZ8XYxrWfV4ro4ngHIqv2++64YpuU0LWbloiWp5Vh24I/q3xYVticm4wPgPzV6sDI6KOfVVVPtHtTz2YusKrFuVcmXWx08sfoyg+oHg3qDQfoi0aa6beuG+Enp9lyM710cHA9pC6lSNBjVR8fDk/L2wSmaPPu+bNPN8eKPGlY/p+tq2Tbf2fb+rL5KO8WnZpYanINt38vsQP3t7TzdEA8FOHE+RvUY2xi4NMZq8FpzFaSyE2YMGysfuFZCUywFs8JxbbxzE2YhFaziwgofJsxLKLGeS5QZyayx3EgBRmkXuctzJK+C5dI6ZVejaHhUMlAlExxqQNQta2AiOK+Y1Q6iVBQfFQumQ+DOk5ARhvtgM20fpVApuTdOxMmkGJ7DY/ETQOxTQDbl33+NiEAsEemgbTQ5Uii3wvJovdCARWNZK66UswSEZeOI3YSYg6SJmjurtMEwYigDNyTYKbJCAxof/YRtBYCmABWUG4wR07HxkccgDN0k3QIDLhygW9eDBIq05zbmXJCCPO6tASaLDHDBr5DWgMf56CL2Wjil4a/MPmaQfgaRewrRGln/T3QmdLng6OAMOKLzvWg5DqbBCVSIsbERsVOOjuAULgYEBbe1lUATAhNcvwgHMApEqxysYE0HgQMERC/ZgS4RRQH+dFA+6jbBc9zjFN+tnANAUQgdIeiI3cpyjRzRzCjFQZms4nEWqiLAtMFCgQ+ED3jqLR6NF9znoz1sR6JIhn5EKZgHfyNDY7E19ighQYX+zmwEnhnt7X2W9NYoL0BmDSEGX7mUeKRZjQCAwaZvU8ocTcmdE5nyBkGXOT8NypDTID92UZyUw2GomlC2gR0oDIAEAd2YbY+Jlocfy5u0qSofzsvrJTPFPt0CLYs6wEcTTHcvtGxXIbYSWe7R9qSbL8gELjQwKwbl7btUXX9F43MPbXHcInun+4trdBkiGz6gzmoXBTIiWtDmwHBBvJUioMxqlGQWDeDz4NgkixxW84QWz/947Ww61KbKtnYqb0XvPBh0J+nSs3cSp+WKAX97EikUtwQe25UoSav8DgE1G5VEI8vvC1r/KOFlR1mrAC87BcgUYjDmH50CvMiYPjkEeEcYhYeq1j/CWq9DnfQSTfIdnJHF+2q2HOcWYPJsY7LWbLB8//ZK4Ggw/P3L8PV+U5Xzk1GvB9GrrndDA7O3N9a5QZlstPukeq4VYG2etf5vy6pctSGKug1cQ4Yoq+mio9JFt84LPltZ1EHU0Y3kPBt71F/6YAJcFCiNXncmYqQaLqgm5b4l32H64QlaQGYIgHrdo5TiiTM0Y++V4F/Vag2jSf/qAeGfTegfs+58lZhGrIb4A5Xa6deube/lpXOG7Wr6tydQVuE8kvAxr2n8UKmE7bFByuKi22Rl6FW8DsucyOVNNSf0aG6nY4/oWKZVL9l195fpL01SCJQKZW5kc3RyZWFtCmVuZG9iagozNyAwIG9iago8PC9Sb290IDEgMCBSL0luZm8gMiAwIFIvSURbKDNjMzVhNzQwLTg4MDktNDc0YS1hNTlhLWIyYTNjZWI1ZGY0OSkgKDNjMzVhNzQwLTg4MDktNDc0YS1hNTlhLWIyYTNjZWI1ZGY0OSldL1R5cGUvWFJlZi9JbmRleFswIDM4XS9XWzEgNCA0XS9TaXplIDM4L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMTUyPj5zdHJlYW0KeJxNjjEKwkAQRSeaNUaNUe9glUJFJMdIk9JjBHtrG08RsE7vOTyD6VIJFvoH5sMMLPv2/T+wovPDRCJtqY8RTtCbsCQIOkNhIJUvR2pyRlcfjQkxouRpnTD4TiBMCAkhJ0yxtdv6rRRmf/NmBnP4ejMnLAgZOseHfaN+GTSdQdv49RVMf/FmTdggep9tqzsZfO4Kf+U8FW8KZW5kc3RyZWFtCmVuZG9iagpzdGFydHhyZWYKNjM2MzIKJSVFT0YK", "display": "inline", "includeInDownload": "true", "signerMustAcknowledge": "no_interaction", "templateLocked": "false", "templateRequired": "false" } ], "emailSubject": "Please sign this document", "emailBlurb": "", "signingLocation": "Online", "authoritativeCopy": "false", "enforceSignerVisibility": "false", "enableWetSign": "true", "allowMarkup": "false", "allowReassign": "true", "customFields": { "textCustomFields": [ { "fieldId": "11230853228", "name": "ModelNamespace", "show": "false", "required": "false", "value": "docusign.forms._85443307_664c_4c85_882f_87671e153075._608a6c8a_16b2_4419_92f4_d06bc3af6e53" }, { "fieldId": "11230853229", "name": "ModelVersion", "show": "false", "required": "false", "value": "1" }, { "fieldId": "11230853230", "name": "ModelAccount", "show": "false", "required": "false", "value": "85443307-664c-4c85-882f-87671e153075" } ], "listCustomFields": [] }, "recipients": { "signers": [ { "defaultRecipient": "false", "tabs": { "signHereTabs": [ { "stampType": "signature", "name": "SignHere", "tabLabel": "Signature", "scaleValue": "1", "optional": "false", "documentId": "1", "recipientId": "1", "pageNumber": "1", "xPosition": "126", "yPosition": "374", "anchorString": "/SignHere/", "anchorXOffset": "20", "anchorYOffset": "10", "anchorUnits": "pixels", "anchorCaseSensitive": "false", "anchorMatchWholeWord": "true", "anchorHorizontalAlignment": "left", "anchorTabProcessorVersion": "v1_3", "tabId": "be01d0ca-1057-455f-9af6-95f6074b5cf6", "tabType": "signhere" } ], "dateSignedTabs": [ { "name": "DateSigned", "value": "", "tabLabel": "DateSigned", "localePolicy": {}, "documentId": "1", "recipientId": "1", "pageNumber": "1", "xPosition": "409", "yPosition": "396", "anchorString": "/Date/", "anchorXOffset": "20", "anchorYOffset": "10", "anchorUnits": "pixels", "anchorCaseSensitive": "false", "anchorMatchWholeWord": "true", "anchorHorizontalAlignment": "left", "anchorTabProcessorVersion": "v1_3", "tabId": "a0276278-95a3-4de2-a374-15e92510112e", "tabType": "datesigned" } ], "textTabs": [ { "requireAll": "false", "value": "", "originalValue": "", "required": "true", "locked": "false", "concealValueOnDocument": "false", "disableAutoSize": "false", "maxLength": "4000", "tabLabel": "FullName", "bold": "false", "italic": "false", "underline": "false", "localePolicy": {}, "documentId": "1", "recipientId": "1", "pageNumber": "1", "xPosition": "145", "yPosition": "234", "width": "0", "height": "0", "anchorString": "/FullName/", "anchorXOffset": "20", "anchorYOffset": "10", "anchorUnits": "pixels", "anchorCaseSensitive": "false", "anchorMatchWholeWord": "true", "anchorHorizontalAlignment": "left", "anchorTabProcessorVersion": "v1_3", "tabId": "c995df10-9141-4686-b9bf-f1dfc4121d33", "mergeFieldXml": "{\"adm\":{\"path\":\"ADM.Form.FullName\"}} ", "tabType": "text" }, { "requireAll": "false", "value": "", "originalValue": "", "required": "true", "locked": "false", "concealValueOnDocument": "false", "disableAutoSize": "false", "maxLength": "4000", "tabLabel": "PhoneNumber", "bold": "false", "italic": "false", "underline": "false", "localePolicy": {}, "documentId": "1", "recipientId": "1", "pageNumber": "1", "xPosition": "167", "yPosition": "261", "width": "0", "height": "0", "anchorString": "/PhoneNumber/", "anchorXOffset": "20", "anchorYOffset": "10", "anchorUnits": "pixels", "anchorCaseSensitive": "false", "anchorMatchWholeWord": "true", "anchorHorizontalAlignment": "left", "anchorTabProcessorVersion": "v1_3", "tabId": "71ccfefa-5469-493e-b0c7-886c65b84742", "mergeFieldXml": "{\"adm\":{\"path\":\"ADM.Form.PhoneNumber\"}} ", "tabType": "text" }, { "requireAll": "false", "value": "", "originalValue": "", "required": "true", "locked": "false", "concealValueOnDocument": "false", "disableAutoSize": "false", "maxLength": "4000", "tabLabel": "Company", "bold": "false", "italic": "false", "underline": "false", "localePolicy": {}, "documentId": "1", "recipientId": "1", "pageNumber": "1", "xPosition": "182", "yPosition": "315", "width": "0", "height": "0", "anchorString": "/Company/", "anchorXOffset": "20", "anchorYOffset": "10", "anchorUnits": "pixels", "anchorCaseSensitive": "false", "anchorMatchWholeWord": "true", "anchorHorizontalAlignment": "left", "anchorTabProcessorVersion": "v1_3", "tabId": "184f8a65-f2be-48b9-a30e-15592c59b335", "mergeFieldXml": "{\"adm\":{\"path\":\"ADM.Form.Company\"}} ", "tabType": "text" }, { "requireAll": "false", "value": "", "originalValue": "", "required": "true", "locked": "false", "concealValueOnDocument": "false", "disableAutoSize": "false", "maxLength": "4000", "tabLabel": "JobTitle", "bold": "false", "italic": "false", "underline": "false", "localePolicy": {}, "documentId": "1", "recipientId": "1", "pageNumber": "1", "xPosition": "137", "yPosition": "342", "width": "0", "height": "0", "anchorString": "/Title/", "anchorXOffset": "20", "anchorYOffset": "10", "anchorUnits": "pixels", "anchorCaseSensitive": "false", "anchorMatchWholeWord": "true", "anchorHorizontalAlignment": "left", "anchorTabProcessorVersion": "v1_3", "tabId": "e7d30733-ce70-4fee-93a0-ea10ecc014b1", "mergeFieldXml": "{\"adm\":{\"path\":\"ADM.Form.JobTitle\"}} ", "tabType": "text" } ], "checkboxTabs": [ { "name": "Yes", "tabLabel": "Yes", "selected": "false", "selectedOriginal": "false", "requireInitialOnSharedChange": "false", "bold": "false", "italic": "false", "underline": "false", "required": "true", "locked": "false", "documentId": "1", "recipientId": "1", "pageNumber": "1", "xPosition": "237", "yPosition": "288", "width": "0", "height": "0", "anchorString": "/SMS/", "anchorXOffset": "20", "anchorYOffset": "10", "anchorUnits": "pixels", "anchorCaseSensitive": "false", "anchorMatchWholeWord": "true", "anchorHorizontalAlignment": "left", "anchorTabProcessorVersion": "v1_3", "tabId": "0f1e242d-550d-4729-a141-de0dce1d1b6c", "mergeFieldXml": "{\"adm\":{\"path\":\"ADM.Form.Yes.Yes\"}} ", "tabType": "checkbox" } ] }, "signInEachLocation": "false", "agentCanEditEmail": "false", "agentCanEditName": "false", "requireUploadSignature": "false", "name": "", "email": "", "recipientId": "1", "recipientIdGuid": "00000000-0000-0000-0000-000000000000", "accessCode": "", "requireIdLookup": "false", "routingOrder": "1", "note": "", "roleName": "signer", "completedCount": "0", "deliveryMethod": "email", "templateLocked": "false", "templateRequired": "false", "inheritEmailNotificationConfiguration": "false", "recipientType": "signer" } ], "agents": [], "editors": [], "intermediaries": [], "carbonCopies": [], "certifiedDeliveries": [], "inPersonSigners": [], "seals": [], "witnesses": [], "notaries": [], "recipientCount": "1" }, "envelopeIdStamping": "true", "autoNavigation": "true", "uSigState": "esign", "allowComments": "true", "disableResponsiveDocument": "true", "anySigner": null, "envelopeLocation": "current_site" } ] }
+
diff --git a/docs/stripe_skip_account_form_link.png b/docs/stripe_skip_account_form_link.png
new file mode 100644
index 0000000..766a12a
Binary files /dev/null and b/docs/stripe_skip_account_form_link.png differ
diff --git a/eg001EmbeddedSigning.ps1 b/eg001EmbeddedSigning.ps1
index 01597ca..1db4868 100644
--- a/eg001EmbeddedSigning.ps1
+++ b/eg001EmbeddedSigning.ps1
@@ -1,19 +1,31 @@
$apiUri = "https://demo.docusign.net/restapi"
+$configPath = ".\config\settings.json"
+$tokenPath = ".\config\ds_access_token.txt"
+$accountIdPath = ".\config\API_ACCOUNT_ID"
+
+# Check the folder structure to switch paths for Quick ACG
+if ((Test-Path $configPath) -eq $false) {
+ $configPath = "..\config\settings.json"
+}
+if ((Test-Path $tokenPath) -eq $false) {
+ $tokenPath = "..\config\ds_access_token.txt"
+}
+if ((Test-Path $accountIdPath) -eq $false) {
+ $accountIdPath = "..\config\API_ACCOUNT_ID"
+}
# Use embedded signing
# Get required variables from .\config\settings.json file
-$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
-
-
+$variables = Get-Content $configPath -Raw | ConvertFrom-Json
# 1. Obtain your OAuth token
-$accessToken = Get-Content .\config\ds_access_token.txt
+$accessToken = Get-Content $tokenPath
# Obtain your accountId from demo.docusign.net -- the account id is shown in
# the drop down on the upper right corner of the screen by your picture or
# the default picture.
-$accountID = Get-Content .\config\API_ACCOUNT_ID
+$accountID = Get-Content $accountIdPath
# Step 2. Create the envelope definition.
# The signer recipient includes a clientUserId setting
@@ -28,12 +40,20 @@ $requestData = New-TemporaryFile
$response = New-TemporaryFile
$doc1Base64 = New-TemporaryFile
+$docPath = ".\demo_documents\World_Wide_Corp_lorem.pdf"
+
+# Check the folder structure to switch paths for Quick ACG
+if ((Test-Path $docPath) -eq $false) {
+ $docPath = "..\demo_documents\World_Wide_Corp_lorem.pdf"
+}
+
# Fetch doc and encode
-[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $doc1Base64
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path $docPath))) > $doc1Base64
-Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "Sending the envelope request to Docusign..."
# Concatenate the different parts of the request
+#ds-snippet-start:eSign1Step2
@{
emailSubject = "Please sign this document set";
documents = @(
@@ -67,8 +87,10 @@ Write-Output "Sending the envelope request to DocuSign..."
};
status = "sent";
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign1Step2
-# Step 3. Call DocuSign to create the envelope
+# Step 3. Call Docusign to create the envelope
+#ds-snippet-start:eSign1Step3
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
-Method 'POST' `
@@ -78,6 +100,7 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign1Step3
Write-Output "Response: $(Get-Content -Raw $response)"
@@ -88,11 +111,12 @@ Write-Output "EnvelopeId: $envelopeId"
# Step 4. Create a recipient view definition
# The signer will directly open this link from the browser to sign.
#
-# The returnUrl is normally your own web app. DocuSign will redirect
+# The returnUrl is normally your own web app. Docusign will redirect
# the signer to returnUrl when the signing completes.
# For this example, we'll use http://httpbin.org/get to show the
-# query parameters passed back from DocuSign
+# query parameters passed back from Docusign
+#ds-snippet-start:eSign1Step4
Write-Output "Requesting the url for the embedded signing..."
$json = [ordered]@{
@@ -102,9 +126,10 @@ $json = [ordered]@{
'userName' = $variables.SIGNER_NAME;
'clientUserId' = 1000
} | ConvertTo-Json -Compress
+#ds-snippet-end:eSign1Step4
-
-# Step 5. Create the recipient view and begin the DocuSign signing
+# Step 5. Create the recipient view and begin the Docusign signing
+#ds-snippet-start:eSign1Step5
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/recipient" `
-Method 'POST' `
@@ -117,6 +142,7 @@ Invoke-RestMethod `
Write-Output "Response: $(Get-Content -Raw $response)"
$signingUrl = $(Get-Content $response | ConvertFrom-Json).url
+#ds-snippet-end:eSign1Step5
# ***DS.snippet.0.end
Write-Output "The embedded signing URL is $signingUrl"
@@ -129,4 +155,4 @@ Remove-Item $requestData
Remove-Item $response
Remove-Item $doc1Base64
-Write-Output "Done."
+Write-Output "Done."
\ No newline at end of file
diff --git a/examples/Admin/eg001CreateNewUserWithActiveStatus.ps1 b/examples/Admin/eg001CreateNewUserWithActiveStatus.ps1
new file mode 100644
index 0000000..4fabd0b
--- /dev/null
+++ b/examples/Admin/eg001CreateNewUserWithActiveStatus.ps1
@@ -0,0 +1,98 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Construct your API headers
+#ds-snippet-start:Admin1Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Admin1Step2
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# Check that we have an organization id in the settings.json config file
+if (!$variables.ORGANIZATION_ID) {
+ Write-Output "Organization ID is needed. Please add the ORGANIZATION_ID variable to the settings.json"
+ exit -1
+}
+
+$base_path = "https://api-d.docusign.net/management"
+$organizationId = $variables.ORGANIZATION_ID
+
+# Get groups and permission profile IDs
+#ds-snippet-start:Admin1Step3
+$uri = "${base_path}/v2/organizations/${organizationId}/accounts/${accountId}/permissions"
+$result = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+
+$permissionsObj = $($result.Content | ConvertFrom-Json).permissions
+#ds-snippet-end:Admin1Step3
+
+# Setup a temporary menu option to pick a permission profile
+$menu = @{}
+ for ($i=1;$i -le $permissionsObj.count; $i++)
+ { Write-Output "$i. $($permissionsObj[$i-1].name)"
+ $menu.Add($i,($permissionsObj[$i-1].id))}
+ do {
+ [int]$selection = Read-Host 'Select an eSignature permission profile to assign to the new user'
+ } while ($selection -gt $permissionsObj.count -or $selection -lt 1);
+ $permissionsId = $menu.Item($selection)
+
+#ds-snippet-start:Admin1Step4
+$uri = "${base_path}/v2/organizations/${organizationId}/accounts/${accountId}/groups"
+$result = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+
+$groupsObj = $($result.Content | ConvertFrom-Json).groups
+#ds-snippet-end:Admin1Step4
+
+# Setup a temporary menu option to pick a group
+$menu = @{}
+ for ($i=1;$i -le $groupsObj.count; $i++)
+ { Write-Output "$i. $($groupsObj[$i-1].name)"
+ $menu.Add($i,($groupsObj[$i-1].id))}
+ do {
+ [int]$selection = Read-Host 'Select an eSignature group Id to assign to the new user'
+ } while ($selection -gt $groupsObj.count -or $selection -lt 1);
+ $groupId = $menu.Item($selection)
+
+
+
+$userName = Read-Host "Enter a username for the new user"
+$firstName = Read-Host "Enter the first name of the new user"
+$lastName = Read-Host "Enter the last name of the new user"
+$userEmail = Read-Host "Enter an email for the new user"
+
+# Construct the request body for the new user
+#ds-snippet-start:Admin1Step5
+$body = @"
+{
+ "user_name": "$userName",
+ "first_name": "$firstName",
+ "last_name": "$lastName",
+ "email": "$userEmail",
+ "auto_activate_memberships": true,
+ "accounts": [
+ {
+ "id": "${accountId}",
+ "permission_profile": {
+ "id": $permissionsId,
+ },
+ "groups": [
+ {
+ "id": $groupId,
+ }
+ ]
+ }
+ ]
+}
+"@
+#ds-snippet-end:Admin1Step5
+
+$result = ""
+# Call the Docusign Admin API
+#ds-snippet-start:Admin1Step6
+$uri = "${base_path}/v2/organizations/${organizationId}/users"
+$result = Invoke-WebRequest -headers $headers -Uri $uri -body $body -Method POST
+$result.Content
+#ds-snippet-end:Admin1Step6
diff --git a/examples/Admin/eg002CreateActiveCLMEsignUser.ps1 b/examples/Admin/eg002CreateActiveCLMEsignUser.ps1
new file mode 100644
index 0000000..19fc491
--- /dev/null
+++ b/examples/Admin/eg002CreateActiveCLMEsignUser.ps1
@@ -0,0 +1,183 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+$base_path = "https://api-d.docusign.net/management"
+$organizationId=$variables.ORGANIZATION_ID
+
+# Construct your API headers
+#ds-snippet-start:Admin2Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Admin2Step2
+
+
+try {
+ # Display the JSON response
+ # Write-Output "Response:"
+ #ds-snippet-start:Admin2Step3
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/accounts/${APIAccountId}/products/permission_profiles"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+
+ $productProfiles = $($response.Content | ConvertFrom-Json).product_permission_profiles
+ #ds-snippet-end:Admin2Step3
+}
+catch {
+ Write-Output "Error:"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+
+$esignPermissionProfiles = $null
+$clmPermissionProfiles = $null
+foreach ($productProfile in $productProfiles) {
+ if ($productProfile.product_name -eq "ESign") {
+ $esignPermissionProfiles = $productProfile.permission_profiles
+ $esignProductId = $productProfile.product_id
+ } else {
+ $clmPermissionProfiles = $productProfile.permission_profiles
+ $clmProductId = $productProfile.product_id
+ }
+}
+
+if($null -eq $esignPermissionProfiles){
+ Write-Output "You must create an eSignature permission profile before running this code example"
+ exit 1
+} elseif ($esignPermissionProfiles.count -eq 1){
+ $esignPermissionProfileId = $esignPermissionProfiles[0].permission_profile_id
+} else {
+ $menu = @{}
+ for ($i=1;$i -le $esignPermissionProfiles.count; $i++)
+ { Write-Output "$i. $($esignPermissionProfiles[$i-1].permission_profile_name)"
+ $menu.Add($i,($esignPermissionProfiles[$i-1].permission_profile_id))}
+ do {
+ [int]$selection = Read-Host 'Select an eSignature permission profile to assign to the new user'
+ } while ($selection -gt $esignPermissionProfiles.count -or $selection -lt 1);
+ $esignPermissionProfileId = $menu.Item($selection)
+}
+
+if($null -eq $clmPermissionProfiles){
+ Write-Output "You must create a CLM permission profile before running this code example"
+ exit 1
+} elseif ($clmPermissionProfiles.count -eq 1){
+ $clmPermissionProfileId = $clmPermissionProfiles[0].permission_profile_id
+} else {
+ $menu = @{}
+ for ($i=1;$i -le $clmPermissionProfiles.count; $i++)
+ { Write-Output "$i. $($clmPermissionProfiles[$i-1].permission_profile_name)"
+ $menu.Add($i,($clmPermissionProfiles[$i-1].permission_profile_id))}
+ do {
+ [int]$selection = Read-Host 'Select a CLM permission profile to assign to the new user'
+ } while ($selection -gt $clmPermissionProfiles.count -or $selection -lt 1);
+ $clmPermissionProfileId = $menu.Item($selection)
+}
+
+
+try {
+ # Display the JSON response
+ Write-Output "Response:"
+ #ds-snippet-start:Admin2Step4
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/accounts/${APIAccountId}/dsgroups"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+ $dsGroups = $($response.Content | ConvertFrom-Json).ds_groups
+ #ds-snippet-end:Admin2Step4
+}
+catch {
+ Write-Output "Error:"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+
+if($dsGroups.count -eq 0){
+ Write-Output "You must create a DS Group before running this code example"
+ exit 1
+} elseif ($dsGroups.count -eq 1){
+ $dsGroupId = $dsGroups[0].ds_group_id
+} else {
+ $menu = @{}
+ for ($i=1;$i -le $dsGroups.count; $i++)
+ { Write-Output "$i. $($dsGroups[$i-1].group_name)"
+ $menu.Add($i,($dsGroups[$i-1].ds_group_id))}
+ do {
+ [int]$selection = Read-Host 'Select a DS Group to assign the new user to'
+ } while ($selection -gt $dsGroups.count -or $selection -lt 1);
+ $dsGroupId = $menu.Item($selection)
+}
+
+$userName = Read-Host "Enter a username for the new user"
+$firstName = Read-Host "Enter the first name of the new user"
+$lastName = Read-Host "Enter the last name of the new user"
+$userEmail = Read-Host "Enter an email for the new user"
+
+# Construct the request body for the new user
+#ds-snippet-start:Admin2Step5
+$body = @"
+{
+ "user_name": "$userName",
+ "first_name": "$firstName",
+ "last_name": "$lastName",
+ "email": "$userEmail",
+ "auto_activate_memberships": true,
+ "product_permission_profiles": [
+ {
+ "permission_profile_id": "$esignPermissionProfileId",
+ "product_id": "$esignProductId"
+ },
+ {
+ "permission_profile_id": "$clmPermissionProfileId",
+ "product_id": "$clmProductId"
+ }
+ ],
+ "ds_groups": [
+ {
+ "ds_group_id": "$dsGroupId"
+ }
+ ]
+}
+"@
+#ds-snippet-end:Admin2Step5
+
+
+try {
+ # Display the JSON response
+ Write-Output "Response:"
+ #ds-snippet-start:Admin2Step6
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/accounts/${APIAccountId}/users/"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -body $body -method POST
+ $response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 5
+ #ds-snippet-end:Admin2Step6
+
+ # Store user email to the file for future reference
+ $($response.Content | ConvertFrom-Json).email > .\config\ESIGN_CLM_USER_EMAIL
+ Write-Output "Done"
+}
+catch {
+ Write-Output "Unable to create a new user."
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
diff --git a/examples/Admin/eg003BulkExportUserData.ps1 b/examples/Admin/eg003BulkExportUserData.ps1
new file mode 100644
index 0000000..1261c5d
--- /dev/null
+++ b/examples/Admin/eg003BulkExportUserData.ps1
@@ -0,0 +1,86 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Construct your API headers
+#ds-snippet-start:Admin3Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Admin3Step2
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# Check that we have an organization id in the settings.json config file
+if (!$variables.ORGANIZATION_ID) {
+ Write-Output "Organization ID is needed. Please add the ORGANIZATION_ID variable to the settings.json"
+ exit -1
+}
+
+$base_path = "https://api-d.docusign.net/management"
+$organizationId = $variables.ORGANIZATION_ID
+
+# Create the bulk export request
+$uri2 = "${base_path}/v2/organizations/$organizationId/exports/user_list"
+
+$body = @"
+{
+ "type": "organization_memberships_export"
+}
+"@
+
+$result = Invoke-WebRequest -headers $headers -Uri $uri2 -body $body -Method POST
+
+# Get request Id
+$requestId = $($result.Content | ConvertFrom-Json).id
+$requestId
+
+#ds-snippet-start:Admin3Step3
+Write-Output "Checking Bulk Action Status"
+$uri2 = "${base_path}/v2/organizations/$organizationId/exports/user_list/$requestId"
+$result2 = Invoke-WebRequest -headers $headers -Uri $uri2 -Method GET
+$result2.Content
+$results = $result2 | ConvertFrom-Json
+$retrycount = 0
+
+Do {
+ Write-Output "The Bulk Action has not been completed. Retrying in 5 seconds. To abort, Press Control+C"
+ Start-Sleep 5
+ $result2 = Invoke-WebRequest -headers $headers -Uri $uri2 -Method GET
+ $resultStatus = $($result2 | ConvertFrom-Json).status
+ $retrycount++
+ if ($retrycount -eq 5) {
+ exit 1
+ }
+} While ($resultStatus -ne "completed")
+
+if ($resultStatus -eq "completed") {
+ Write-Output $($result2 | ConvertFrom-Json).results.id
+ $resultId = $($result2 | ConvertFrom-Json).results.id
+}
+else {
+ Write-Output "An error has occurred, the Bulk Action has not been completed."
+ exit 1
+}
+#ds-snippet-end:Admin3Step3
+
+# Check the request status
+#ds-snippet-start:Admin3Step4
+$uri2 = "${base_path}/v2/organizations/$organizationId/exports/user_list/$requestId"
+$result2 = Invoke-WebRequest -headers $headers -Uri $uri2 -Method GET
+$result2.Content
+$results = $result2 | ConvertFrom-Json
+#ds-snippet-end:Admin3Step4
+$results
+
+# Get result Id
+$resultId = $($result2 | ConvertFrom-Json).results.id
+
+# Download the exported user data
+#ds-snippet-start:Admin3Step5
+$uri3 = "https://demo.docusign.net/restapi/v2/organization_exports/$organizationId/user_list/$resultId"
+$result3 = Invoke-WebRequest -headers $headers -Uri $uri3 -Method GET
+$result3.Content
+#ds-snippet-end:Admin3Step5
+Write-Output "Export data to file bulkexport.csv ..."
+$result3.Content > bulkexport.csv
diff --git a/examples/Admin/eg004AddUsersViaBulkImport.ps1 b/examples/Admin/eg004AddUsersViaBulkImport.ps1
new file mode 100644
index 0000000..ab78979
--- /dev/null
+++ b/examples/Admin/eg004AddUsersViaBulkImport.ps1
@@ -0,0 +1,51 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Construct your API headers
+#ds-snippet-start:Admin4Step2
+$headers1 = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers1.add("Authorization","Bearer ${accessToken}")
+$headers1.add("Content-Disposition", "filename=bulkimport.csv")
+$headers1.add("Content-Type","text/csv")
+
+$headers2 = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers2.add("Authorization","Bearer ${accessToken}")
+#ds-snippet-end:Admin4Step2
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# Check that we have an organization id in the settings.json config file
+if (!$variables.ORGANIZATION_ID) {
+ Write-Output "Organization ID is needed. Please add the ORGANIZATION_ID variable to the settings.json"
+ exit -1
+}
+
+$base_path = "https://api-d.docusign.net/management"
+$organizationId = $variables.ORGANIZATION_ID
+
+# Create the bulk import request
+#ds-snippet-start:Admin4Step3
+$body = @"
+AccountID,AccountName,FirstName,LastName,UserEmail,eSignPermissionProfile,Group,Language,UserTitle,CompanyName,AddressLine1,AddressLine2,City,StateRegionProvince,PostalCode,Phone,LoginPolicy,AutoActivate
+$accountId,Sample Account,John,Markson,user1email@example.com,Account Administrator,Everyone,en,Mr.,Some Division,123 4th St,Suite C1,Seattle,WA,8178,2065559999,fedAuthRequired,true
+$accountId,Sample Account,Jill,Smith,user2email@example.com,Account Administrator,Everyone,en,Mr.,Some Division,123 4th St,Suite C1,Seattle,WA,8178,2065559999,fedAuthRequired,true
+$accountId,Sample Account,James,Grayson,user3emailt@example.com,Account Administrator,Everyone,en,Mr.,Some Division,123 4th St,Suite C1,Seattle,WA,8178,2065559999,fedAuthRequired,true
+"@
+
+$uri1 = "${base_path}/v2/organizations/$organizationId/imports/bulk_users/add"
+$result1 = Invoke-WebRequest -headers $headers1 -Uri $uri1 -body $body -Method POST
+$result1.Content
+$results = $result1 | ConvertFrom-Json
+$importId = $results.id
+#ds-snippet-end:Admin4Step3
+
+# Check the request status
+Write-Output "Sleep 20 seconds..."
+Start-Sleep 20
+#ds-snippet-start:Admin4Step4
+$uri2 = "${base_path}/v2/organizations/$organizationId/imports/bulk_users/$importId"
+$result2 = Invoke-WebRequest -headers $headers2 -Uri $uri2 -Method GET
+$result2.Content
+#ds-snippet-end:Admin4Step4
diff --git a/examples/Admin/eg005AuditUsers.ps1 b/examples/Admin/eg005AuditUsers.ps1
new file mode 100644
index 0000000..c0bb422
--- /dev/null
+++ b/examples/Admin/eg005AuditUsers.ps1
@@ -0,0 +1,75 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+$base_path = "https://api-d.docusign.net/management"
+$organizationId=$variables.ORGANIZATION_ID
+
+# Check that organizationId has been set
+if($null -eq $organizationId)
+{
+ Write-Output "PROBLEM: Please add your ORGANIZATION_ID to settings.json."
+ Exit
+}
+
+# Construct your API headers
+#ds-snippet-start:Admin5Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Admin5Step2
+
+#ds-snippet-start:Admin5Step3
+$modifiedSince = (Get-Date (Get-Date).AddDays(-10) -Format "yyyy-MM-dd")
+
+try {
+ # Display the JSON response
+ Write-Output "Response:"
+ $uri = "${base_path}/management/v2/organizations/${organizationId}/users?account_id=${APIAccountId}&last_modified_since=${modifiedSince}"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+ $response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 4
+ $modifiedUsers = $($response.Content | ConvertFrom-Json).users
+}
+catch {
+ Write-Output "Error:"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+#ds-snippet-end:Admin5Step3
+
+#ds-snippet-start:Admin5Step4
+$userEmails = $modifiedUsers.email
+#ds-snippet-end:Admin5Step4
+
+#ds-snippet-start:Admin5Step5
+foreach ($emailAddress in $userEmails){
+ try {
+ # Display the JSON response
+ Write-Output "Response:"
+ $uri = "${base_path}/management/v2/organizations/${organizationId}/users/profile?email=${emailAddress}"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+ $response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 4
+ }
+ catch {
+ Write-Output "Error:"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+ }
+}
+#ds-snippet-end:Admin5Step5
\ No newline at end of file
diff --git a/examples/Admin/eg006GetUserProfileByEmail.ps1 b/examples/Admin/eg006GetUserProfileByEmail.ps1
new file mode 100644
index 0000000..94b88af
--- /dev/null
+++ b/examples/Admin/eg006GetUserProfileByEmail.ps1
@@ -0,0 +1,31 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Construct your API headers
+#ds-snippet-start:Admin6Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Admin6Step2
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# Check that we have an organization id in the settings.json config file
+if (!$variables.ORGANIZATION_ID) {
+ Write-Output "Organization ID is needed. Please add the ORGANIZATION_ID variable to the settings.json"
+ exit -1
+}
+
+$base_path = "https://api-d.docusign.net/management"
+$organizationId = $variables.ORGANIZATION_ID
+
+$email = Read-Host "Enter the user's email address"
+
+$result = ""
+# Call the Docusign Admin API
+#ds-snippet-start:Admin6Step3
+$uri = "${base_path}/v2.1/organizations/${organizationId}/users/dsprofile?email=${email}"
+$result = Invoke-WebRequest -headers $headers -Uri $uri -body $body -Method GET
+$result.Content
+#ds-snippet-end:Admin6Step3
diff --git a/examples/Admin/eg007GetUserProfileByUserId.ps1 b/examples/Admin/eg007GetUserProfileByUserId.ps1
new file mode 100644
index 0000000..dbfcd0a
--- /dev/null
+++ b/examples/Admin/eg007GetUserProfileByUserId.ps1
@@ -0,0 +1,31 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Construct your API headers
+#ds-snippet-start:Admin7Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Admin7Step2
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# Check that we have an organization id in the settings.json config file
+if (!$variables.ORGANIZATION_ID) {
+ Write-Output "Organization ID is needed. Please add the ORGANIZATION_ID variable to the settings.json"
+ exit -1
+}
+
+$base_path = "https://api-d.docusign.net/management"
+$organizationId = $variables.ORGANIZATION_ID
+
+$userId = Read-Host "Enter the user's User ID"
+
+$result = ""
+# Call the Docusign Admin API
+#ds-snippet-start:Admin7Step3
+$uri = "${base_path}/v2.1/organizations/${organizationId}/users/${userId}/dsprofile"
+$result = Invoke-WebRequest -headers $headers -Uri $uri -body $body -Method GET
+$result.Content
+#ds-snippet-end:Admin7Step3
diff --git a/examples/Admin/eg008UpdateUserProductPermissionProfile.ps1 b/examples/Admin/eg008UpdateUserProductPermissionProfile.ps1
new file mode 100644
index 0000000..9a74af3
--- /dev/null
+++ b/examples/Admin/eg008UpdateUserProductPermissionProfile.ps1
@@ -0,0 +1,170 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+$emailAddressFile = ".\config\ESIGN_CLM_USER_EMAIL"
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+$base_path = "https://api-d.docusign.net/management"
+$organizationId=$variables.ORGANIZATION_ID
+
+# Check that we have an email address of created user
+if (Test-Path $emailAddressFile) {
+ $emailAddress = Get-Content $emailAddressFile
+
+ try {
+ $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+ $headers.add("Authorization", "Bearer $accessToken")
+ $headers.add("Content-Type", "application/json")
+
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/users/dsprofile?email=${emailAddress}"
+ $response = Invoke-WebRequest -headers $headers -Uri $uri -body $body -Method GET
+ } catch {
+ Write-Output "The user with stored email address is not present in the account."
+ Write-Output "Please run example 2: 'Create a new active CLM and eSignature user' before running this code example"
+ exit 1
+ }
+} else {
+ Write-Output "Please run example 2: 'Create a new active CLM and eSignature user' before running this code example"
+ exit 1
+}
+
+# Construct your API headers
+#ds-snippet-start:Admin8Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Admin8Step2
+
+try {
+ # Get all permission profiles
+ Write-Output "Getting permission profiles..."
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/accounts/${APIAccountId}/products/permission_profiles"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+ $productProfiles = $($response.Content | ConvertFrom-Json).product_permission_profiles
+
+ # Get and showcase permission profiles that are currently added to the user
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/accounts/${APIAccountId}/products/permission_profiles/users?email=${emailAddress}"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+
+ Write-Output "Response:"
+ Write-Output ""
+ Write-Output $response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 5
+ Write-Output ""
+}
+catch {
+ Write-Output "Error:"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+$esignPermissionProfiles = $null
+$clmPermissionProfiles = $null
+
+foreach ($productProfile in $productProfiles) {
+ if ($productProfile.product_name -eq "ESign") {
+ $esignPermissionProfiles = $productProfile.permission_profiles
+ $esignProductId = $productProfile.product_id
+ } else {
+ $clmPermissionProfiles = $productProfile.permission_profiles
+ $clmProductId = $productProfile.product_id
+ }
+}
+
+Write-Output ""
+Write-Output "Update user product permission profile for the following email: $emailAddress"
+Write-Output ""
+
+Enum listProductChoices {
+ CLM = 1;
+ eSignature = 2;
+}
+$listProductChoicesView = $null;
+do {
+ Write-Output "$([int][listProductChoices]::CLM)) CLM"
+ Write-Output "$([int][listProductChoices]::eSignature)) eSignature"
+ [int]$listProductChoicesView = Read-Host "Would you like to update the permission profile for the eSignature or CLM product?"
+} while (-not [listProductChoices]::IsDefined([listProductChoices], $listProductChoicesView));
+
+if ($listProductChoicesView -eq [listProductChoices]::CLM) {
+ $productId = $clmProductId
+ Write-Output ""
+
+ $menu = @{}
+ for ($i=1;$i -le $clmPermissionProfiles.count; $i++) {
+ Write-Output "$i. $($clmPermissionProfiles[$i-1].permission_profile_name)"
+ $menu.Add($i,($clmPermissionProfiles[$i-1].permission_profile_id))
+ }
+
+ do {
+ [int]$selection = Read-Host 'Select a CLM permission profile to update'
+ } while ($selection -gt $clmPermissionProfiles.count -or $selection -lt 1);
+
+ $permissionProfileId = $menu.Item($selection)
+} else {
+ $productId = $esignProductId
+ Write-Output ""
+
+ $menu = @{}
+ for ($i=1;$i -le $esignPermissionProfiles.count; $i++) {
+ Write-Output "$i. $($esignPermissionProfiles[$i-1].permission_profile_name)"
+ $menu.Add($i,($esignPermissionProfiles[$i-1].permission_profile_id))
+ }
+
+ do {
+ [int]$selection = Read-Host 'Select an eSignature permission profile to update'
+ } while ($selection -gt $esignPermissionProfiles.count -or $selection -lt 1);
+
+ $permissionProfileId = $menu.Item($selection)
+}
+
+# Construct the request body
+#ds-snippet-start:Admin8Step3
+$body = @"
+{
+ "email": "$emailAddress",
+ "product_permission_profiles": [
+ {
+ "product_id": '$productId',
+ "permission_profile_id": '$permissionProfileId',
+ }
+ ]
+}
+"@
+#ds-snippet-end:Admin8Step3
+
+try {
+ # Display the JSON response
+ Write-Output "Response:"
+#ds-snippet-start:Admin8Step4
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/accounts/${APIAccountId}/products/permission_profiles/users"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -body $body -method POST
+ $response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 4
+#ds-snippet-end:Admin8Step4
+
+ Write-Output "Done"
+}
+catch {
+ Write-Output "Unable to update the permission profiles."
+
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
diff --git a/examples/Admin/eg009DeleteUserProductPermissionProfile.ps1 b/examples/Admin/eg009DeleteUserProductPermissionProfile.ps1
new file mode 100644
index 0000000..ef9ac2f
--- /dev/null
+++ b/examples/Admin/eg009DeleteUserProductPermissionProfile.ps1
@@ -0,0 +1,147 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+$emailAddressFile = ".\config\ESIGN_CLM_USER_EMAIL"
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+$base_path = "https://api-d.docusign.net/management"
+$organizationId=$variables.ORGANIZATION_ID
+
+# Check that we have an email address of created user
+if (Test-Path $emailAddressFile) {
+ $emailAddress = Get-Content $emailAddressFile
+
+ try {
+ $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+ $headers.add("Authorization", "Bearer $accessToken")
+ $headers.add("Content-Type", "application/json")
+
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/users/dsprofile?email=${emailAddress}"
+ $response = Invoke-WebRequest -headers $headers -Uri $uri -body $body -Method GET
+ } catch {
+ Write-Output "The user with stored email address is not present in the account."
+ Write-Output "Please run example 2: 'Create a new active CLM and eSignature user' before running this code example"
+ exit 1
+ }
+} else {
+ Write-Output "Please run example 2: 'Create a new active CLM and eSignature user' before running this code example"
+ exit 1
+}
+
+# Construct your API headers
+#ds-snippet-start:Admin9Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Admin9Step2
+
+try {
+ # Display the JSON response
+ Write-Output "Getting permission profiles by email address..."
+ #ds-snippet-start:Admin9Step3
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/accounts/${APIAccountId}/products/permission_profiles/users?email=${emailAddress}"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+ $productProfiles = $($response.Content | ConvertFrom-Json).product_permission_profiles
+ #ds-snippet-end:Admin9Step3
+
+ Write-Output "Response:"
+ Write-Output ""
+ Write-Output $response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 5
+ Write-Output ""
+}
+catch
+{
+ Write-Output "Error:"
+
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+$clmProductId = "37f013eb-7012-4588-8028-357b39fdbd00"
+$esignProductId = "f6406c68-225c-4e9b-9894-64152a26fa83"
+
+Write-Output ""
+Write-Output "Delete user product permission profile for the following email: " $emailAddress
+Write-Output ""
+
+Enum listProductChoices {
+ CLM = 1;
+ eSignature = 2;
+}
+
+$listProductChoicesView = $null;
+do {
+ Write-Output "$([int][listProductChoices]::CLM)) CLM"
+ Write-Output "$([int][listProductChoices]::eSignature)) eSignature"
+ [int]$listProductChoicesView = Read-Host "Which product permission profile would you like to delete?"
+} while (-not [listProductChoices]::IsDefined([listProductChoices], $listProductChoicesView));
+
+if ($listProductChoicesView -eq [listProductChoices]::CLM) {
+ $productId = $clmProductId
+} else {
+ $productId = $esignProductId
+}
+
+
+foreach ($productProfile in $productProfiles) {
+ if ($productProfile.product_id -eq $productId) {
+ $userHasProductPermissions = "true"
+ }
+}
+
+if ($null -eq $userHasProductPermissions) {
+ Write-Output ""
+ Write-Output "This user was already removed from this product."
+ Write-Output "Please, try another product or run example 2: 'Create a new active CLM and eSignature user' to create a user with both product accesses."
+ Write-Output ""
+} else {
+ # Construct the request body
+#ds-snippet-start:Admin9Step4
+ $body = @"
+ {
+ "user_email": "$emailAddress",
+ "product_ids": [
+ "$productId",
+ ]
+ }
+"@
+#ds-snippet-end:Admin9Step4
+
+ try {
+ # Display the JSON response
+ Write-Output "Response:"
+#ds-snippet-start:Admin9Step5
+ $uri = "${base_path}/v2.1/organizations/${organizationId}/accounts/${APIAccountId}/products/users"
+ Invoke-WebRequest -uri $uri -headers $headers -body $body -method DELETE
+#ds-snippet-end:Admin9Step5
+
+ Write-Output "Product permission profile has been deleted."
+ Write-Output ""
+ Write-Output "Done"
+ } catch {
+ Write-Output "Unable to delete the permission profile."
+
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+ }
+}
diff --git a/examples/Admin/eg010DeleteUserDataFromOrganization.ps1 b/examples/Admin/eg010DeleteUserDataFromOrganization.ps1
new file mode 100644
index 0000000..4113d9b
--- /dev/null
+++ b/examples/Admin/eg010DeleteUserDataFromOrganization.ps1
@@ -0,0 +1,62 @@
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+$basePath = "https://api-d.docusign.net/management"
+$organizationId=$variables.ORGANIZATION_ID
+
+#ds-snippet-start:Admin10Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Admin10Step2
+
+# Get user information
+$emailAddress = Read-Host "Please input the email address of the user whose data will be deleted. Note that this email address should be associated with a user that has been closed for at least 24 hours."
+
+$uri = "${basePath}/v2.1/organizations/${organizationId}/users/dsprofile?email=${emailAddress}"
+$response = Invoke-WebRequest -headers $headers -Uri $uri -body $body -Method GET
+
+$userId = $($response.Content | ConvertFrom-Json).users.id
+$accountId = $($response.Content | ConvertFrom-Json).users.memberships.account_id
+
+# Construct the request body
+#ds-snippet-start:Admin10Step3
+$body = @"
+ {
+ "user_id": "$userId",
+ "memberships": [{
+ "account_id": "$accountId",
+ }]
+ }
+"@
+#ds-snippet-end:Admin10Step3
+
+try {
+ # Display the JSON response
+ Write-Output ""
+ Write-Output "Response:"
+ #ds-snippet-start:Admin10Step4
+ $uri = "${basePath}/v2/data_redaction/organizations/${organizationId}/user"
+
+ $result = Invoke-WebRequest -uri $uri -headers $headers -body $body -method POST
+ $result.content
+ #ds-snippet-end:Admin10Step4
+} catch {
+ Write-Output "Unable to delete the user."
+
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+Write-Output ""
+Write-Output "Done"
diff --git a/examples/Admin/eg011DeleteUserDataFromAccount.ps1 b/examples/Admin/eg011DeleteUserDataFromAccount.ps1
new file mode 100644
index 0000000..b3efeaf
--- /dev/null
+++ b/examples/Admin/eg011DeleteUserDataFromAccount.ps1
@@ -0,0 +1,52 @@
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+$basePath = "https://api-d.docusign.net/management"
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+#ds-snippet-start:Admin11Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Admin11Step2
+
+# Get user information
+$userId = Read-Host "Please enter the user ID of the user whose data will be deleted. Note that this user ID should be associated with a user that has been closed for at least 24 hours."
+
+# Construct the request body
+#ds-snippet-start:Admin11Step3
+$body = @"
+ {
+ "user_id": "$userId",
+ }
+"@
+#ds-snippet-end:Admin11Step3
+
+try {
+ # Display the JSON response
+ Write-Output ""
+ Write-Output "Response:"
+ #ds-snippet-start:Admin11Step4
+ $uri = "${basePath}/v2/data_redaction/accounts/${APIAccountId}/user"
+
+ $result = Invoke-WebRequest -uri $uri -headers $headers -body $body -method POST
+ $result.content
+ #ds-snippet-end:Admin11Step4
+} catch {
+ Write-Output "Unable to delete the user."
+
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+Write-Output ""
+Write-Output "Done"
diff --git a/examples/Admin/eg012CloneAccount.ps1 b/examples/Admin/eg012CloneAccount.ps1
new file mode 100644
index 0000000..83588cc
--- /dev/null
+++ b/examples/Admin/eg012CloneAccount.ps1
@@ -0,0 +1,112 @@
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+$basePath = "https://api-d.docusign.net/management"
+$organizationId=$variables.ORGANIZATION_ID
+
+# Construct your API headers
+#ds-snippet-start:Admin12Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Admin12Step2
+
+$response = $null
+
+try {
+ # Retrieve asset group accounts
+ Write-Output ""
+ Write-Output "Accounts to clone:"
+
+ #ds-snippet-start:Admin12Step3
+ $uri = "${basePath}/v1/organizations/${organizationId}/assetGroups/accounts?compliant=true"
+ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+ #ds-snippet-end:Admin12Step3
+} catch {
+ Write-Output "Unable retrieve asset group accounts."
+
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+$sourceAccountId = $null
+$accounts = $($response.Content | ConvertFrom-Json).assetGroupAccounts
+if ($accounts.count -eq 1){
+ $sourceAccountId = $accounts[0].accountId
+} else {
+ $menu = @{}
+ for ($i=1;$i -le $accounts.count; $i++)
+ { Write-Output "$i. $($accounts[$i-1].accountName)"
+ $menu.Add($i,($accounts[$i-1].accountId))}
+ do {
+ [int]$selection = Read-Host 'Select an account to clone'
+ } while ($selection -gt $accounts.count -or $selection -lt 1);
+ $sourceAccountId = $menu.Item($selection)
+}
+
+$targetAccountName = Read-Host "Please enter the name of the new account"
+$targetAccountFirstName = Read-Host "Please enter the first name of the new account admin"
+$targetAccountLastName = Read-Host "Please enter the last name of the new account admin"
+$targetAccountEmail = Read-Host "Please enter the email address of the new account admin"
+
+#ds-snippet-start:Admin12Step4
+# The country code value is set to "US" for the developer environment
+# In production, set the value to the code for the country of the target account
+$body = @"
+{
+ "sourceAccount": {
+ "id": "$sourceAccountId"
+ },
+ "targetAccount": {
+ "name": "$targetAccountName",
+ "admin": {
+ "firstName": "$targetAccountFirstName",
+ "lastName": "$targetAccountLastName",
+ "email": "$targetAccountEmail"
+ },
+ "countryCode": "US"
+ }
+}
+"@
+#ds-snippet-end:Admin12Step4
+
+try {
+ # Clone source account into new account
+ Write-Output ""
+ Write-Output "Response:"
+
+ #ds-snippet-start:Admin12Step5
+ $uri = "${basePath}/v1/organizations/${organizationId}/assetGroups/accountClone"
+ $response = Invoke-WebRequest -uri $uri -headers $headers -body $body -method POST
+ $response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 5
+ #ds-snippet-end:Admin12Step5
+} catch {
+ Write-Output "Failed to clone an account."
+
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+Write-Output ""
+Write-Output "Done"
diff --git a/examples/Admin/eg013CreateAccount.ps1 b/examples/Admin/eg013CreateAccount.ps1
new file mode 100644
index 0000000..ae23e92
--- /dev/null
+++ b/examples/Admin/eg013CreateAccount.ps1
@@ -0,0 +1,97 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+$base_path = "https://api-d.docusign.net/management"
+$organizationId=$variables.ORGANIZATION_ID
+
+# Construct your API headers
+#ds-snippet-start:Admin13Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Admin13Step2
+
+try {
+ #ds-snippet-start:Admin13Step3
+ $uri = "${base_path}/v2/organizations/${organizationId}/planItems"
+ $response = Invoke-WebRequest -headers $headers -Uri $uri -Method GET
+
+ Write-Output "Results from the GET request:"
+ $response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 5
+ #ds-snippet-end:Admin13Step3
+} catch {
+ Write-Output "Error:"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+$responseJson = $response.Content | ConvertFrom-Json
+$planId = $responseJson.plan_id
+$subscriptionId = $responseJson.subscription_id
+
+$emailAddress = Read-Host "Please enter the email address for the new account"
+$firstName = Read-Host "Please enter the first name for the new account"
+$lastName = Read-Host "Please enter the last name for the new account"
+
+#ds-snippet-start:Admin13Step4
+# The country code value is set to "US" for the developer environment
+# In production, set the value to the code for the country of the target account
+$body = @"
+{
+ "subscriptionDetails": {
+ "id": "$subscriptionId",
+ "planId": "$planId",
+ "modules": []
+ },
+ "targetAccount": {
+ "name": "CreatedThroughAPI",
+ "countryCode": "US",
+ "admin": {
+ "email": "$emailAddress",
+ "firstName": "$firstName",
+ "lastName": "$lastName",
+ "locale": "en"
+ }
+ }
+}
+"@
+#ds-snippet-end:Admin13Step4
+
+try {
+ #ds-snippet-start:Admin13Step5
+ $uri = "${base_path}/v2/organizations/${organizationId}/assetGroups/accountCreate"
+ $response = Invoke-WebRequest -headers $headers -Uri $uri -body $body -Method POST
+
+ Write-Output "Results from the create account method:"
+ $response.Content | ConvertFrom-Json | ConvertTo-Json -Depth 5
+ #ds-snippet-end:Admin13Step5
+}
+catch
+{
+ Write-Output "Error:"
+
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+ exit 1
+}
+
+Write-Output ""
+Write-Output "Done"
diff --git a/examples/Click/eg001CreateClickwrap.ps1 b/examples/Click/eg001CreateClickwrap.ps1
index 6c60997..1ed129b 100644
--- a/examples/Click/eg001CreateClickwrap.ps1
+++ b/examples/Click/eg001CreateClickwrap.ps1
@@ -2,13 +2,18 @@
$accessToken = Get-Content .\config\ds_access_token.txt
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+$clickwrapName = Read-Host "Please input a name for the clickwrap: "
+
# Step 2. Construct your API headers
+#ds-snippet-start:Click1Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Click1Step2
# Step 3. Construct the request body
+#ds-snippet-start:Click1Step3
$body = @"
{
"displaySettings": {
@@ -18,7 +23,6 @@ $body = @"
"format": "modal",
"hasAccept": true,
"mustRead": true,
- "mustView": true,
"requireAccept": true,
"size": "medium",
"documentDisplay": "document"
@@ -31,17 +35,21 @@ $body = @"
"order": 0
}
],
- "name": "Terms of Service",
+ "name": "$clickwrapName",
"requireReacceptance": true
}
"@
+#ds-snippet-end:Click1Step3
# Step 4. Call the Click API
# a) Make a POST call to the clickwraps endpoint to create a clickwrap for an account
# b) Display the JSON structure of the created clickwrap
+#ds-snippet-start:Click1Step4
$uri = "https://demo.docusign.net/clickapi/v1/accounts/$APIAccountId/clickwraps"
$result = Invoke-WebRequest -headers $headers -Uri $uri -UseBasicParsing -Method POST -Body $body
+Write-Output "Response: "
$result.Content
+#ds-snippet-end:Click1Step4
# Store clickwrapId to the file for future reference
$($result.Content | ConvertFrom-Json).clickwrapId > .\config\CLICKWRAP_ID
\ No newline at end of file
diff --git a/examples/Click/eg002ActivateClickwrap.ps1 b/examples/Click/eg002ActivateClickwrap.ps1
index 11750f0..9b06052 100644
--- a/examples/Click/eg002ActivateClickwrap.ps1
+++ b/examples/Click/eg002ActivateClickwrap.ps1
@@ -12,23 +12,30 @@ if (Test-Path .\config\CLICKWRAP_ID) {
}
# Step 2. Construct your API headers
+#ds-snippet-start:Click2Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Click2Step2
# Note: These values are not valid, but are shown for example purposes only!
$VersionNumber = "1"
# Construct your clickwrap JSON body
+#ds-snippet-start:Click2Step3
$body = @"
{
"status" : "active"
}
"@
+#ds-snippet-end:Click2Step3
# a) Make a POST call to updateClickwrapVersionByNumber
# b) Display the JSON structure of the created clickwrap
+#ds-snippet-start:Click2Step4
$uri = "https://demo.docusign.net/clickapi/v1/accounts/$APIAccountId/clickwraps/$ClickWrapId/versions/$VersionNumber"
$result = Invoke-WebRequest -headers $headers -Uri $uri -UseBasicParsing -Method PUT -Body $body
+Write-Output "Response: "
$result.Content
+#ds-snippet-end:Click2Step4
diff --git a/examples/Click/eg003CreateNewClickwrapVersion.ps1 b/examples/Click/eg003CreateNewClickwrapVersion.ps1
index e75926d..c3f39b7 100644
--- a/examples/Click/eg003CreateNewClickwrapVersion.ps1
+++ b/examples/Click/eg003CreateNewClickwrapVersion.ps1
@@ -12,12 +12,15 @@ if (Test-Path .\config\CLICKWRAP_ID) {
}
# Step 2. Construct your API headers
+#ds-snippet-start:Click3Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Click3Step2
# Construct your clickwrap JSON body
+#ds-snippet-start:Click3Step3
$body = @"
{
"name": "Terms of Service",
@@ -25,7 +28,6 @@ $body = @"
"displaySettings": {
"displayName": "Terms of Service v2",
"mustRead": true,
- "mustView": false,
"requireAccept": false,
"downloadable": false,
"sendToEmail": false,
@@ -47,10 +49,14 @@ $body = @"
"requireReacceptance": true
}
"@
+#ds-snippet-end:Click3Step3
# Step 4. Call the Click API
# a) Make a POST call to the versions endpoint to update a specific clickwrap (create a version) for an account
# b) Display the returned JSON structure of the versioned clickwrap
+#ds-snippet-start:Click3Step4
$uri = "https://demo.docusign.net/clickapi/v1/accounts/$APIAccountId/clickwraps/$ClickWrapId/versions"
$result = Invoke-WebRequest -headers $headers -Uri $uri -UseBasicParsing -body $body -Method POST
+Write-Output "Response: "
$result.Content
+#ds-snippet-end:Click3Step4
diff --git a/examples/Click/eg004GetListOfClickwraps.ps1 b/examples/Click/eg004GetListOfClickwraps.ps1
index 988bf76..2842f8d 100644
--- a/examples/Click/eg004GetListOfClickwraps.ps1
+++ b/examples/Click/eg004GetListOfClickwraps.ps1
@@ -3,14 +3,19 @@ $accessToken = Get-Content .\config\ds_access_token.txt
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Step 2. Construct your API headers
+#ds-snippet-start:Click4Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Click4Step2
# Step 3. Call the Click API
# a) Make a GET call to the clickwraps endpoint to retrieve all clickwraps for an account
# b) Display the JSON structure of the returned clickwraps
+#ds-snippet-start:Click4Step3
$uri = "https://demo.docusign.net/clickapi/v1/accounts/$APIAccountId/clickwraps"
$result = Invoke-WebRequest -headers $headers -Uri $uri -UseBasicParsing -Method GET
+Write-Output "Response: "
$result.Content
+#ds-snippet-end:Click4Step3
diff --git a/examples/Click/eg005GetClickwrapResponses.ps1 b/examples/Click/eg005GetClickwrapResponses.ps1
index 5ff769d..80559f2 100644
--- a/examples/Click/eg005GetClickwrapResponses.ps1
+++ b/examples/Click/eg005GetClickwrapResponses.ps1
@@ -12,14 +12,19 @@ if (Test-Path .\config\CLICKWRAP_ID) {
}
# Step 2. Construct your API headers
+#ds-snippet-start:Click5Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Click5Step2
# Step 3. Call the Click API
# a) Make a GET call to the users endpoint to retrieve responses (acceptance) of a specific clickwrap for an account
# b) Display the returned JSON structure of the responses
+#ds-snippet-start:Click5Step3
$uri = "https://demo.docusign.net/clickapi/v1/accounts/$APIAccountId/clickwraps/$ClickWrapId/users"
$result = Invoke-WebRequest -headers $headers -Uri $uri -UseBasicParsing -Method GET
-$result.Content
\ No newline at end of file
+Write-Output "Response: "
+$result.Content
+#ds-snippet-end:Click5Step3
\ No newline at end of file
diff --git a/examples/Click/eg006EmbedClickwrap.ps1 b/examples/Click/eg006EmbedClickwrap.ps1
new file mode 100644
index 0000000..5a30aab
--- /dev/null
+++ b/examples/Click/eg006EmbedClickwrap.ps1
@@ -0,0 +1,87 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Check that we have a clickwrap ID
+if (Test-Path .\config\CLICKWRAP_ID) {
+ $ClickWrapId = Get-Content .\config\CLICKWRAP_ID
+}
+else {
+ Write-Output "Clickwrap ID required. Please run code example 1 - Create Clickwrap"
+ exit 1
+}
+
+# Construct your API headers
+#ds-snippet-start:Click6Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Click6Step2
+
+$client_user_id = Read-Host "Please input a Client User Id (your own unique identifier) for the clickwrap"
+$full_name = Read-Host "Please input a full name"
+$email_address = Read-Host "Please input an email address"
+$company_name = Read-Host "Please input a company name"
+$title = Read-Host "Please input a job title"
+
+# Construct the request body
+#ds-snippet-start:Click6Step3
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+
+@{
+ clientUserId = $client_user_id;
+ documentData =
+ @{
+ fullName = $full_name;
+ email = $email_address;
+ company = $company_name;
+ title = $title;
+ date = $((Get-Date).ToString("yyyy-MM-ddThh:mm:ssK"))
+ };
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:Click6Step3
+
+# Call the Click API
+# a) Make a GET call to the users endpoint to retrieve responses (acceptance) of a specific clickwrap for an account
+# b) Display the returned JSON structure of the responses
+try {
+
+
+ #ds-snippet-start:Click6Step4
+ Invoke-RestMethod `
+ -Uri "https://demo.docusign.net/clickapi/v1/accounts/$APIAccountId/clickwraps/$ClickWrapId/agreements" `
+ -UseBasicParsing `
+ -Method "POST" `
+ -Headers @{
+ "Authorization" = "Bearer $accessToken"
+ "Content-Type" = "application/json"
+ "Accept" = "application/json"
+} `
+-InFile (Resolve-Path $requestData).Path `
+-OutFile $response
+#ds-snippet-end:Click6Step4
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Write-Output "Done."
+
+}
+catch {
+ $errorMessage = $_.ErrorDetails.Message
+ Write-Host ""
+ if($errorMessage){
+ if ( $errorMessage.Contains("There are no active versions for clickwrapId") ) {
+ Write-Host "Clickwrap must be activated. Please run code example 2 - Activate Clickwrap"
+ }
+ elseif ( $errorMessage.Contains("Unable to find Clickwrap with id") ) {
+ Write-Host "Clickwrap ID required. Please run code example 1 - Create Clickwrap"
+ }
+
+}
+}
diff --git a/examples/ConnectedFields/eg001SetConnectedFields.ps1 b/examples/ConnectedFields/eg001SetConnectedFields.ps1
new file mode 100644
index 0000000..e55c31c
--- /dev/null
+++ b/examples/ConnectedFields/eg001SetConnectedFields.ps1
@@ -0,0 +1,301 @@
+$apiUri1 = "https://api-d.docusign.com"
+$apiUri2 = "https://demo.docusign.net/restapi"
+$configPath = ".\config\settings.json"
+$tokenPath = ".\config\ds_access_token.txt"
+$accountIdPath = ".\config\API_ACCOUNT_ID"
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content $configPath -Raw | ConvertFrom-Json
+
+# 1. Obtain your OAuth token
+$accessToken = Get-Content $tokenPath
+
+# Obtain your accountId from demo.docusign.net -- the account id is shown in
+# the drop down on the upper right corner of the screen by your picture or
+# the default picture.
+$accountID = Get-Content $accountIdPath
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$docBase64 = New-TemporaryFile
+
+#ds-snippet-start:ConnectedFields1Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:ConnectedFields1Step2
+
+#ds-snippet-start:ConnectedFields1Step3
+Invoke-RestMethod `
+ -Uri "${apiUri1}/v1/accounts/${accountId}/connected-fields/tab-groups" `
+ -Method 'GET' `
+ -Headers $headers `
+ -OutFile $response
+#ds-snippet-end:ConnectedFields1Step3
+
+#ds-snippet-start:ConnectedFields1Step4
+function Extract-VerifyInfo {
+ param (
+ [string]$responseFile
+ )
+
+ # Read the response file content
+ $content = Get-Content $responseFile -Raw
+
+ # Extract JSON
+ $jsonStart = $content.IndexOf('[')
+ if ($jsonStart -ge 0) {
+ $json = $content.Substring($jsonStart) | ConvertFrom-Json
+ } else {
+ Write-Error "No JSON array found in the response."
+ return
+ }
+
+ # Filter the JSON to keep only verification extension apps
+ $filtered = $json | Where-Object {
+ $_.tabs -and ($_.tabs | Where-Object {
+ ($_.extensionData.actionContract -like "*Verify*") -or
+ ($_.PSObject.Properties['tabLabel'] -and $_.tabLabel -like "*connecteddata*")
+ })
+ }
+
+ return $filtered | ConvertTo-Json -Depth 10
+}
+
+function Prompt-UserChoice {
+ param (
+ [string]$jsonData
+ )
+
+ if (-not $jsonData -or $jsonData -eq "[]") {
+ Write-Host "No data verification were found in the account. Please install a data verification app."
+ Write-Host "You can install a phone number verification extension app by copying the following link to your browser: "
+ Write-Host "https://apps.docusign.com/app-center/app/d16f398f-8b9a-4f94-b37c-af6f9c910c04"
+ exit 1
+ }
+
+ $data = $jsonData | ConvertFrom-Json
+
+ # Extract unique app IDs and application names
+ $uniqueApps = @{}
+ foreach ($item in $data) {
+ if ($item.appId -and $item.tabs[0].extensionData.applicationName) {
+ $uniqueApps[$item.appId] = $item.tabs[0].extensionData.applicationName
+ }
+ }
+
+ # If no unique apps are found
+ if ($uniqueApps.Count -eq 0) {
+ Write-Host "No valid apps found in the JSON data."
+ exit 1
+ }
+
+ # Display available apps
+ Write-Host "Please select an app by entering a number:"
+ $appList = $uniqueApps.Keys | Sort-Object
+ for ($i = 0; $i -lt $appList.Count; $i++) {
+ Write-Host "$($i + 1). $($uniqueApps[$appList[$i]])"
+ }
+
+ # Get user choice
+ $choice = Read-Host "Enter choice (1-$($appList.Count))"
+ if ($choice -match "^\d+$" -and [int]$choice -ge 1 -and [int]$choice -le $appList.Count) {
+ $chosenAppId = $appList[[int]$choice - 1]
+
+ # Filter JSON data for the selected app ID
+ $selectedData = $data | Where-Object { $_.appId -eq $chosenAppId }
+ return $selectedData
+ } else {
+ Write-Host "Invalid choice. Exiting."
+ exit 1
+ }
+}
+
+function Parse-VerificationData {
+ param (
+ $selectedAppId,
+ $tab
+ )
+
+ $connectionKeyData = ''
+ $connectionValueData = ''
+ if ($tab.extensionData.connectionInstances) {
+ $connectionKeyData = $tab.extensionData.connectionInstances[0].connectionKey
+ $connectionValueData = $tab.extensionData.connectionInstances[0].connectionValue
+ }
+
+ # Extract required fields from the first element
+ $extractedData = @{
+ appId = $selectedAppId
+ extensionGroupId = $tab.extensionData.extensionGroupId
+ publisherName = $tab.extensionData.publisherName
+ applicationName = $tab.extensionData.applicationName
+ actionName = $tab.extensionData.actionName
+ actionInputKey = $tab.extensionData.actionInputKey
+ actionContract = $tab.extensionData.actionContract
+ extensionName = $tab.extensionData.extensionName
+ extensionContract = $tab.extensionData.extensionContract
+ requiredForExtension = $tab.extensionData.requiredForExtension
+ tabLabel = $tab.tabLabel
+ connectionKey = $connectionKeyData
+ connectionValue = $connectionValueData
+ }
+
+ return $extractedData
+}
+
+$filteredData = Extract-VerifyInfo -responseFile $response
+
+$selectedApp = Prompt-UserChoice -jsonData $filteredData
+#ds-snippet-end:ConnectedFields1Step4
+
+Write-Output "Sending the envelope request to Docusign..."
+
+# Fetch doc and encode
+$docPath = ".\demo_documents\World_Wide_Corp_Lorem.pdf"
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path $docPath))) > $docBase64
+
+# Construct the request body
+#ds-snippet-start:ConnectedFields1Step5
+function Get-Extension-Data {
+ param (
+ $verificationData
+ )
+
+ return @{
+ extensionGroupId = $verificationData.extensionGroupId;
+ publisherName = $verificationData.publisherName;
+ applicationId = $verificationData.appId;
+ applicationName = $verificationData.applicationName;
+ actionName = $verificationData.actionName;
+ actionContract = $verificationData.actionContract;
+ extensionName = $verificationData.extensionName;
+ extensionContract = $verificationData.extensionContract;
+ requiredForExtension = $verificationData.requiredForExtension;
+ actionInputKey = $verificationData.actionInputKey;
+ extensionPolicy = "MustVerifyToSign";
+ connectionInstances = @(
+ @{
+ connectionKey = $verificationData.connectionKey;
+ connectionValue = $verificationData.connectionValue;
+ };
+ );
+ };
+}
+
+function Make-Text-Tab {
+ param (
+ $verificationData,
+ $extensionData,
+ $textTabCount
+ )
+
+ return @{
+ requireInitialOnSharedChange = "false";
+ requireAll = "false";
+ name = $verificationData.applicationName;
+ required = "true";
+ locked = "false";
+ disableAutoSize = "false";
+ maxLength = "4000";
+ tabLabel = $verificationData.tabLabel;
+ font = "lucidaconsole";
+ fontColor = "black";
+ fontSize = "size9";
+ documentId = "1";
+ recipientId = "1";
+ pageNumber = "1";
+ xPosition = [string](70 + 100 * [math]::Floor($textTabCount / 10));
+ yPosition = [string](560 + 20 * ($textTabCount % 10));
+ width = "84";
+ height = "22";
+ templateRequired = "false";
+ tabType = "text";
+ tooltip = $verificationData.actionInputKey;
+ extensionData = $extensionData
+ };
+}
+
+function Make-Text-Tab-List {
+ param (
+ $app
+ )
+
+ $text_tabs = @()
+ foreach ($tab in $app.tabs | Where-Object { $_.tabLabel -notlike '*SuggestionInput*' }) {
+ $verificationData = Parse-VerificationData -selectedAppId $app.appId -tab $tab
+ $extensionData = Get-Extension-Data -verificationData $verificationData
+
+ $text_tab = Make-Text-Tab -verificationData $verificationData -extensionData $extensionData -textTabCount $text_tabs.Count
+ $text_tabs += $text_tab
+ }
+
+ return $text_tabs
+}
+
+$textTabs = Make-Text-Tab-List -app $selectedApp
+
+@{
+ emailSubject = "Please sign this document";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $docBase64)";
+ name = "Lorem Ipsum";
+ fileExtension = "pdf";
+ documentId = "1";
+ };
+ );
+ status = "sent";
+ recipients = @{
+ signers = @(
+ @{
+ email = $variables.SIGNER_EMAIL;
+ name = $variables.SIGNER_NAME;
+ recipientId = "1";
+ routingOrder = "1";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "/sn1/";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ );
+ textTabs = @($textTabs);
+ };
+ };
+ );
+ };
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:ConnectedFields1Step5
+
+#ds-snippet-start:ConnectedFields1Step6
+Invoke-RestMethod `
+ -Uri "${apiUri2}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:ConnectedFields1Step6
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+# pull out the envelopeId
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+
+# Save the envelope id for use by other scripts
+Write-Output "EnvelopeId: $envelopeId"
+Write-Output $envelopeId > .\config\ENVELOPE_ID
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $docBase64
+
+Write-Output "Done. When signing the envelope, ensure the connection to your data verification extension app is active."
diff --git a/examples/ID_Evidence/retrieveEvents.ps1 b/examples/ID_Evidence/retrieveEvents.ps1
new file mode 100644
index 0000000..4b6517a
--- /dev/null
+++ b/examples/ID_Evidence/retrieveEvents.ps1
@@ -0,0 +1,127 @@
+# Required values: $oAuthAccessToken, $APIaccountId, $envelopeId
+# Returns: $recipientIdGuid, $resourceToken, $copy_of_id_front
+
+$oAuthAccessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Check that we have an IDV Envelope ID
+if (-not (Test-Path .\config\IDV_ENVELOPE_ID)) {
+ Write-Output "An IDV Envelope ID is needed. Run eSignature example 23 'Signing via Email with IDV Authentication' and complete IDV before running this code example."
+ exit 0
+}
+
+$envelopeId = Get-Content .\config\IDV_ENVELOPE_ID
+
+# Construct your API headers
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization","Bearer ${oAuthAccessToken}")
+$headers.add("Accept","application/json, text/plain, */*")
+$headers.add("Content-Type","application/json;charset=UTF-8")
+
+# Retrieve recipient data
+#ds-snippet-start:IDEvidence1Step2
+$uri = "https://demo.docusign.net/restapi/v2.1/accounts/${APIaccountId}/envelopes/${envelopeId}/recipients"
+
+write-host "Retrieving recipient data"
+
+try{
+ write-host "Response:"
+ $result = Invoke-RestMethod -uri $uri -headers $headers -method GET
+ $result.content
+ #Obtain the recipient ID GUID from the API response
+ $recipientIdGuid = $result.signers.recipientIdGuid
+ }
+#ds-snippet-end
+catch{
+ $int = 0
+ foreach($header in $_.Exception.Response.Headers){
+ #On error, display the error, the line that triggered the error, and the TraceToken
+ if($header -eq "X-DocuSign-TraceToken"){ write-host "TraceToken : " $_.Exception.Response.Headers[$int]}
+ $int++
+ }
+ write-host "Error : "$_.ErrorDetails.Message
+ write-host "Command : "$_.InvocationInfo.Line
+}
+
+write-host "recipientIdGuid: " $recipientIdGuid
+# Save the Recipient ID Guid for use by other scripts
+Write-Output $recipientIdGuid > .\config\RECIPIENT_ID_GUID
+
+
+# Construct your API headers
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization","Bearer ${oAuthAccessToken}")
+$headers.add("Accept","application/json, text/plain, */*")
+$headers.add("Content-Type","application/json;charset=UTF-8")
+
+# Obtain identity proof token (resource token)
+#ds-snippet-start:IDEvidence1Step3
+$uri = "https://demo.docusign.net/restapi/v2.1/accounts/${APIaccountId}/envelopes/${envelopeId}/recipients/${recipientIdGuid}/identity_proof_token"
+
+write-host "Attempting to retrieve your identity proof token"
+
+try{
+ write-host "Response:"
+ $result = Invoke-RestMethod -uri $uri -headers $headers -method POST
+ $result.content
+ #Obtain the resourceToken from the API response
+ $resourceToken = $result.resourceToken
+ }
+#ds-snippet-end
+catch{
+ $int = 0
+ foreach($header in $_.Exception.Response.Headers){
+ #On error, display the error, the line that triggered the error, and the TraceToken
+ if($header -eq "X-DocuSign-TraceToken"){ write-host "TraceToken : " $_.Exception.Response.Headers[$int]}
+ $int++
+ }
+ write-host "Error : "$_.ErrorDetails.Message
+ write-host "Command : "$_.InvocationInfo.Line
+}
+
+write-host "resourceToken: " $resourceToken
+# Save the Resource Token for use by other scripts
+Write-Output $resourceToken > .\config\RESOURCE_TOKEN.txt
+
+#ds-snippet-start:IDEvidence1Step4
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization","Bearer $resourceToken")
+$headers.add("Accept","application/json, text/plain, */*")
+$headers.add("Content-Type","application/json;charset=UTF-8")
+#ds-snippet-end
+
+# Retrieve recipient data
+#ds-snippet-start:IDEvidence1Step5
+$uri = "https://proof-d.docusign.net/api/v1/events/person/$recipientIdGuid.json"
+
+write-host "Retrieving recipient data"
+
+try{
+ write-host "Response:"
+ $result = Invoke-RestMethod -uri $uri -headers $headers -UseBasicParsing -method GET
+ #Obtain the Event List from the API response
+ $EventList = $result.events | ConvertTo-Json
+
+ write-host $EventList
+ }
+#ds-snippet-end
+
+catch{
+ $int = 0
+ foreach($header in $_.Exception.Response.Headers){
+ #On error, display the error, the line that triggered the error, and the TraceToken
+ if($header -eq "X-DocuSign-TraceToken"){ write-host "TraceToken : " $_.Exception.Response.Headers[$int]}
+ $int++
+ }
+ write-host "Error : "$_.ErrorDetails.Message
+ write-host "Command : "$_.InvocationInfo.Line
+}
+
+$copy_of_id_front = $result.events.data.copy_of_id_front | ConvertTo-Json
+write-host "copy_of_id_front:"$copy_of_id_front
+# Save the copy_of_id_front URL for use by other scripts
+Write-Output $copy_of_id_front > .\config\COPY_OF_ID_FRONT_URL.txt
+
+# cleanup
+Remove-Item $result
+Write-Output "Done."
diff --git a/examples/ID_Evidence/retrieveMedia.ps1 b/examples/ID_Evidence/retrieveMedia.ps1
new file mode 100644
index 0000000..49cb86f
--- /dev/null
+++ b/examples/ID_Evidence/retrieveMedia.ps1
@@ -0,0 +1,166 @@
+# Required values: $oAuthAccessToken, $APIaccountId, $envelopeId
+# Returns: $recipientIdGuid, $resourceToken, $copy_of_id_front
+
+$oAuthAccessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Check that we have an IDV Envelope ID
+if (-not (Test-Path .\config\IDV_ENVELOPE_ID)) {
+ Write-Output "An IDV Envelope ID is needed. Run eSignature example 23 'Signing via Email with IDV Authentication' and complete IDV before running this code example."
+ exit 0
+}
+
+# Check that we have Copy of ID front URL and Resource Token in config file
+if ((-not (Test-Path .\config\COPY_OF_ID_FRONT_URL.txt)) -or (-not (Test-Path .\config\RESOURCE_TOKEN.txt))) {
+ Write-Output "Copy of ID Front URL and Resource Token are needed. Run ID Evidence example 1 'Retrieve events' before running this code example."
+ exit 0
+}
+
+$envelopeId = Get-Content .\config\IDV_ENVELOPE_ID
+
+# Construct your API headers
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization","Bearer ${oAuthAccessToken}")
+$headers.add("Accept","application/json, text/plain, */*")
+$headers.add("Content-Type","application/json;charset=UTF-8")
+
+# Retrieve recipient data
+#ds-snippet-start:IDEvidence2Step2
+$uri = "https://demo.docusign.net/restapi/v2.1/accounts/${APIaccountId}/envelopes/${envelopeId}/recipients"
+
+write-host "Retrieving recipient data"
+
+try{
+ write-host "Response:"
+ $result = Invoke-RestMethod -uri $uri -headers $headers -method GET
+ $result.content
+ #Obtain the recipient ID GUID from the API response
+ $recipientIdGuid = $result.signers.recipientIdGuid
+ }
+#ds-snippet-end
+catch{
+ $int = 0
+ foreach($header in $_.Exception.Response.Headers){
+ #On error, display the error, the line that triggered the error, and the TraceToken
+ if($header -eq "X-DocuSign-TraceToken"){ write-host "TraceToken : " $_.Exception.Response.Headers[$int]}
+ $int++
+ }
+ write-host "Error : "$_.ErrorDetails.Message
+ write-host "Command : "$_.InvocationInfo.Line
+}
+
+write-host "recipientIdGuid: " $recipientIdGuid
+# Save the Recipient ID Guid for use by other scripts
+Write-Output $recipientIdGuid > .\config\RECIPIENT_ID_GUID
+
+# Construct your API headers
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization","Bearer ${oAuthAccessToken}")
+$headers.add("Accept","application/json, text/plain, */*")
+$headers.add("Content-Type","application/json;charset=UTF-8")
+
+# Obtain identity proof token (resource token)
+#ds-snippet-start:IDEvidence2Step3
+$uri = "https://demo.docusign.net/restapi/v2.1/accounts/${APIaccountId}/envelopes/${envelopeId}/recipients/${recipientIdGuid}/identity_proof_token"
+
+write-host "Attempting to retrieve your identity proof token"
+
+try{
+ write-host "Response:"
+ $result = Invoke-RestMethod -uri $uri -headers $headers -method POST
+ $result.content
+ #Obtain the resourceToken from the API response
+ $resourceToken = $result.resourceToken
+ }
+#ds-snippet-end
+catch{
+ $int = 0
+ foreach($header in $_.Exception.Response.Headers){
+ #On error, display the error, the line that triggered the error, and the TraceToken
+ if($header -eq "X-DocuSign-TraceToken"){ write-host "TraceToken : " $_.Exception.Response.Headers[$int]}
+ $int++
+ }
+ write-host "Error : "$_.ErrorDetails.Message
+ write-host "Command : "$_.InvocationInfo.Line
+}
+
+write-host "resourceToken: " $resourceToken
+
+# Save the Resource Token for use by other scripts
+Write-Output $resourceToken > .\config\RESOURCE_TOKEN.txt
+
+#ds-snippet-start:IDEvidence2Step4
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization","Bearer $resourceToken")
+$headers.add("Accept","application/json, text/plain, */*")
+$headers.add("Content-Type","application/json;charset=UTF-8")
+#ds-snippet-end
+
+# Retrieve recipient data
+#ds-snippet-start:IDEvidence2Step5
+$uri = "https://proof-d.docusign.net/api/v1/events/person/$recipientIdGuid.json"
+
+write-host "Retrieving recipient data"
+
+try{
+ write-host "Response:"
+ $result = Invoke-RestMethod -uri $uri -headers $headers -UseBasicParsing -method GET
+ #Obtain the Event List from the API response
+ $EventList = $result.events | ConvertTo-Json
+ write-host $EventList
+#ds-snippet-end
+}catch{
+ $int = 0
+ foreach($header in $_.Exception.Response.Headers){
+ #On error, display the error, the line that triggered the error, and the TraceToken
+ if($header -eq "X-DocuSign-TraceToken"){ write-host "TraceToken : " $_.Exception.Response.Headers[$int]}
+ $int++
+ }
+ write-host "Error : "$_.ErrorDetails.Message
+ write-host "Command : "$_.InvocationInfo.Line
+}
+
+$copy_of_id_front = $result.events.data.copy_of_id_front | ConvertTo-Json
+write-host "copy_of_id_front:"$copy_of_id_front
+# Save the copy_of_id_front URL for use by other scripts
+Write-Output $copy_of_id_front > .\config\COPY_OF_ID_FRONT_URL.txt
+
+
+# Required values: $resourceToken, $copy_of_id_front
+$copy_of_id_front = Get-Content .\config\COPY_OF_ID_FRONT_URL.txt
+$recipientIdGuid = Get-Content .\config\RECIPIENT_ID_GUID
+$resourceToken = Get-Content .\config\RESOURCE_TOKEN.txt
+
+
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization","Bearer $resourceToken")
+$headers.add("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*")
+$headers.add("Content-Type","image/jpg")
+
+# return a base-64 image of the front of the photo ID
+#ds-snippet-start:IDEvidence2Step6
+$uri = $copy_of_id_front -replace '"'
+
+write-host "Retrieving recipient data"
+
+try{
+ #Obtain the base-64 image
+ $result = Invoke-RestMethod -uri $uri -headers $headers -method GET
+ $result | Out-File -FilePath .\id_front_base64_image.txt
+ write-host "Response: Saved to .\id_front_base64_image.txt"
+ }
+#ds-snippet-end
+catch{
+ $int = 0
+ foreach($header in $_.Exception.Response.Headers){
+ #On error, display the error, the line that triggered the error, and the TraceToken
+ if($header -eq "X-DocuSign-TraceToken"){ write-host "TraceToken : " $_.Exception.Response.Headers[$int]}
+ $int++
+ }
+ write-host "Error : "$_.ErrorDetails.Message
+ write-host "Command : "$_.InvocationInfo.Line
+}
+
+# cleanup
+Remove-Item $result
+Write-Output "Done."
diff --git a/examples/Maestro/createWorkflowUtils.ps1 b/examples/Maestro/createWorkflowUtils.ps1
new file mode 100644
index 0000000..4b18b05
--- /dev/null
+++ b/examples/Maestro/createWorkflowUtils.ps1
@@ -0,0 +1,594 @@
+. "utils/invokeScript.ps1"
+
+# Check that we have a template id
+if (-not (Test-Path .\config\TEMPLATE_ID)) {
+ Write-Output "Creating template"
+ Invoke-Script -Command "`".\examples\eSignature\eg008CreateTemplate.ps1`""
+}
+
+$templateId = Get-Content "config/TEMPLATE_ID"
+
+Write-Host "Creating a new workflow"
+
+$signerId = [guid]::NewGuid().ToString().ToLower()
+$ccId = [guid]::NewGuid().ToString().ToLower()
+$triggerId = "wfTrigger"
+
+$accessToken = Get-Content "config/ds_access_token.txt"
+$accountId = Get-Content "config/API_ACCOUNT_ID"
+
+$base_path = "https://demo.services.docusign.net/aow-manage/v1.0"
+
+$headers = @{
+ 'Authorization' = "Bearer $accessToken"
+ 'Accept' = 'application/json'
+ 'Content-Type' = 'application/json'
+}
+
+$body = @"
+{
+ "workflowDefinition": {
+ "workflowName": "Example workflow - send invite to signer",
+ "workflowDescription": "",
+ "accountId": "$accountId",
+ "documentVersion": "1.0.0",
+ "schemaVersion": "1.0.0",
+ "participants": {
+ "$signerId": {
+ "participantRole": "Signer"
+ },
+ "$ccId": {
+ "participantRole": "CC"
+ }
+ },
+ "trigger": {
+ "name": "Get_URL",
+ "type": "Http",
+ "httpType": "Get",
+ "id": "$triggerId",
+ "input": {
+ "metadata": {
+ "customAttributes": {}
+ },
+ "payload": {
+ "dacId_$triggerId": {
+ "source": "step",
+ "propertyName": "dacId",
+ "stepId": "$triggerId"
+ },
+ "id_$triggerId": {
+ "source": "step",
+ "propertyName": "id",
+ "stepId": "$triggerId"
+ },
+ "signerName_$triggerId": {
+ "source": "step",
+ "propertyName": "signerName",
+ "stepId": "$triggerId"
+ },
+ "signerEmail_$triggerId": {
+ "source": "step",
+ "propertyName": "signerEmail",
+ "stepId": "$triggerId"
+ },
+ "ccName_$triggerId": {
+ "source": "step",
+ "propertyName": "ccName",
+ "stepId": "$triggerId"
+ },
+ "ccEmail_$triggerId": {
+ "source": "step",
+ "propertyName": "ccEmail",
+ "stepId": "$triggerId"
+ }
+ },
+ "participants": {}
+ },
+ "output": {
+ "dacId_$triggerId": {
+ "source": "step",
+ "propertyName": "dacId",
+ "stepId": "$triggerId"
+ }
+ },
+ "type": "API"
+ },
+ "variables": {
+ "dacId_$triggerId": {
+ "source": "step",
+ "propertyName": "dacId",
+ "stepId": "$triggerId"
+ },
+ "id_$triggerId": {
+ "source": "step",
+ "propertyName": "id",
+ "stepId": "$triggerId"
+ },
+ "signerName_$triggerId": {
+ "source": "step",
+ "propertyName": "signerName",
+ "stepId": "$triggerId"
+ },
+ "signerEmail_$triggerId": {
+ "source": "step",
+ "propertyName": "signerEmail",
+ "stepId": "$triggerId"
+ },
+ "ccName_$triggerId": {
+ "source": "step",
+ "propertyName": "ccName",
+ "stepId": "$triggerId"
+ },
+ "ccEmail_$triggerId": {
+ "source": "step",
+ "propertyName": "ccEmail",
+ "stepId": "$triggerId"
+ },
+ "envelopeId_step2": {
+ "source": "step",
+ "propertyName": "envelopeId",
+ "stepId": "step2",
+ "type": "String"
+ },
+ "combinedDocumentsBase64_step2": {
+ "source": "step",
+ "propertyName": "combinedDocumentsBase64",
+ "stepId": "step2",
+ "type": "File"
+ },
+ "fields.signer.text.value_step2": {
+ "source": "step",
+ "propertyName": "fields.signer.text.value",
+ "stepId": "step2",
+ "type": "String"
+ }
+ },
+ "steps": [
+ {
+ "id": "step2",
+ "name": "Get Signatures",
+ "moduleName": "ESign",
+ "configurationProgress": "Completed",
+ "type": "DS-Sign",
+ "config": {
+ "participantId": "$signerId"
+ },
+ "input": {
+ "isEmbeddedSign": true,
+ "documents": [
+ {
+ "type": "FromDSTemplate",
+ "eSignTemplateId": "$templateId"
+ }
+ ],
+ "emailSubject": "Please sign this document",
+ "emailBlurb": "",
+ "recipients": {
+ "signers": [
+ {
+ "defaultRecipient": "false",
+ "tabs": {
+ "signHereTabs": [
+ {
+ "stampType": "signature",
+ "name": "SignHere",
+ "tabLabel": "Sign Here",
+ "scaleValue": "1",
+ "optional": "false",
+ "documentId": "1",
+ "recipientId": "1",
+ "pageNumber": "1",
+ "xPosition": "191",
+ "yPosition": "148",
+ "tabId": "1",
+ "tabType": "signhere"
+ }
+ ],
+ "textTabs": [
+ {
+ "requireAll": "false",
+ "value": "",
+ "required": "false",
+ "locked": "false",
+ "concealValueOnDocument": "false",
+ "disableAutoSize": "false",
+ "tabLabel": "text",
+ "font": "helvetica",
+ "fontSize": "size14",
+ "localePolicy": {},
+ "documentId": "1",
+ "recipientId": "1",
+ "pageNumber": "1",
+ "xPosition": "153",
+ "yPosition": "230",
+ "width": "84",
+ "height": "23",
+ "tabId": "2",
+ "tabType": "text"
+ }
+ ],
+ "checkboxTabs": [
+ {
+ "name": "",
+ "tabLabel": "ckAuthorization",
+ "selected": "false",
+ "selectedOriginal": "false",
+ "requireInitialOnSharedChange": "false",
+ "required": "true",
+ "locked": "false",
+ "documentId": "1",
+ "recipientId": "1",
+ "pageNumber": "1",
+ "xPosition": "75",
+ "yPosition": "417",
+ "width": "0",
+ "height": "0",
+ "tabId": "3",
+ "tabType": "checkbox"
+ },
+ {
+ "name": "",
+ "tabLabel": "ckAuthentication",
+ "selected": "false",
+ "selectedOriginal": "false",
+ "requireInitialOnSharedChange": "false",
+ "required": "true",
+ "locked": "false",
+ "documentId": "1",
+ "recipientId": "1",
+ "pageNumber": "1",
+ "xPosition": "75",
+ "yPosition": "447",
+ "width": "0",
+ "height": "0",
+ "tabId": "4",
+ "tabType": "checkbox"
+ },
+ {
+ "name": "",
+ "tabLabel": "ckAgreement",
+ "selected": "false",
+ "selectedOriginal": "false",
+ "requireInitialOnSharedChange": "false",
+ "required": "true",
+ "locked": "false",
+ "documentId": "1",
+ "recipientId": "1",
+ "pageNumber": "1",
+ "xPosition": "75",
+ "yPosition": "478",
+ "width": "0",
+ "height": "0",
+ "tabId": "5",
+ "tabType": "checkbox"
+ },
+ {
+ "name": "",
+ "tabLabel": "ckAcknowledgement",
+ "selected": "false",
+ "selectedOriginal": "false",
+ "requireInitialOnSharedChange": "false",
+ "required": "true",
+ "locked": "false",
+ "documentId": "1",
+ "recipientId": "1",
+ "pageNumber": "1",
+ "xPosition": "75",
+ "yPosition": "508",
+ "width": "0",
+ "height": "0",
+ "tabId": "6",
+ "tabType": "checkbox"
+ }
+ ],
+ "radioGroupTabs": [
+ {
+ "documentId": "1",
+ "recipientId": "1",
+ "groupName": "radio1",
+ "radios": [
+ {
+ "pageNumber": "1",
+ "xPosition": "142",
+ "yPosition": "384",
+ "value": "white",
+ "selected": "false",
+ "tabId": "7",
+ "required": "false",
+ "locked": "false",
+ "bold": "false",
+ "italic": "false",
+ "underline": "false",
+ "fontColor": "black",
+ "fontSize": "size7"
+ },
+ {
+ "pageNumber": "1",
+ "xPosition": "74",
+ "yPosition": "384",
+ "value": "red",
+ "selected": "false",
+ "tabId": "8",
+ "required": "false",
+ "locked": "false",
+ "bold": "false",
+ "italic": "false",
+ "underline": "false",
+ "fontColor": "black",
+ "fontSize": "size7"
+ },
+ {
+ "pageNumber": "1",
+ "xPosition": "220",
+ "yPosition": "384",
+ "value": "blue",
+ "selected": "false",
+ "tabId": "9",
+ "required": "false",
+ "locked": "false",
+ "bold": "false",
+ "italic": "false",
+ "underline": "false",
+ "fontColor": "black",
+ "fontSize": "size7"
+ }
+ ],
+ "shared": "false",
+ "requireInitialOnSharedChange": "false",
+ "requireAll": "false",
+ "tabType": "radiogroup",
+ "value": "",
+ "originalValue": ""
+ }
+ ],
+ "listTabs": [
+ {
+ "listItems": [
+ {
+ "text": "Red",
+ "value": "red",
+ "selected": "false"
+ },
+ {
+ "text": "Orange",
+ "value": "orange",
+ "selected": "false"
+ },
+ {
+ "text": "Yellow",
+ "value": "yellow",
+ "selected": "false"
+ },
+ {
+ "text": "Green",
+ "value": "green",
+ "selected": "false"
+ },
+ {
+ "text": "Blue",
+ "value": "blue",
+ "selected": "false"
+ },
+ {
+ "text": "Indigo",
+ "value": "indigo",
+ "selected": "false"
+ },
+ {
+ "text": "Violet",
+ "value": "violet",
+ "selected": "false"
+ }
+ ],
+ "value": "",
+ "originalValue": "",
+ "required": "false",
+ "locked": "false",
+ "requireAll": "false",
+ "tabLabel": "list",
+ "font": "helvetica",
+ "fontSize": "size14",
+ "localePolicy": {},
+ "documentId": "1",
+ "recipientId": "1",
+ "pageNumber": "1",
+ "xPosition": "142",
+ "yPosition": "291",
+ "width": "78",
+ "height": "0",
+ "tabId": "10",
+ "tabType": "list"
+ }
+ ],
+ "numericalTabs": [
+ {
+ "validationType": "currency",
+ "value": "",
+ "required": "false",
+ "locked": "false",
+ "concealValueOnDocument": "false",
+ "disableAutoSize": "false",
+ "tabLabel": "numericalCurrency",
+ "font": "helvetica",
+ "fontSize": "size14",
+ "localePolicy": {
+ "cultureName": "en-US",
+ "currencyPositiveFormat": "csym_1_comma_234_comma_567_period_89",
+ "currencyNegativeFormat": "opar_csym_1_comma_234_comma_567_period_89_cpar",
+ "currencyCode": "usd"
+ },
+ "documentId": "1",
+ "recipientId": "1",
+ "pageNumber": "1",
+ "xPosition": "163",
+ "yPosition": "260",
+ "width": "84",
+ "height": "0",
+ "tabId": "11",
+ "tabType": "numerical"
+ }
+ ]
+ },
+ "signInEachLocation": "false",
+ "agentCanEditEmail": "false",
+ "agentCanEditName": "false",
+ "requireUploadSignature": "false",
+ "name": {
+ "source": "step",
+ "propertyName": "signerName",
+ "stepId": "$triggerId"
+ },
+ "email": {
+ "source": "step",
+ "propertyName": "signerEmail",
+ "stepId": "$triggerId"
+ },
+ "recipientId": "1",
+ "recipientIdGuid": "00000000-0000-0000-0000-000000000000",
+ "accessCode": "",
+ "requireIdLookup": "false",
+ "routingOrder": "1",
+ "note": "",
+ "roleName": "signer",
+ "completedCount": "0",
+ "deliveryMethod": "email",
+ "templateLocked": "false",
+ "templateRequired": "false",
+ "inheritEmailNotificationConfiguration": "false",
+ "recipientType": "signer"
+ }
+ ],
+ "carbonCopies": [
+ {
+ "agentCanEditEmail": "false",
+ "agentCanEditName": "false",
+ "name": {
+ "source": "step",
+ "propertyName": "ccName",
+ "stepId": "$triggerId"
+ },
+ "email": {
+ "source": "step",
+ "propertyName": "ccEmail",
+ "stepId": "$triggerId"
+ },
+ "recipientId": "2",
+ "recipientIdGuid": "00000000-0000-0000-0000-000000000000",
+ "accessCode": "",
+ "requireIdLookup": "false",
+ "routingOrder": "2",
+ "note": "",
+ "roleName": "cc",
+ "completedCount": "0",
+ "deliveryMethod": "email",
+ "templateLocked": "false",
+ "templateRequired": "false",
+ "inheritEmailNotificationConfiguration": "false",
+ "recipientType": "carboncopy"
+ }
+ ],
+ "certifiedDeliveries": []
+ }
+ },
+ "output": {
+ "envelopeId_step2": {
+ "source": "step",
+ "propertyName": "envelopeId",
+ "stepId": "step2",
+ "type": "String"
+ },
+ "combinedDocumentsBase64_step2": {
+ "source": "step",
+ "propertyName": "combinedDocumentsBase64",
+ "stepId": "step2",
+ "type": "File"
+ },
+ "fields.signer.text.value_step2": {
+ "source": "step",
+ "propertyName": "fields.signer.text.value",
+ "stepId": "step2",
+ "type": "String"
+ }
+ }
+ },
+ {
+ "id": "step3",
+ "name": "Show a Confirmation Screen",
+ "moduleName": "ShowConfirmationScreen",
+ "configurationProgress": "Completed",
+ "type": "DS-ShowScreenStep",
+ "config": {
+ "participantId": "$signerId"
+ },
+ "input": {
+ "httpType": "Post",
+ "payload": {
+ "participantId": "$signerId",
+ "confirmationMessage": {
+ "title": "Tasks complete",
+ "description": "You have completed all your workflow tasks."
+ }
+ }
+ },
+ "output": {},
+ "triggerType": "API"
+ }
+ ]
+ }
+}
+"@
+
+# Create temporary file for response
+$response = New-TemporaryFile
+
+# Send request to create new workflow
+try {
+ $workflowDefinition = Invoke-RestMethod -Uri "$base_path/management/accounts/$accountId/workflowDefinitions" -Method POST -Headers $headers -body $body
+
+ $workflow_id = $workflowDefinition.workflowDefinitionId
+ Write-Host "Workflow ID: $workflow_id"
+}
+catch {
+ Write-Host ""
+ Write-Host "Unable to create a new workflow"
+ Write-Host ""
+ Get-Content $workflowDefinition.FullName
+ Exit 0
+}
+
+# Define redirect_url
+$redirect_url = "http://localhost:8080"
+
+if (-not (Test-Path -Path "config/WORKFLOW_ID")) {
+ New-Item -ItemType File -Path "config/WORKFLOW_ID"
+}
+
+# Publish workflow
+$published = $false
+while (-not $published) {
+ try {
+ Invoke-RestMethod -Uri "$base_path/management/accounts/$accountId/workflowDefinitions/$workflow_id/publish?isPreRunCheck=true" -Method POST -Headers $Headers
+
+ $published = $true
+ $workflow_id | Out-File -FilePath "config/WORKFLOW_ID"
+ Write-Host "Successfully created and published workflow $workflow_id, ID saved to config/WORKFLOW_ID"
+ }
+ catch {
+ $message = $($_ | ConvertFrom-Json).message
+ Write-Host $message
+ if ($message -eq "Consent required") {
+ $consentUrl = $($_ | ConvertFrom-Json).consentUrl
+ Write-Host ""
+ Write-Host "Please grant consent at the following URL to publish this workflow: $consentUrl&host=$redirect_url"
+
+ # Wait for user to press Enter
+ Read-Host "Press Enter to continue"
+ } else {
+ Write-Host $message
+ Exit 0
+ }
+ }
+}
+
+# Remove the temporary files
+Remove-Item $response
\ No newline at end of file
diff --git a/examples/Maestro/eg001TriggerWorkflow.ps1 b/examples/Maestro/eg001TriggerWorkflow.ps1
new file mode 100644
index 0000000..bb479ad
--- /dev/null
+++ b/examples/Maestro/eg001TriggerWorkflow.ps1
@@ -0,0 +1,107 @@
+. "utils/invokeScript.ps1"
+
+# Trigger a workflow
+if (-not (Test-Path .\config\WORKFLOW_ID)) {
+ # create workflow
+ Invoke-Script -Command "`".\examples\Maestro\createWorkflowUtils.ps1`""
+}
+
+$workflowId = Get-Content .\config\WORKFLOW_ID
+
+# check that create workflow script ran successfully
+if (Test-Path .\config\WORKFLOW_ID) {
+ $workflowId = Get-Content .\config\WORKFLOW_ID
+} else {
+ Write-Output "Please create a workflow before running this example"
+ exit 1
+}
+
+$base_path = "https://demo.services.docusign.net/v1"
+
+# Step 1: Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# temp files:
+$response = New-TemporaryFile
+
+# Construct your API headers
+#ds-snippet-start:Maestro1Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Maestro1Step2
+
+Write-Output "Attempting to retrieve the workflow definition..."
+
+#ds-snippet-start:Maestro1Step3
+Invoke-RestMethod `
+ -Uri "${base_path}/accounts/${accountId}/workflows/${workflowId}/trigger-requirements" `
+ -Method 'GET' `
+ -Headers $headers `
+ -OutFile $response
+
+$jsonContent = Get-Content -Path $response -Raw | ConvertFrom-Json
+$triggerUrl = $jsonContent.trigger_http_config.url
+$triggerUrl = $triggerUrl -replace "\\u0026", "&"
+#ds-snippet-end:Maestro1Step3
+
+$instance_name = Read-Host "Please input a name for the workflow instance"
+$signerName = Read-Host "Please input the full name for the signer participant"
+$signerEmail = Read-Host "Please input an email for the signer participant"
+$ccName = Read-Host "Please input the full name for the cc participant"
+$ccEmail = Read-Host "Please input an email for the cc participant"
+
+#ds-snippet-start:Maestro1Step4
+$body = @"
+{
+ "instance_name": "$instance_name",
+ "trigger_inputs": {
+ "signerEmail": "$signerEmail",
+ "signerName": "$signerName",
+ "ccEmail": "$ccEmail",
+ "ccName": "$ccName"
+ }
+}
+"@
+#ds-snippet-end:Maestro1Step4
+
+if (-not ([string]::IsNullOrEmpty($triggerUrl))) {
+ #ds-snippet-start:Maestro1Step5
+ $triggerResult = Invoke-WebRequest -uri $triggerUrl -headers $headers -body $body -method POST -UseBasicParsing
+ #ds-snippet-end:Maestro1Step5
+ Write-Host $triggerResult
+ Write-Host ""
+
+ $workflowInstanceId = $($triggerResult | ConvertFrom-Json).instance_id
+ $workflowInstanceId | Out-File -FilePath "config/INSTANCE_ID" -Encoding utf8 -Force
+ Write-Host "Successfully created and published workflow $workflowInstanceId, ID saved to config/INSTANCE_ID"
+
+
+ $instanceUrl = $($triggerResult | ConvertFrom-Json).instance_url
+ # Decode escaped characters
+ $instanceUrl = $instanceUrl -replace "\\u0026", "&"
+ Write-Host "Use this URL to complete the workflow steps:"
+ Write-Host $instanceUrl
+
+
+ Write-Host ""
+ Write-Host "Opening a browser with the embedded workflow..."
+
+ # Wait a bit to let the server start
+ Start-Sleep -Seconds 2
+
+ # Start script for the embedded workflow
+& "./examples/Maestro/startServerForEmbeddingWorkflow.ps1" -instanceUrl $instanceUrl
+
+ # Open the browser
+ Start-Process "http://localhost:8080"
+} else {
+ Write-Host ""
+ Write-Host "The WORKFLOW_ID file contains the ID of the unpublished maestro workflow. Please, delete this file and try running the example again."
+}
\ No newline at end of file
diff --git a/examples/Maestro/eg002PauseWorkflow.ps1 b/examples/Maestro/eg002PauseWorkflow.ps1
new file mode 100644
index 0000000..6e37578
--- /dev/null
+++ b/examples/Maestro/eg002PauseWorkflow.ps1
@@ -0,0 +1,63 @@
+# Pause a running workflow instance
+
+# Check for workflow_id file existence and content
+if (Test-Path "config/WORKFLOW_ID") {
+ $workflowId = Get-Content "config/WORKFLOW_ID"
+ if ([string]::IsNullOrWhiteSpace($workflowId)) {
+ Write-Host "Workflow ID file is empty. Please run example 1 to create a workflow before running this example."
+ exit 0
+ }
+} else {
+ Write-Host "Workflow ID file does not exist. Please run example 1 to create a workflow before running this example."
+ exit 1
+}
+# Step 1: Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+$basePath = "https://api-d.docusign.com/v1"
+
+# Construct your API headers
+#ds-snippet-start:Maestro2Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Maestro2Step2
+
+Write-Host ""
+Write-Host "Attempting to pause the Workflow.."
+Write-Host ""
+
+# Send the POST request
+
+$response = New-TemporaryFile
+try {
+ #ds-snippet-start:Maestro2Step3
+ Invoke-RestMethod `
+ -Uri "${basePath}/accounts/${accountId}/workflows/${workflowId}/actions/pause" `
+ -Method 'POST' `
+ -Headers $headers `
+ -OutFile $response
+ #ds-snippet-end:Maestro2Step3
+
+ Write-Host ""
+ Write-Host "Workflow has been paused."
+ Write-Host ""
+ Write-Output "Response: $(Get-Content -Raw $response)"
+} catch {
+ Write-Output "Unable to pause creation of workflow instances."
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+}
+Write-Host ""
+
diff --git a/examples/Maestro/eg003ResumeWorkflow.ps1 b/examples/Maestro/eg003ResumeWorkflow.ps1
new file mode 100644
index 0000000..e513d82
--- /dev/null
+++ b/examples/Maestro/eg003ResumeWorkflow.ps1
@@ -0,0 +1,62 @@
+# Resume creation of a workflow instance
+
+# Check for workflow_id file existence and content
+if (Test-Path "config/WORKFLOW_ID") {
+ $workflowId = Get-Content "config/WORKFLOW_ID"
+ if ([string]::IsNullOrWhiteSpace($workflowId)) {
+ Write-Host "Workflow ID file is empty. Please run example 1 to create a workflow before running this example."
+ exit 0
+ }
+} else {
+ Write-Host "Workflow ID file does not exist. Please run example 1 to create a workflow before running this example."
+ exit 1
+}
+
+# Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+$basePath = "https://api-d.docusign.com/v1"
+
+# Construct your API headers
+#ds-snippet-start:Maestro3Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Maestro3Step2
+
+Write-Host ""
+Write-Host "Attempting to resume the Workflow..."
+Write-Host ""
+
+# Make the API call to resume
+$response = New-TemporaryFile
+try {
+#ds-snippet-start:Maestro3Step3
+ Invoke-RestMethod `
+ -Uri "${basePath}/accounts/${accountId}/workflows/${workflowId}/actions/resume" `
+ -Method 'POST' `
+ -Headers $headers `
+ -OutFile $response
+#ds-snippet-end:Maestro3Step3
+
+ Write-Host ""
+ Write-Host "Workflow has been resumed."
+ Write-Host ""
+ Write-Output "Response: $(Get-Content -Raw $response)"
+} catch {
+ Write-Output "Unable to resume creation of workflow instances."
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+ Write-Output "Error : " $_.ErrorDetails.Message
+ Write-Output "Command : " $_.InvocationInfo.Line
+}
+Write-Host ""
diff --git a/examples/Maestro/eg004CancelWorkflow.ps1 b/examples/Maestro/eg004CancelWorkflow.ps1
new file mode 100644
index 0000000..b8a40c3
--- /dev/null
+++ b/examples/Maestro/eg004CancelWorkflow.ps1
@@ -0,0 +1,56 @@
+# Cancel a workflow instance
+
+# Check that there is a workflow
+if (Test-Path .\config\WORKFLOW_ID) {
+ $workflowId = Get-Content .\config\WORKFLOW_ID
+} else {
+ Write-Output "Please run example 1 to create and trigger a workflow before running this example,"
+ exit 0
+}
+
+# Check that there is a running workflow instance to cancel
+if (Test-Path .\config\INSTANCE_ID) {
+ $workflowInstanceId = Get-Content .\config\INSTANCE_ID
+} else {
+ Write-Output "Please run example 1 to trigger a workflow before running this example."
+ exit 0
+}
+
+$base_path = "https://api-d.docusign.com/v1"
+
+# Step 1: Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$apiAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# temp file:
+$response = New-TemporaryFile
+
+# Construct your API headers
+#ds-snippet-start:Maestro4Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Maestro4Step2
+
+Write-Output "Attempting to cancel the Workflow instance..."
+
+#ds-snippet-start:Maestro4Step3
+Invoke-RestMethod `
+ -Uri "${base_path}/accounts/${apiAccountId}/workflows/${workflowId}/instances/${workflowInstanceId}/actions/cancel" `
+ -Method 'POST' `
+ -Headers $headers `
+ -OutFile $response
+
+#Write-Output "Workflow instance $workflowInstanceId has been canceled."
+Write-Output "Response: $(Get-Content -Raw $response)"
+#ds-snippet-end:Maestro4Step3
+
+# cleanup
+Remove-Item $response
+
+Write-Output "Done."
\ No newline at end of file
diff --git a/examples/Maestro/startServerForEmbeddingWorkflow.ps1 b/examples/Maestro/startServerForEmbeddingWorkflow.ps1
new file mode 100644
index 0000000..92aeb6f
--- /dev/null
+++ b/examples/Maestro/startServerForEmbeddingWorkflow.ps1
@@ -0,0 +1,68 @@
+param (
+ [string]$instanceUrl
+)
+
+$PORT = 8080
+$IP = "localhost"
+$listener = New-Object System.Net.HttpListener
+$prefix = "http://$IP`:$PORT/"
+$listener.Prefixes.Add($prefix)
+$listener.Start()
+Write-Host "Listening on $prefix"
+
+# Correct HTML without raw HTTP headers
+$responseHtml = @"
+
+The document has been embedded using Maestro Embedded Workflow.
+
+
+
+
+
+
+ Example Workflow
+
+
+
+
+
+
+
+
+
+
+
+Continue
+"@
+
+try {
+ while ($true) {
+ $context = $listener.GetContext()
+ $request = $context.Request
+ $response = $context.Response
+
+ if ($request.HttpMethod -eq "GET") {
+ $response.ContentType = "text/html"
+ $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseHtml)
+ $response.ContentLength64 = $buffer.Length
+ $response.OutputStream.Write($buffer, 0, $buffer.Length)
+ $response.OutputStream.Close()
+ break
+ }
+ }
+} catch {
+ Write-Error "Server error: $_"
+} finally {
+ $listener.Stop()
+ Write-Host "Server stopped."
+}
\ No newline at end of file
diff --git a/examples/Monitor/eg001GetMonitoringData.ps1 b/examples/Monitor/eg001GetMonitoringData.ps1
new file mode 100644
index 0000000..7aacf53
--- /dev/null
+++ b/examples/Monitor/eg001GetMonitoringData.ps1
@@ -0,0 +1,90 @@
+# Temp files:
+$response = New-TemporaryFile
+
+# Step 1. Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Step 2. Construct your API headers
+#ds-snippet-start:Monitor1Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Monitor1Step2
+
+# Declare variables
+$complete=$false
+$cursorValue = (Get-Date (Get-Date).AddDays(-10) -Format "yyyy-MM-dd")
+$iterations=0
+# You must provide an access token that impersonates a user with permissions to access the Monitor API endpoint
+if (($accessToken -eq "") -or ($null -eq $accessToken)) {
+ Write-Output "You must provide an access token"
+ $complete = $true
+}
+
+# Step 3: Get monitoring data
+# First call the endpoint with no cursor to get the first records.
+# After each call, save the cursor and use it to make the next
+# call from the point where the previous one left off when iterating through
+# the monitoring records
+#ds-snippet-start:Monitor1Step3
+DO {
+ $iterations++
+ Write-Output ""
+ try {
+ Invoke-RestMethod `
+ -Uri "https://lens-d.docusign.net/api/v2.0/datasets/monitor/stream?cursor=${cursorValue}&limit=2000" `
+ -Method 'GET' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ } `
+ -OutFile $response
+ # Display the data
+ Write-Output "Iteration:"
+ Write-Output $iterations
+ Write-Output "Results:"
+ Get-Content $response
+ # Get the endCursor value from the response. This lets you resume
+ # getting records from the spot where this call left off
+ $endCursorValue = (Get-Content $response | ConvertFrom-Json).endCursor
+ Write-Output "endCursorValue is:"
+ Write-Output $endCursorValue
+ Write-Output "cursorValue is:"
+ Write-Output $cursorValue
+
+ # If the endCursor from the response is the same as the one that you already have,
+ # it means that you have reached the
+ # end of the records
+ if ($endCursorValue -eq $cursorValue) {
+ Write-Output 'After getting records, the cursor values are the same. This indicates that you have reached the end of your available records.'
+ $complete=$true
+ }
+ else {
+ Write-Output "Updating the cursor value of $cursorValue to the new value of $endCursorValue"
+ $cursorValue=$endCursorValue
+ Start-Sleep -Second 5
+ }
+ }
+ catch {
+ $int = 0
+ foreach($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") {
+ Write-Output "TraceToken : " $_.Exception.Response.Headers[$int]
+ }
+ $int++
+ }
+ Write-Output "You do not have Monitor enabled for your account, follow https://developers.docusign.com/docs/monitor-api/how-to/enable-monitor/ to get it enabled."
+ Write-Output "Command : "$_.InvocationInfo.Line
+ $complete = $true
+ }
+
+} While ($complete -eq $false )
+#ds-snippet-end:Monitor1Step3
+
+Remove-Item $response
+
+Write-Output ""
+Write-Output ""
+Write-Output "Done."
+Write-Output ""
diff --git a/examples/Navigator/eg001ListAgreements.ps1 b/examples/Navigator/eg001ListAgreements.ps1
new file mode 100644
index 0000000..bdd22f6
--- /dev/null
+++ b/examples/Navigator/eg001ListAgreements.ps1
@@ -0,0 +1,49 @@
+$apiUri = "https://api-d.docusign.com/v1"
+$configPath = ".\config\settings.json"
+$tokenPath = ".\config\ds_access_token.txt"
+$accountIdPath = ".\config\API_ACCOUNT_ID"
+$agreementsPath = ".\config\AGREEMENTS.txt"
+
+# Get required variables from .\config\settings.json file
+$config = Get-Content $configPath -Raw | ConvertFrom-Json
+
+$accessToken = Get-Content $tokenPath
+$accountId = Get-Content $accountIdPath
+
+#ds-snippet-start:Navigator1Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Navigator1Step2
+
+# List agreements
+#ds-snippet-start:Navigator1Step3
+$response = New-TemporaryFile
+Invoke-RestMethod `
+ -Uri "${apiUri}/accounts/${accountId}/agreements" `
+ -Method 'GET' `
+ -Headers $headers `
+ -OutFile $response
+
+$responseContent = $(Get-Content $response | ConvertFrom-Json)
+#ds-snippet-end:Navigator1Step3
+
+Write-Host ""
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+# Clear the output file at the beginning
+Clear-Content -Path $agreementsPath -ErrorAction SilentlyContinue
+
+# Loop through each item in the 'data' array
+foreach ($item in $responseContent.data) {
+ # Extract id and file_name
+ $id = $item.id
+ $fileName = $item.file_name
+
+ # Write the id and file_name to the output file
+ "$id $fileName" | Out-File -FilePath $agreementsPath -Append
+}
+
+Write-Output ""
+Write-Output "Done."
diff --git a/examples/Navigator/eg002GetSingleAgreement.ps1 b/examples/Navigator/eg002GetSingleAgreement.ps1
new file mode 100644
index 0000000..dc76b0c
--- /dev/null
+++ b/examples/Navigator/eg002GetSingleAgreement.ps1
@@ -0,0 +1,78 @@
+$apiUri = "https://api-d.docusign.com/v1"
+$configPath = ".\config\settings.json"
+$tokenPath = ".\config\ds_access_token.txt"
+$accountIdPath = ".\config\API_ACCOUNT_ID"
+$agreementsPath = ".\config\AGREEMENTS.txt"
+
+# Check if the agreements file exists and has content
+if (-not (Test-Path $agreementsPath) -or -not (Get-Content $agreementsPath -ErrorAction SilentlyContinue)) {
+ Write-Output "No agreements found in $agreementsPath."
+ Write-Output "Please run Navigator example 1: List_Agreements first to get a list of agreements."
+ exit 0
+}
+
+# Load the file into an array, separating each line into id and file name
+$agreements = Get-Content -Path $agreementsPath | ForEach-Object {
+ $parts = $_ -split '\s+'
+ [PSCustomObject]@{
+ Id = $parts[0]
+ FileName = $parts[1]
+ }
+}
+
+# Display the file names for selection
+Write-Output "Please select an agreement:"
+for ($i = 0; $i -lt $agreements.Count; $i++) {
+ Write-Output "$($i + 1). $($agreements[$i].FileName)"
+}
+
+# Prompt user selection
+do {
+ $selection = Read-Host "Enter the number corresponding to your choice"
+
+ if ($selection -match '^\d+$' -and $selection -gt 0 -and $selection -le $agreements.Count) {
+ $chosenAgreement = $agreements[$selection - 1]
+ $AGREEMENT_ID = $chosenAgreement.Id
+
+ Write-Output "You selected: $($chosenAgreement.FileName)"
+ Write-Output "AGREEMENT_ID: $AGREEMENT_ID"
+ break
+ }
+ else {
+ Write-Output "Invalid selection. Please try again."
+ }
+} while ($true)
+
+# Get required variables from .\config\settings.json file
+$config = Get-Content $configPath -Raw | ConvertFrom-Json
+
+$accessToken = Get-Content $tokenPath
+$accountId = Get-Content $accountIdPath
+
+#ds-snippet-start:Navigator2Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Navigator2Step2
+
+# List agreements
+#ds-snippet-start:Navigator2Step3
+$response = New-TemporaryFile
+Invoke-RestMethod `
+ -Uri "${apiUri}/accounts/${accountId}/agreements/${AGREEMENT_ID}" `
+ -Method 'GET' `
+ -Headers $headers `
+ -OutFile $response
+
+$responseContent = $(Get-Content $response | ConvertFrom-Json)
+#ds-snippet-end:Navigator2Step3
+
+Write-Host ""
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+
+
+
+Write-Output ""
+Write-Output "Done."
diff --git a/examples/Notary/Jurisdictions.ps1 b/examples/Notary/Jurisdictions.ps1
new file mode 100644
index 0000000..ab1b537
--- /dev/null
+++ b/examples/Notary/Jurisdictions.ps1
@@ -0,0 +1,36 @@
+# Returns the status of whether or not jurisdictions are disabled
+
+$apiUri = "https://notary-d.docusign.net/restapi"
+
+# Obtain your Oauth access token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountID = Get-Content .\config\API_ACCOUNT_ID
+
+# Make a GET request to the jurisdictions endpoint
+
+$response = New-TemporaryFile
+
+Write-Output "Sending the jurisdiction status request to Docusign..."
+Write-Output ""
+Write-Output "Results:"
+#ds-snippet-start:Notary3Step2
+Invoke-RestMethod `
+ -UseBasicParsing `
+ -Uri "${apiUri}/v1.0/accounts/${accountID}/jurisdictions" `
+ -Method 'GET' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ } `
+ -OutFile $response
+#ds-snippet-end
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+# cleanup
+Remove-Item $response
+Write-Output ""
+Write-Output "Done."
diff --git a/examples/Notary/inviteNotaryToPool.ps1 b/examples/Notary/inviteNotaryToPool.ps1
new file mode 100644
index 0000000..edd830f
--- /dev/null
+++ b/examples/Notary/inviteNotaryToPool.ps1
@@ -0,0 +1,80 @@
+# Invite a notary to join your pool
+
+$apiUri = "https://notary-d.docusign.net/restapi"
+
+
+# Step 1. Obtain your Oauth access token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+$accountID = Get-Content .\config\API_ACCOUNT_ID
+$response = New-TemporaryFile
+
+# Construct your API headers
+
+#ds-snippet-start:Notary2Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# Check that we have an organization id in the settings.json config file
+if (!$variables.ORGANIZATION_ID) {
+ Write-Output "Organization ID is needed. Please add the ORGANIZATION_ID variable to the settings.json"
+ exit -1
+}
+
+$organizationId = $variables.ORGANIZATION_ID
+
+
+Write-Output ""
+Write-Output "Retrieving your notary pool:"
+Write-Output ""
+
+#ds-snippet-start:Notary2Step3
+Invoke-RestMethod `
+ -UseBasicParsing `
+ -Uri "${apiUri}/v1.0/organizations/${organizationId}/pools/" `
+ -Headers $headers `
+ -Method 'GET' `
+ -OutFile $response
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+$POOL_ID = $(Get-Content $response | ConvertFrom-Json).pools[0].poolId
+#ds-snippet-end
+
+#ds-snippet-start:Notary2Step4
+write-Output ""
+$NOTARY_NAME = Read-Host "Enter a name for the notary"
+$NOTARY_EMAIL = Read-Host "Enter an email address for the notary"
+
+$body = @"
+{
+ "email" : "${NOTARY_EMAIL}",
+ "name" : "${NOTARY_NAME}",
+}
+"@
+#ds-snippet-end
+
+write-Output ""
+write-Output "Inviting ${NOTARY_NAME} to your organization's notary pool"
+write-Output ""
+write-Output "Pool id is ${POOL_ID}"
+write-Output ""
+#ds-snippet-start:Notary2Step5
+Invoke-RestMethod `
+ -Uri "${apiUri}/v1.0/organizations/${organizationId}/pools/${POOL_ID}/invites" `
+ -Headers $headers `
+ -Method 'POST' `
+ -Body $body `
+ -Outfile $response
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+#ds-snippet-end
+
+# cleanup
+Remove-Item $response
+Write-Output ""
+Write-Output "Done."
diff --git a/examples/Notary/sendWithThirdPartyNotary.ps1 b/examples/Notary/sendWithThirdPartyNotary.ps1
new file mode 100644
index 0000000..f50432d
--- /dev/null
+++ b/examples/Notary/sendWithThirdPartyNotary.ps1
@@ -0,0 +1,159 @@
+$apiUri = "https://demo.docusign.net/restapi"
+$configPath = ".\config\settings.json"
+$tokenPath = ".\config\ds_access_token.txt"
+$accountIdPath = ".\config\API_ACCOUNT_ID"
+
+# Check the folder structure to switch paths for Quick ACG
+if ((Test-Path $configPath) -eq $false) {
+ $configPath = "..\config\settings.json"
+}
+if ((Test-Path $tokenPath) -eq $false) {
+ $tokenPath = "..\config\ds_access_token.txt"
+}
+if ((Test-Path $accountIdPath) -eq $false) {
+ $accountIdPath = "..\config\API_ACCOUNT_ID"
+}
+
+# Send an envelope with a third-party notary service
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content $configPath -Raw | ConvertFrom-Json
+
+# 1. Obtain your OAuth token
+$accessToken = Get-Content $tokenPath
+
+# Obtain your accountId from demo.docusign.net -- the account id is shown in
+# the drop down on the upper right corner of the screen by your picture or
+# the default picture.
+$accountID = Get-Content $accountIdPath
+
+# Step 2. Create the envelope definition.
+# The signer recipient includes a clientUserId setting
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$docBase64 = New-TemporaryFile
+
+$docPath = ".\demo_documents\World_Wide_Corp_Battle_Plan_Trafalgar.docx"
+
+# Check the folder structure to switch paths for Quick ACG
+if ((Test-Path $docPath) -eq $false) {
+ $docPath = "..\demo_documents\World_Wide_Corp_Battle_Plan_Trafalgar.docx"
+}
+
+# Fetch doc and encode
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path $docPath))) > $docBase64
+
+Write-Output "Sending the envelope request to Docusign..."
+Write-Output "Please wait, this may take a few moments."
+
+#ds-snippet-start:Notary4Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:Notary4Step2
+
+# Concatenate the different parts of the request
+#ds-snippet-start:Notary4Step3
+@{
+ emailSubject = "Please sign this document set";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $docBase64)";
+ name = "Order acknowledgement";
+ fileExtension = "html";
+ documentId = "1";
+ };
+ );
+ recipients = @{
+ signers = @(
+ @{
+ clientUserId = "1000";
+ email = $variables.SIGNER_EMAIL;
+ name = $variables.SIGNER_NAME;
+ recipientId = "2";
+ routingOrder = "1";
+ notaryId = "1";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ documentId = "1";
+ xPosition = "200";
+ yPosition = "235";
+ pageNumber = "1";
+ };
+ @{
+ stampType = "stamp";
+ documentId = "1";
+ xPosition = "200";
+ yPosition = "150";
+ pageNumber = "1";
+ };
+ );
+ };
+ };
+ );
+ notaries = @(
+ @{
+ name = "Notary";
+ recipientId = "1";
+ routingOrder = "1";
+ tabs = @{
+ notarySealTabs = @(
+ @{
+ xPosition = "300";
+ yPosition = "235";
+ documentId = "1";
+ pageNumber = "1";
+ };
+ );
+ signHereTabs = @(
+ @{
+ xPosition = "300";
+ yPosition = "150";
+ documentId = "1";
+ pageNumber = "1";
+ };
+ );
+ };
+ notaryType = "remote";
+ notarySourceType = "thirdparty";
+ notaryThirdPartyPartner = "onenotary";
+ recipientSignatureProviders = @(
+ @{
+ sealDocumentsWithTabsOnly = "false";
+ signatureProviderName = "ds_authority_idv";
+ signatureProviderOptions = @{};
+ };
+ );
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:Notary4Step3
+
+# Step 3. Call Docusign to create the envelope
+#ds-snippet-start:Notary4Step4
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers $headers `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:Notary4Step4
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+# pull out the envelopeId
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+Write-Output "EnvelopeId: $envelopeId"
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $docBase64
+
+Write-Output "Done."
\ No newline at end of file
diff --git a/examples/Notary/signatureRequestToNotaryGroup.ps1 b/examples/Notary/signatureRequestToNotaryGroup.ps1
new file mode 100644
index 0000000..796ec27
--- /dev/null
+++ b/examples/Notary/signatureRequestToNotaryGroup.ps1
@@ -0,0 +1,148 @@
+$apiUri = "https://demo.docusign.net/restapi"
+
+# Send an envelope with three documents
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# Check that we have a Notary name and email in the settings.json config file
+if ((!$variables.NOTARY_EMAIL) -or (!$variables.NOTARY_NAME) -or (!$variables.NOTARY_API_ACCOUNT_ID)) {
+ Write-Output "NOTARY_EMAIL, NOTARY_NAME, and NOTARY_API_ACCOUNT_ID are needed. Please add the NOTARY_EMAIL, NOTARY_NAME, and NOTARY_API_ACCOUNT_ID variables to the settings.json"
+ exit -1
+}
+
+# Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+#ds-snippet-start:Notary1Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Accept' = "application/json";
+ 'Content-Type' = "application/json";
+}
+#ds-snippet-end
+
+# document 1 (html) has tag **signature_1**
+# document 2 (docx) has tag /sn1/
+# document 3 (pdf) has tag /sn1/
+#
+# The envelope has two recipients.
+# recipient 1 - signer
+# recipient 2 - cc
+# The envelope will be sent first to the signer.
+# After it is signed, a copy is sent to the cc person.
+
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$docBase64 = New-TemporaryFile
+
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_Battle_Plan_Trafalgar.docx"))) > $docBase64
+
+Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "The envelope processing time will be about 15 seconds."
+
+# Concatenate the different parts of the request
+
+#ds-snippet-start:Notary1Step3
+@{
+ emailSubject = "Please sign this document set";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $docBase64)";
+ name = "Order acknowledgement";
+ fileExtension = "html";
+ documentId = "1";
+ };
+ );
+ recipients = @{
+ notaries = @(
+ @{
+ email = $variables.NOTARY_EMAIL;
+ name = $variables.NOTARY_NAME;
+ recipientId = "1";
+ routingOrder = "1";
+ tabs = @{
+ notarySealTabs = @(
+ @{
+ xPosition = "300";
+ yPosition = "245";
+ documentId = "1";
+ pageNumber = "1";
+ };
+ );
+ signHereTabs = @(
+ @{
+ xPosition = "300";
+ yPosition = "150";
+ documentId = "1";
+ pageNumber = "1";
+ };
+ )
+ };
+ userId = $variables.NOTARY_API_ACCOUNT_ID;
+ notaryType = "remote";
+ };
+ );
+ signers = @(
+ @{
+ clientUserId = "12345";
+ email = $variables.SIGNER_EMAIL;
+ name = $variables.SIGNER_NAME;
+ recipientId = "2";
+ routingOrder = "1";
+ notaryId = "1";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ documentId = "1";
+ xPosition = "200";
+ yPosition = "245";
+ pageNumber = "1";
+ };
+ @{
+ stampType = "stamp";
+ documentId = "1";
+ xPosition = "200";
+ yPosition = "150";
+ pageNumber = "1";
+ };
+ );
+ };
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end
+
+# Create and send the envelope
+#ds-snippet-start:Notary1Step4
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers $headers `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+#ds-snippet-end
+# pull out the envelopeId
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+
+# Save the envelope id for use by other scripts
+Write-Output "EnvelopeId: $envelopeId"
+Write-Output $envelopeId > .\config\ENVELOPE_ID
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $docBase64
+
+Write-Output "Done."
diff --git a/examples/Rooms/eg001CreateRoomWithDataController.ps1 b/examples/Rooms/eg001CreateRoomWithDataController.ps1
index 3fda371..d2833aa 100644
--- a/examples/Rooms/eg001CreateRoomWithDataController.ps1
+++ b/examples/Rooms/eg001CreateRoomWithDataController.ps1
@@ -3,28 +3,26 @@ $accessToken = Get-Content .\config\ds_access_token.txt
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Construct your API headers
+#ds-snippet-start:Rooms1Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Rooms1Step2
# Get Role ID
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/roles"
$response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
-$roleId = $($response.Content | ConvertFrom-Json).roles[0].roleid
-
-# Get Office ID
-$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/offices"
-$response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
-$officeId = $($response.Content | ConvertFrom-Json).officeSummaries.officeId
+$roles = $($response.Content | ConvertFrom-Json).roles
+$roleId = $roles.Where({$_.name -eq "Default Admin"}).roleId
# - Construct the request body for your room
+#ds-snippet-start:Rooms1Step3
$body = @"
{
"name": "Sample Room Creation",
"roleId": "$roleId",
"transactionSideId": "listbuy",
- "officeId": "$officeId",
"fieldData": {
"data" : {
"address1": "123 EZ Street",
@@ -38,9 +36,11 @@ $body = @"
}
}
"@
+#ds-snippet-end:Rooms1Step3
# a) Call the Rooms API
# b) Display the JSON response
+#ds-snippet-start:Rooms1Step4
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/rooms"
try {
@@ -59,4 +59,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:Rooms1Step4
diff --git a/examples/Rooms/eg002CreateRoomWithTemplateController.ps1 b/examples/Rooms/eg002CreateRoomWithTemplateController.ps1
index 93ac09a..432bbc8 100644
--- a/examples/Rooms/eg002CreateRoomWithTemplateController.ps1
+++ b/examples/Rooms/eg002CreateRoomWithTemplateController.ps1
@@ -5,19 +5,23 @@ $APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Construct your API headers
# - Construct your API headers
+#ds-snippet-start:Rooms2Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Rooms2Step2
# - Retrieve rooms pre-requisite data
# - Obtain our RoleID and OfficeID
+#ds-snippet-start:Rooms2Step3
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/roles"
$uriOfficeId = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/offices"
try {
$response = Invoke-RestMethod -uri $uri -headers $headers -method GET
- $roleId = $response.roles[0].roleId
+ $roles = $response.roles
+ $roleId = $roles.Where({$_.name -eq "Default Admin"}).roleId
$roomTemplateId = $response.roomTemplates.roomTemplateId
Write-Output "roleID:" $roleId
$response = Invoke-RestMethod -uri $uriOfficeId -headers $headers -method GET
@@ -33,6 +37,7 @@ catch {
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
}
+#ds-snippet-end:Rooms2Step3
# - Retrieve a Rooms template ID
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/room_templates"
@@ -55,6 +60,7 @@ catch {
}
# Construct the JSON body for your room
+#ds-snippet-start:Rooms2Step4
$body = @"
{
"name": "Sample Rooms Creation from Template",
@@ -75,9 +81,11 @@ $body = @"
}
}
"@
+#ds-snippet-end:Rooms2Step4
# a) Call the Rooms API
# b) Display JSON response
+#ds-snippet-start:Rooms2Step5
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/rooms"
try {
@@ -94,4 +102,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:Rooms2Step5
diff --git a/examples/Rooms/eg003ExportDataFromRoomController.ps1 b/examples/Rooms/eg003ExportDataFromRoomController.ps1
index bc7ca9b..e86f951 100644
--- a/examples/Rooms/eg003ExportDataFromRoomController.ps1
+++ b/examples/Rooms/eg003ExportDataFromRoomController.ps1
@@ -3,10 +3,12 @@ $accessToken = Get-Content .\config\ds_access_token.txt
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Construct your API headers
+#ds-snippet-start:Rooms3Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Rooms3Step2
# Get Room ID
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/rooms"
@@ -15,6 +17,7 @@ $roomId = $($response.Content | ConvertFrom-Json).rooms[0].roomId
# a) Call the Rooms API
# b) Display JSON response
+#ds-snippet-start:Rooms3Step3
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/rooms/$roomId/field_data"
try {
@@ -31,4 +34,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:Rooms3Step3
diff --git a/examples/Rooms/eg004AddFormsToRoomController.ps1 b/examples/Rooms/eg004AddFormsToRoomController.ps1
index 96cc221..430041a 100644
--- a/examples/Rooms/eg004AddFormsToRoomController.ps1
+++ b/examples/Rooms/eg004AddFormsToRoomController.ps1
@@ -3,10 +3,12 @@ $accessToken = Get-Content .\config\ds_access_token.txt
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Construct your API headers
+#ds-snippet-start:Rooms4Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Rooms4Step2
# Get Room ID
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/rooms"
@@ -14,21 +16,25 @@ $response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -meth
$roomId = $($response.Content | ConvertFrom-Json).rooms[0].roomId
# Get Form Library ID
+#ds-snippet-start:Rooms4Step3
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/form_libraries"
$response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers
-$formLibraryId = $($response.Content | ConvertFrom-Json).formsLibrarySummaries.formsLibraryId
+$formLibraryId = $($response.Content | ConvertFrom-Json).formsLibrarySummaries[0].formsLibraryId
# Get Form ID
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/form_libraries/$formLibraryId/forms"
-$response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers
+$response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
$formId = $($response.Content | ConvertFrom-Json).forms[0].libraryFormId
# Construct the request body for adding a form
$body = @"
{"formId":"$formId"}
"@
+#ds-snippet-end:Rooms4Step3
+
# Call the Rooms API
+#ds-snippet-start:Rooms4Step4
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/rooms/$roomId/forms"
try {
@@ -46,4 +52,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:Rooms4Step4
diff --git a/examples/Rooms/eg005GetRoomsWithFiltersController.ps1 b/examples/Rooms/eg005GetRoomsWithFiltersController.ps1
index d17ce8b..054bc24 100644
--- a/examples/Rooms/eg005GetRoomsWithFiltersController.ps1
+++ b/examples/Rooms/eg005GetRoomsWithFiltersController.ps1
@@ -3,17 +3,22 @@ $accessToken = Get-Content .\config\ds_access_token.txt
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Construct your API headers
+#ds-snippet-start:Rooms5Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Rooms5Step2
+#ds-snippet-start:Rooms5Step3
# Set your filtering parameters
$past = (Get-Date (Get-Date).AddDays(-10) -Format "yyyy-MM-dd")
# Set the date 1 day forward to account for changes made today
$current = (Get-Date (Get-Date).AddDays(1) -Format "yyyy-MM-dd")
+#ds-snippet-end:Rooms5Step3
# Call the v2 Rooms API
+#ds-snippet-start:Rooms5Step4
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/rooms?fieldDataChangedStartDate=$past&fieldDataChangedEndDate=$current"
try {
@@ -30,4 +35,5 @@ catch {
}
Write-Output "Error : "$_
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:Rooms5Step4
diff --git a/examples/Rooms/eg006CreateAnExternalFormFillSessionController.ps1 b/examples/Rooms/eg006CreateAnExternalFormFillSessionController.ps1
index 96bcf22..ef7281b 100644
--- a/examples/Rooms/eg006CreateAnExternalFormFillSessionController.ps1
+++ b/examples/Rooms/eg006CreateAnExternalFormFillSessionController.ps1
@@ -3,10 +3,12 @@ $accessToken = Get-Content .\config\ds_access_token.txt
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Construct your API headers
+#ds-snippet-start:Rooms6Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $accessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Rooms6Step2
# Get Room ID
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/rooms"
@@ -16,30 +18,47 @@ $roomId = $($response.Content | ConvertFrom-Json).rooms[0].roomId
# Get Form Library ID
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/form_libraries"
$response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers
-$formLibraryId = $($response.Content | ConvertFrom-Json).formsLibrarySummaries.formsLibraryId
+$formLibraryId = $($response.Content | ConvertFrom-Json).formsLibrarySummaries[0].formsLibraryId
# Get Form ID
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/form_libraries/$formLibraryId/forms"
-$response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers
+$response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
$formId = $($response.Content | ConvertFrom-Json).forms[0].libraryFormId
+
# Construct your request body
+#ds-snippet-start:Rooms6Step3
$body =
@"
{
- "roomId": $roomId,
- "formId": "$formId"
+ "roomId": "$roomId",
+ "formId": "$formId",
+ "xFrameAllowedUrl": "https://iframetester.com/"
}
"@
+#ds-snippet-end:Rooms6Step3
# a) Call the v2 Rooms API
# b) Display the JSON response
+#ds-snippet-start:Rooms6Step4
$uri = "https://demo.rooms.docusign.com/restapi/v2/accounts/$APIAccountId/external_form_fill_sessions"
try {
Write-Output "Response:"
$response = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -body $body -method POST
$response.Content | ConvertFrom-Json | ConvertTo-Json
+#ds-snippet-end:Rooms6Step4
+
+#ds-snippet-start:Rooms6Step5
+ $signingUrl = $($response.Content | ConvertFrom-Json).url
+
+ $redirectUrl = "https://iframetester.com/?url="+$signingUrl
+
+ Write-Output "The embedded form URL is $redirectUrl"
+ Write-Output "Attempting to automatically open your browser..."
+
+ Start-Process $redirectUrl
+#ds-snippet-end:Rooms6Step5
}
catch {
Write-Output "Unable to access form fill view link "
@@ -49,6 +68,14 @@ catch {
if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
$int++
}
- Write-Output "Error : "$_.ErrorDetails.Message
+
+ $errorMessage = $_.ErrorDetails.Message
+
+ if ( $errorMessage.Contains("INVALID_REQUEST_PARAMETERS") ) { Write-Output "Problem: Create a room using example 1." }
+
+ if ( $errorMessage.Contains("PROPERTY_VALIDATION_FAILURE") -or $errorMessage.Contains("FORM_NOT_IN_ROOM")) { Write-Output "Problem: Selected room does not have any forms. Add a form to a room using example 4." }
+
+ Write-Output "Error : "$errorMessage
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+
+}
diff --git a/examples/Rooms/eg007CreateFormGroup.ps1 b/examples/Rooms/eg007CreateFormGroup.ps1
new file mode 100644
index 0000000..5760198
--- /dev/null
+++ b/examples/Rooms/eg007CreateFormGroup.ps1
@@ -0,0 +1,49 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+
+# Construct your API headers
+#ds-snippet-start:Rooms7Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Rooms7Step2
+
+#ds-snippet-start:Rooms7Step3
+# Construct the request body
+$body = @"
+ {
+ "name": "Sample Room Form Group"
+ }
+"@
+#ds-snippet-end:Rooms7Step3
+
+# Call the Rooms API
+#ds-snippet-start:Rooms7Step4
+$base_path = "https://demo.rooms.docusign.com"
+$uri = "$base_path/restapi/v2/accounts/$APIAccountId/form_groups"
+
+try {
+ Write-Output "Response:"
+ $response = Invoke-WebRequest -uri $uri -headers $headers -method POST -body $body
+ $response.Content
+ $obj = $response.Content | ConvertFrom-Json
+ $formGroupID = $obj.formGroupId
+
+ # Store formGroupID into the file .\config\FORM_GROUP_ID
+ $formGroupID > .\config\FORM_GROUP_ID
+}
+catch {
+ Write-Output "Unable to create a form group"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+}
+#ds-snippet-end:Rooms7Step4
diff --git a/examples/Rooms/eg008AccessFormGroup.ps1 b/examples/Rooms/eg008AccessFormGroup.ps1
new file mode 100644
index 0000000..44bfbfc
--- /dev/null
+++ b/examples/Rooms/eg008AccessFormGroup.ps1
@@ -0,0 +1,105 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Construct your API headers
+#ds-snippet-start:Rooms8Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Rooms8Step2
+
+# Get form groups
+#ds-snippet-start:Rooms8Step3
+$base_path = "https://demo.rooms.docusign.com"
+$formGroupsUri = "$base_path/restapi/v2/accounts/$APIAccountId/form_groups"
+
+try {
+ Write-Output "Retrieving form groups..."
+ $response = Invoke-WebRequest -uri $formGroupsUri -headers $headers -method GET
+ $formGroups = ($response.Content | ConvertFrom-Json).formGroups
+
+ if (-not $formGroups) {
+ Write-Output "No form groups found. Execute code example 7 - Create a form group..."
+ exit 1
+ }
+
+ # Display the form groups
+ Write-Host "Available form groups:"
+ for ($i = 0; $i -lt $formGroups.Count; $i++) {
+ Write-Host "$($i + 1): $($formGroups[$i].name) (ID: $($formGroups[$i].formGroupId))"
+ }
+
+ # Prompt the user to select a form group
+ $selection = Read-Host "Enter the number of the form group you want to use"
+ if (-not ($selection -as [int]) -or $selection -lt 1 -or $selection -gt $formGroups.Count) {
+ Write-Output "Invalid selection. Please enter a number between 1 and $($formGroups.Count)."
+ exit 1
+ }
+
+ # Get the selected form group
+ $selectedFormGroup = $formGroups[$selection - 1]
+ $formGroupID = $selectedFormGroup.formGroupId
+ Write-Host "You selected: $($selectedFormGroup.name)"
+}
+catch {
+ Write-Output "Unable to retrieve form groups."
+ Write-Output "Error: $($_.Exception.Message)"
+ exit 1
+}
+#ds-snippet-end:Rooms8Step3
+
+# Get an office ID
+#ds-snippet-start:Rooms8Step4
+$officeUri = "$base_path/restapi/v2/accounts/$APIAccountId/offices"
+
+try {
+ Write-Output "Retrieving office ID..."
+ $response = Invoke-WebRequest -uri $officeUri -headers $headers -method GET
+ $officeSummaries = ($response.Content | ConvertFrom-Json).officeSummaries
+
+ if (-not $officeSummaries) {
+ Write-Output "No offices found."
+ exit 1
+ }
+
+ $officeID = $officeSummaries[0].officeId
+}
+catch {
+ Write-Output "Unable to retrieve an office ID."
+ Write-Output "Error: $($_.Exception.Message)"
+ exit 1
+}
+#ds-snippet-end:Rooms8Step4
+
+# Call the Rooms API to grant office access to the selected form group
+#ds-snippet-start:Rooms8Step5
+$uri = "$base_path/restapi/v2/accounts/$APIAccountId/form_groups/$formGroupID/grant_office_access/$officeID"
+
+try {
+ Write-Output "Response:"
+ $response = Invoke-WebRequest -uri $uri -headers $headers -method POST -body $body
+ $response.StatusCode
+ if ($response.StatusCode -eq "204") {
+ Write-Output "Form group has been assigned to office ID."
+ }
+
+ # check that we have got a 204 Status code response
+ if ($response.StatusCode -ne "204" ) {
+ Write-Output "Unable to assign the provided form group ID to the provided office ID!"
+ exit 1
+ }
+}
+catch {
+ Write-Output "Unable to grant office access to a form group"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+}
+#ds-snippet-end:Rooms8Step5
diff --git a/examples/Rooms/eg009AssignFormGroup.ps1 b/examples/Rooms/eg009AssignFormGroup.ps1
new file mode 100644
index 0000000..b9ba05f
--- /dev/null
+++ b/examples/Rooms/eg009AssignFormGroup.ps1
@@ -0,0 +1,140 @@
+# Get required environment variables from .\config\settings.json file
+$accessToken = Get-Content .\config\ds_access_token.txt
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Construct your API headers
+#ds-snippet-start:Rooms9Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:Rooms9Step2
+
+# Call the Rooms API to look up your forms library ID
+#ds-snippet-start:Rooms9Step3
+$base_path = "https://demo.rooms.docusign.com"
+$uri = "$base_path/restapi/v2/accounts/$APIAccountId/form_libraries"
+try {
+ Write-Output "Response:"
+ $response = Invoke-WebRequest -uri $uri -headers $headers -method GET
+ $response.Content
+ # Retrieve a form library ID
+ $obj = $response.Content | ConvertFrom-Json
+ $formsLibraryID = $obj.formsLibrarySummaries[0].formsLibraryId
+} catch {
+ Write-Output "Unable to retrieve form library"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+}
+
+# Call the Rooms API to look up a list of form IDs for the given forms library
+$uri = "$base_path/restapi/v2/accounts/$APIAccountId/form_libraries/$formsLibraryID/forms"
+
+try {
+ Write-Output ""
+ Write-Output "Response:"
+ $response = Invoke-WebRequest -uri $uri -headers $headers -method GET
+ $response.Content
+
+ $formsObj = $($response.Content | ConvertFrom-Json).forms
+
+ Write-Output ""
+ $menu = @{}
+ for ($i=1;$i -le $formsObj.count; $i++) {
+ Write-Output "$i. $($formsObj[$i-1].name)"
+ $menu.Add($i,($formsObj[$i-1].libraryFormId))
+ }
+
+ do {
+ Write-Output ""
+ [int]$selection = Read-Host 'Select a form by the form name: '
+ } while ($selection -gt $formsObj.count -or $selection -lt 1);
+ $formID = $menu.Item($selection)
+
+ Write-Output ""
+ Write-Output "Form Id: $formID"
+} catch {
+ Write-Output "Unable to retrieve a form id"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+}
+#ds-snippet-end:Rooms9Step3
+
+#ds-snippet-start:Rooms9Step4
+$formGroupID = ""
+
+# Call the Rooms API to look up a list of form group IDs
+$uri = "${base_path}/restapi/v2/accounts/$APIAccountId/form_groups"
+$result = Invoke-WebRequest -uri $uri -UseBasicParsing -headers $headers -method GET
+
+Write-Output ""
+Write-Output "Response:"
+$result.Content
+
+$formGroupObj = $($result.Content | ConvertFrom-Json).formGroups
+Write-Output ""
+
+# Setup a temporary menu option to pick a form group
+$menu = @{}
+for ($i=1;$i -le $formGroupObj.count; $i++) {
+ Write-Output "$i. $($formGroupObj[$i-1].name)"
+ $menu.Add($i,($formGroupObj[$i-1].formGroupId))
+}
+
+if ($formGroupObj.count -lt 1) {
+ Write-Output "A form group ID is needed. Fix: execute code example 7 - Create a form group..."
+ exit 1
+}
+
+do {
+ Write-Output ""
+ [int]$selection = Read-Host 'Select a form group: '
+} while ($selection -gt $formGroupObj.count -or $selection -lt 1);
+$formGroupID = $menu.Item($selection)
+
+Write-Output ""
+Write-Output "Form group Id: $formGroupID"
+Write-Output ""
+#ds-snippet-end:Rooms9Step4
+
+# Construct your request body
+#ds-snippet-start:Rooms9Step5
+$body =
+@"
+ {"formId": "$formID" }
+"@
+#ds-snippet-end:Rooms9Step5
+
+
+# Call the Rooms API
+#ds-snippet-start:Rooms9Step6
+$uri = "$base_path/restapi/v2/accounts/$APIAccountId/form_groups/$formGroupID/assign_form"
+
+try {
+ $response = Invoke-WebRequest -uri $uri -headers $headers -method POST -Body $body
+ Write-Output $response.Status
+ Write-Output "Response: No JSON response body returned when setting the default office ID in a form group"
+} catch {
+ Write-Output "Unable to assign the form to the form group"
+ # On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
+
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+}
+#ds-snippet-end:Rooms9Step6
diff --git a/examples/WebForms/eg001CreateInstance.ps1 b/examples/WebForms/eg001CreateInstance.ps1
new file mode 100644
index 0000000..59a2491
--- /dev/null
+++ b/examples/WebForms/eg001CreateInstance.ps1
@@ -0,0 +1,83 @@
+. "utils/invokeScript.ps1"
+
+$apiUri = "https://apps-d.docusign.com/api/webforms/v1.1"
+$configPath = ".\config\settings.json"
+$tokenPath = ".\config\ds_access_token.txt"
+$accountIdPath = ".\config\API_ACCOUNT_ID"
+
+# Get required variables from .\config\settings.json file
+$config = Get-Content $configPath -Raw | ConvertFrom-Json
+
+$accessToken = Get-Content $tokenPath
+$accountId = Get-Content $accountIdPath
+
+# Create template for the Web Form from the API
+Invoke-Script -Command "`".\utils\createWebFormTemplate.ps1`""
+
+$templateId = Get-Content -Path ".\config\WEB_FORM_TEMPLATE_ID"
+
+$webFormConfig = Get-Content -Raw demo_documents\web-form-config.json
+$result = $webFormConfig -replace "template-id", $templateId
+$result | Set-Content -Path demo_documents\web-form-config.json
+
+Write-Host ""
+Write-Host "Go to your Docusign account to create the Web Form. Go to 'Templates' in your developer account, select 'Start,' select 'Web Forms,' and choose 'Upload Web Form.' Upload the JSON config file 'web-form-config.json' found under the demo_documents folder of this project. You will need to activate the web form before proceeding. Press Continue after doing so."
+$choice = Read-Host
+
+#ds-snippet-start:WebForms1Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:WebForms1Step2
+
+# List web forms in account that match the name of the web form we just created
+#ds-snippet-start:WebForms1Step3
+$response = New-TemporaryFile
+Invoke-RestMethod `
+ -Uri "${apiUri}/accounts/${accountId}/forms?search=Web%20Form%20Example%20Template" `
+ -Method 'GET ' `
+ -Headers $headers `
+ -OutFile $response
+
+$formId = $(Get-Content $response | ConvertFrom-Json).items[0].id
+#ds-snippet-end:WebForms1Step3
+
+#ds-snippet-start:WebForms1Step4
+$json = @"
+{
+ "clientUserId": "1234-5678-abcd-ijkl",
+ "formValues": {
+ "PhoneNumber": "555-555-5555",
+ "Yes": ["Yes"],
+ "Company": "Tally",
+ "JobTitle": "Programmer Writer"
+ },
+ "expirationOffset": 24
+}
+"@
+#ds-snippet-end:WebForms1Step4
+
+#ds-snippet-start:WebForms1Step5
+Invoke-RestMethod `
+ -Uri "${apiUri}/accounts/${accountId}/forms/${formId}/instances" `
+ -Method 'POST' `
+ -Headers $headers `
+ -Body $json `
+ -OutFile $response
+
+$responseContent = $(Get-Content $response | ConvertFrom-Json)
+#ds-snippet-end:WebForms1Step5
+
+Write-Host ""
+Write-Host "Response:"
+Write-Host $responseContent
+
+$formUrl = $responseContent.formUrl
+$instanceToken = $responseContent.instanceToken
+$integrationKey = $config.INTEGRATION_KEY_AUTH_CODE
+
+Invoke-Script -Command "./utils/startServerForWebFormsExample.ps1 -integrationKey $integrationKey -url $formUrl -instanceToken $instanceToken"
+
+Write-Output ""
+Write-Output "Done."
diff --git a/examples/WebForms/eg002CreateRemoteInstance.ps1 b/examples/WebForms/eg002CreateRemoteInstance.ps1
new file mode 100644
index 0000000..7d65771
--- /dev/null
+++ b/examples/WebForms/eg002CreateRemoteInstance.ps1
@@ -0,0 +1,87 @@
+. "utils/invokeScript.ps1"
+
+$apiUri = "https://apps-d.docusign.com/api/webforms/v1.1"
+$configPath = ".\config\settings.json"
+$tokenPath = ".\config\ds_access_token.txt"
+$accountIdPath = ".\config\API_ACCOUNT_ID"
+
+# Get required variables from .\config\settings.json file
+$config = Get-Content $configPath -Raw | ConvertFrom-Json
+$signerName = $config.SIGNER_NAME
+$signerEmail = $config.SIGNER_EMAIL
+
+$accessToken = Get-Content $tokenPath
+$accountId = Get-Content $accountIdPath
+
+# Create template for the Web Form from the API
+Invoke-Script -Command "`".\utils\createWebFormTemplate.ps1`""
+
+$templateId = Get-Content -Path ".\config\WEB_FORM_TEMPLATE_ID"
+
+$webFormConfig = Get-Content -Raw demo_documents\web-form-config.json
+$result = $webFormConfig -replace "template-id", $templateId
+$result | Set-Content -Path demo_documents\web-form-config.json
+
+Write-Host ""
+Write-Host "Go to your Docusign account to create the Web Form. Go to 'Templates' in your developer account, select 'Start,' select 'Web Forms,' and choose 'Upload Web Form.' Upload the JSON config file 'web-form-config.json' found under the demo_documents folder of this project. You will need to activate the web form before proceeding. Press any key to continue after doing so."
+$choice = Read-Host
+
+#ds-snippet-start:WebForms2Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+$headers.add("Accept", "application/json")
+#ds-snippet-end:WebForms2Step2
+
+# List web forms in account that match the name of the web form we just created
+#ds-snippet-start:WebForms2Step3
+$response = New-TemporaryFile
+Invoke-RestMethod `
+ -Uri "${apiUri}/accounts/${accountId}/forms?search=Web%20Form%20Example%20Template" `
+ -Method 'GET ' `
+ -Headers $headers `
+ -OutFile $response
+
+$formId = $(Get-Content $response | ConvertFrom-Json).items[0].id
+#ds-snippet-end:WebForms2Step3
+
+#ds-snippet-start:WebForms2Step4
+$json = @"
+{
+ "sendOption": "now",
+ "formValues": {
+ "PhoneNumber": "555-555-5555",
+ "Yes": ["Yes"],
+ "Company": "Tally",
+ "JobTitle": "Programmer Writer"
+ },
+ "recipients": [
+ {
+ "roleName": "signer",
+ "name": "$signerName",
+ "email": "$signerEmail"
+ }
+ ]
+}
+"@
+#ds-snippet-end:WebForms2Step4
+
+#ds-snippet-start:WebForms2Step5
+Invoke-RestMethod `
+ -Uri "${apiUri}/accounts/${accountId}/forms/${formId}/instances" `
+ -Method 'POST' `
+ -Headers $headers `
+ -Body $json `
+ -OutFile $response
+
+$responseContent = $(Get-Content $response | ConvertFrom-Json)
+#ds-snippet-end:WebForms2Step5
+
+Write-Host ""
+Write-Host "Creating a new remote instance of the web form..."
+Write-Host ""
+Write-Host "Response:"
+Write-Host $responseContent
+
+Write-Output ""
+Write-Output "Done."
diff --git a/examples/Workspaces/eg001CreateWorkspace.ps1 b/examples/Workspaces/eg001CreateWorkspace.ps1
new file mode 100644
index 0000000..46c0d9f
--- /dev/null
+++ b/examples/Workspaces/eg001CreateWorkspace.ps1
@@ -0,0 +1,54 @@
+$apiUri = "https://api-d.docusign.com/v1"
+
+# Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+$workspaceName = Read-Host "Enter the name for the new workspace"
+
+#ds-snippet-start:Workspaces1Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Accept' = 'application/json';
+ 'Content-Type' = 'application/json';
+}
+#ds-snippet-end:Workspaces1Step2
+
+try {
+ # Create the workspace definition
+ #ds-snippet-start:Workspaces1Step3
+ $body = @{
+ name = $workspaceName;
+ } | ConvertTo-Json
+ #ds-snippet-end:Workspaces1Step3
+
+ #ds-snippet-start:Workspaces1Step4
+ $response = $(Invoke-WebRequest `
+ -Uri "${apiUri}/accounts/${accountId}/workspaces" `
+ -Method 'POST' `
+ -headers $headers `
+ -body $body)
+ #ds-snippet-end:Workspaces1Step4
+} catch {
+ Write-Output "Failed to create Workspace."
+ Write-Output $_
+ exit 0
+}
+
+Write-Output "Response: $response"
+
+# pull out the workspaceId
+$workspaceId = $($response.Content | ConvertFrom-Json).workspace_id
+$workspaceCreatorId = $($response.Content | ConvertFrom-Json).created_by_user_id
+
+# Save the envelope id for use by other scripts
+Write-Output "Workspace created! ID: $workspaceId"
+Write-Output $workspaceId > .\config\WORKSPACE_ID
+Write-Output $workspaceName > .\config\WORKSPACE_NAME
+Write-Output $workspaceCreatorId > .\config\WORKSPACE_CREATOR_ID
+
+Write-Output "Done."
diff --git a/examples/Workspaces/eg002AddDocumentToWorkspace.ps1 b/examples/Workspaces/eg002AddDocumentToWorkspace.ps1
new file mode 100644
index 0000000..0170b05
--- /dev/null
+++ b/examples/Workspaces/eg002AddDocumentToWorkspace.ps1
@@ -0,0 +1,134 @@
+$apiUri = "https://api-d.docusign.com/v1"
+
+# check that a workspace exists
+$workspaceId = Get-Content .\config\WORKSPACE_ID
+$workspaceName = Get-Content .\config\WORKSPACE_NAME
+if ([string]::IsNullOrWhiteSpace($workspaceId)) {
+ Write-Host "Please create a workspace before running this example"
+ exit 0
+}
+
+# Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# temp files:
+$requestData = New-TemporaryFile
+
+#ds-snippet-start:Workspaces2Step2
+$boundary = [System.Guid]::NewGuid().ToString()
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "multipart/form-data; boundary=${boundary}";
+}
+#ds-snippet-end:Workspaces2Step2
+
+# Get the current script directory
+$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
+
+# Resolve the demo_documents directory (two levels up)
+$DemoDocsPath = Resolve-Path (Join-Path $ScriptDir '..\..\demo_documents')
+
+Write-Host ""
+Write-Host "Enter the PDF file name (e.g. World_Wide_Corp_Web_Form.pdf) from the $DemoDocsPath folder:"
+Write-Host ""
+
+# Ask for the file until valid
+while ($true) {
+ $FileName = Read-Host
+ $FilePath = Join-Path $DemoDocsPath $FileName
+
+ if ($FileName -notmatch '\.pdf$') {
+ Write-Host ""
+ Write-Host "The file must be a PDF (must end with .pdf). Please try again."
+ Write-Host ""
+ continue
+ }
+
+ if (-not (Test-Path $FilePath)) {
+ Write-Host ""
+ Write-Host "File not found in demo_documents folder. Please try again."
+ Write-Host ""
+ continue
+ }
+
+ break
+}
+
+# Ask for document name to be used in the workspace
+Write-Host ""
+Write-Host "Enter the name for the document in the workspace (must end with .pdf):"
+Write-Host ""
+
+while ($true) {
+ $DocName = Read-Host
+ $DocName = $DocName.Trim()
+
+ if ($DocName -match '\.pdf$') {
+ break
+ } else {
+ Write-Host ""
+ Write-Host "Invalid name. The document name must end with '.pdf' (e.g., example.pdf)."
+ Write-Host "Please try again:"
+ Write-Host ""
+ }
+}
+
+try {
+ #ds-snippet-start:Workspaces2Step3
+ # Create a temporary copy with the desired document name
+ $tempFilePath = Join-Path ([System.IO.Path]::GetTempPath()) $docName
+ Copy-Item -Path $filePath -Destination $tempFilePath -Force
+
+ $boundary = [System.Guid]::NewGuid().ToString()
+ $LF = "`r`n"
+ $fileBytes = [System.IO.File]::ReadAllBytes($tempFilePath)
+ $fileContent = [System.Text.Encoding]::GetEncoding("iso-8859-1").GetString($fileBytes)
+
+ # Construct the multipart form body
+ $bodyLines = @(
+ "--$boundary",
+ "Content-Disposition: form-data; name=`"file`"; filename=`"$docName`"",
+ "Content-Type: application/octet-stream$LF",
+ $fileContent,
+ "--$boundary",
+ "Content-Disposition: form-data; name=`"name`"$LF",
+ $docName,
+ "--$boundary--$LF"
+ )
+ $body = $bodyLines -join $LF
+ #ds-snippet-end:Workspaces2Step3
+
+ Remove-Item $tempFilePath -Force
+
+ #ds-snippet-start:Workspaces2Step4
+ $response = Invoke-WebRequest `
+ -Uri "${apiUri}/accounts/${accountId}/workspaces/${workspaceId}/documents" `
+ -Method 'POST' `
+ -Headers $headers `
+ -ContentType "multipart/form-data; boundary=$boundary" `
+ -Body $body
+ #ds-snippet-end:Workspaces2Step4
+} catch {
+ Write-Output "Failed to add document to workspace."
+ Write-Output $_
+ exit 0
+}
+
+Write-Output "Response: $response"
+
+# pull out the documentId
+$documentId = $($response.Content | ConvertFrom-Json).document_id
+
+# Save the document id for use by other scripts
+Write-Output "Document added to the workspace '$workspaceName'!! ID: $documentId"
+Write-Output $documentId > .\config\DOCUMENT_ID
+
+# cleanup
+Remove-Item $requestData
+
+Write-Output "Done."
diff --git a/examples/Workspaces/eg003SendEnvelopeWithRecipientInfo.ps1 b/examples/Workspaces/eg003SendEnvelopeWithRecipientInfo.ps1
new file mode 100644
index 0000000..011037d
--- /dev/null
+++ b/examples/Workspaces/eg003SendEnvelopeWithRecipientInfo.ps1
@@ -0,0 +1,110 @@
+$apiUri = "https://api-d.docusign.com/v1"
+
+# check that a workspace exists
+$workspaceId = Get-Content .\config\WORKSPACE_ID
+if ([string]::IsNullOrWhiteSpace($workspaceId)) {
+ Write-Host "Please create a workspace before running this example"
+ exit 0
+}
+
+# check that a document exists in the workspace
+$documentId = Get-Content .\config\DOCUMENT_ID
+if ([string]::IsNullOrWhiteSpace($documentId)) {
+ Write-Host "Please create a document in the workspace before running this example"
+ exit 0
+}
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+#ds-snippet-start:Workspaces3Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Accept' = 'application/json';
+ 'Content-Type' = "application/json";
+}
+#ds-snippet-end:Workspaces3Step2
+
+try {
+ # Create the workspace envelope definition
+ #ds-snippet-start:Workspaces3Step3
+ $body = @{
+ "envelope_name" = "Example Workspace Envelope";
+ "document_ids" = @("${documentId}")
+ } | ConvertTo-Json
+ #ds-snippet-end:Workspaces3Step3
+
+ #ds-snippet-start:Workspaces3Step4
+ $response = $(Invoke-WebRequest `
+ -Uri "${apiUri}/accounts/${accountId}/workspaces/${workspaceId}/envelopes" `
+ -Method 'POST' `
+ -headers $headers `
+ -body $body)
+ #ds-snippet-end:Workspaces3Step4
+} catch {
+ Write-Output "Failed to send envelope."
+ Write-Output $_
+ exit 0
+}
+
+Write-Output "Response: $response"
+
+# pull out the envelopeId
+$envelopeId = $($response.Content | ConvertFrom-Json).envelope_id
+Write-Output "Envelope created! ID: $envelopeId"
+
+# Set the eSignature REST API base path
+$apiUri = "https://demo.docusign.net/restapi"
+
+#ds-snippet-start:Workspaces3Step5
+$body = @{
+ emailSubject = "Please sign this document";
+ recipients = @{
+ signers = @(
+ @{
+ email = $variables.SIGNER_EMAIL;
+ name = $variables.SIGNER_NAME;
+ recipientId = "1";
+ routingOrder = "1";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "/sn1/";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ );
+ };
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32
+#ds-snippet-end:Workspaces3Step5
+
+try {
+ #ds-snippet-start:Workspaces3Step6
+ $response = $(Invoke-WebRequest `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}" `
+ -Method 'PUT' `
+ -headers $headers `
+ -body $body)
+ #ds-snippet-end:Workspaces3Step6
+} catch {
+ Write-Output "Failed to send envelope."
+ Write-Output $_
+ exit 0
+}
+
+Write-Output "Response: $response"
+Write-Output "Envelope Sent!"
+Write-Output "Done."
diff --git a/examples/Workspaces/eg004CreateWorkspaceWithBrand.ps1 b/examples/Workspaces/eg004CreateWorkspaceWithBrand.ps1
new file mode 100644
index 0000000..ded1364
--- /dev/null
+++ b/examples/Workspaces/eg004CreateWorkspaceWithBrand.ps1
@@ -0,0 +1,69 @@
+. "utils/invokeScript.ps1"
+
+#ds-snippet-start:Workspaces4Step2
+# check that a brand exists
+$path = ".\config\BRAND_ID"
+if (-not (Test-Path $path) -or [string]::IsNullOrWhiteSpace((Get-Content $path))) {
+ Write-Host "No brand_id found. Attempting to run eg028CreatingABrand.ps1..."
+ Invoke-Script -Command "`"./examples/eSignature/eg028CreatingABrand.ps1`""
+}
+
+# re-check after attempt
+$brandId = Get-Content .\config\BRAND_ID
+if ([string]::IsNullOrWhiteSpace($brandId)) {
+ Write-Host "Brand creation did not produce a brand_id. Please create a brand first."
+ exit 1
+}
+#ds-snippet-end:Workspaces4Step2
+
+$apiUri = "https://api-d.docusign.com/v1"
+
+# Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+#ds-snippet-start:Workspaces4Step3
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Accept' = 'application/json';
+ 'Content-Type' = 'application/json';
+}
+#ds-snippet-end:Workspaces4Step3
+
+try {
+ # Create the workspace definition
+ #ds-snippet-start:Workspaces4Step4
+ $body = @{
+ name = "Example workspace";
+ brand_id = "$brandId"
+ } | ConvertTo-Json
+ #ds-snippet-end:Workspaces4Step4
+
+ #ds-snippet-start:Workspaces4Step5
+ $response = $(Invoke-WebRequest `
+ -Uri "${apiUri}/accounts/${accountId}/workspaces" `
+ -Method 'POST' `
+ -headers $headers `
+ -body $body)
+ #ds-snippet-end:Workspaces4Step5
+} catch {
+ Write-Output "Failed to create Workspace."
+ Write-Output $_
+ exit 0
+}
+
+Write-Output "Response: $response"
+
+# pull out the workspaceId
+$workspaceId = $($response.Content | ConvertFrom-Json).workspace_id
+
+# Save the envelope id for use by other scripts
+Write-Output "Workspace created! ID: $workspaceId"
+Write-Output "Brand used: $brandId"
+Write-Output $workspaceId > .\config\WORKSPACE_ID
+
+Write-Output "Done."
diff --git a/examples/Workspaces/eg005CreateUploadRequest.ps1 b/examples/Workspaces/eg005CreateUploadRequest.ps1
new file mode 100644
index 0000000..38a0f6f
--- /dev/null
+++ b/examples/Workspaces/eg005CreateUploadRequest.ps1
@@ -0,0 +1,82 @@
+$apiUri = "https://api-d.docusign.com/v1"
+
+# Check that a workspace exists
+$workspaceId = Get-Content .\config\WORKSPACE_ID
+if ([string]::IsNullOrWhiteSpace($workspaceId)) {
+ Write-Host "Please create a workspace before running this example"
+ exit 0
+}
+
+# Check that a workspace creator ID exists
+$workspaceCreatorId = Get-Content .\config\WORKSPACE_CREATOR_ID
+if ([string]::IsNullOrWhiteSpace($workspaceCreatorId)) {
+ Write-Host "No creator ID was recorded. Please run the Create Workspace example before running this code"
+ exit 0
+}
+
+# Get required variables from .\config\settings.json:
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Calculate ISO 8601 date 7 days from now (UTC)
+$dueDate = (Get-Date).ToUniversalTime().AddDays(7).ToString("yyyy-MM-ddTHH:mm:ssZ")
+
+#ds-snippet-start:Workspaces5Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Accept' = 'application/json';
+ 'Content-Type' = 'application/json';
+}
+#ds-snippet-end:Workspaces5Step2
+
+try {
+ # Create the workspace definition
+ #ds-snippet-start:Workspaces5Step3
+ $body = @{
+ name = "Upload Request example $dueDate";
+ description = 'This is an example upload request created via the workspaces API';
+ status = 'draft';
+ due_date = $dueDate;
+ assignments = @(
+ @{
+ upload_request_responsibility_type_id = 'assignee';
+ first_name = 'Test';
+ last_name = 'User';
+ email = $variables.SIGNER_EMAIL;
+ };
+ @{
+ assignee_user_id = "$workspaceCreatorId";
+ upload_request_responsibility_type_id = 'watcher';
+ };
+ );
+ } | ConvertTo-Json
+ #ds-snippet-end:Workspaces5Step3
+
+ #ds-snippet-start:Workspaces5Step4
+ $response = $(Invoke-WebRequest `
+ -Uri "${apiUri}/accounts/${accountId}/workspaces/${workspaceId}/upload-requests" `
+ -Method 'POST' `
+ -headers $headers `
+ -body $body)
+ #ds-snippet-end:Workspaces5Step4
+} catch {
+ Write-Output "Failed to create Workspace upload request."
+ Write-Output $_
+ exit 0
+}
+
+Write-Output "Response: $response"
+
+# pull out the workspaceId
+$uploadRequestId = $($response.Content | ConvertFrom-Json).upload_request_id
+
+Write-Output "Workspace upload request created! ID: $uploadRequestId"
+
+Write-Output "Done."
diff --git a/examples/eSignature/eg002SigningViaEmail.ps1 b/examples/eSignature/eg002SigningViaEmail.ps1
index 484beb3..00107b0 100644
--- a/examples/eSignature/eg002SigningViaEmail.ps1
+++ b/examples/eSignature/eg002SigningViaEmail.ps1
@@ -6,7 +6,7 @@ $apiUri = "https://demo.docusign.net/restapi"
$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
-# Step 1: Obtain your OAuth token
+# Obtain your OAuth token
# Note: Substitute these values with your own
$accessToken = Get-Content .\config\ds_access_token.txt
@@ -14,7 +14,6 @@ $accessToken = Get-Content .\config\ds_access_token.txt
# Note: Substitute these values with your own
$accountId = Get-Content .\config\API_ACCOUNT_ID
-# ***DS.snippet.0.start
# document 1 (html) has tag **signature_1**
# document 2 (docx) has tag /sn1/
# document 3 (pdf) has tag /sn1/
@@ -38,11 +37,12 @@ $doc3Base64 = New-TemporaryFile
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_Battle_Plan_Trafalgar.docx"))) > $doc2Base64
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $doc3Base64
-Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "Sending the envelope request to Docusign..."
Write-Output "The envelope has three documents. Processing time will be about 15 seconds."
Write-Output "Results:"
# Concatenate the different parts of the request
+#ds-snippet-start:eSign2Step2
@{
emailSubject = "Please sign this document set";
documents = @(
@@ -100,8 +100,10 @@ Write-Output "Results:"
};
status = "sent";
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign2Step2
-# Step 3. Create and send the envelope
+# Create and send the envelope
+#ds-snippet-start:eSign2Step3
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
-Method 'POST' `
@@ -111,13 +113,13 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign2Step3
Write-Output "Response: $(Get-Content -Raw $response)"
# pull out the envelopeId
$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
-# ***DS.snippet.0.end
# Save the envelope id for use by other scripts
Write-Output "EnvelopeId: $envelopeId"
Write-Output $envelopeId > .\config\ENVELOPE_ID
diff --git a/examples/eSignature/eg003ListEnvelopes.ps1 b/examples/eSignature/eg003ListEnvelopes.ps1
index 4208133..bcbed9b 100644
--- a/examples/eSignature/eg003ListEnvelopes.ps1
+++ b/examples/eSignature/eg003ListEnvelopes.ps1
@@ -8,16 +8,17 @@ $apiUri = "https://demo.docusign.net/restapi"
$accessToken = Get-Content .\config\ds_access_token.txt
# Step 2. List envelope status
+#ds-snippet-start:eSign3Step2
# Obtain your accountId from demo.docusign.net -- the account id is shown in
# the drop down on the upper right corner of the screen by your picture or
# the default picture.
$accountID = Get-Content .\config\API_ACCOUNT_ID
-Write-Output "Sending the list envelope status request to DocuSign..."
+Write-Output "Sending the list envelope status request to Docusign..."
Write-Output "Results:"
# Get date in the ISO 8601 format
-$fromDate = ((Get-Date).AddDays(-10d)).ToString("yyyy-MM-ddThh:mm:ssK")
+$fromDate = ((Get-Date).AddDays(-10d)).ToString("yyyy-MM-ddTHH:mm:ssK")
$(Invoke-RestMethod `
@@ -28,5 +29,5 @@ $(Invoke-RestMethod `
'Content-Type' = "application/json";
} `
-Body @{ "from_date" = ${fromDate} }).envelopes
-
-Write-Output "Done..."
+#ds-snippet-end:eSign3Step2
+Write-Output "Done."
diff --git a/examples/eSignature/eg004EnvelopeInfo.ps1 b/examples/eSignature/eg004EnvelopeInfo.ps1
index 0da30d7..c61d9a1 100644
--- a/examples/eSignature/eg004EnvelopeInfo.ps1
+++ b/examples/eSignature/eg004EnvelopeInfo.ps1
@@ -25,10 +25,10 @@ else {
exit 1
}
-Write-Output "Sending the Envelopes::get request to DocuSign..."
+Write-Output "Sending the Envelopes::get request to Docusign..."
Write-Output "Results:"
-# Step 2. Get envelope data
+#ds-snippet-start:eSign4Step2
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}" `
-Method 'GET' `
@@ -36,6 +36,6 @@ Invoke-RestMethod `
'Authorization' = "Bearer $accessToken";
'Content-Type' = "application/json";
}
-# ***DS.snippet.0.end
+#ds-snippet-end:eSign4Step2
Write-Output "Done."
diff --git a/examples/eSignature/eg005EnvelopeRecipients.ps1 b/examples/eSignature/eg005EnvelopeRecipients.ps1
index 9d321bc..21802f1 100644
--- a/examples/eSignature/eg005EnvelopeRecipients.ps1
+++ b/examples/eSignature/eg005EnvelopeRecipients.ps1
@@ -25,12 +25,11 @@ else {
exit 1
}
-Write-Output "Sending the EnvelopeRecipients::list request to DocuSign..."
+Write-Output "Sending the EnvelopeRecipients::list request to Docusign..."
Write-Output "Results:"
-# Step 2. List envelope recipients
-# ***DS.snippet.0.start
+#ds-snippet-start:eSign5Step2
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/recipients" `
-Method 'GET' `
@@ -38,6 +37,6 @@ Invoke-RestMethod `
'Authorization' = "Bearer $accessToken";
'Content-Type' = "application/json";
}
-# ***DS.snippet.0.end
+#ds-snippet-end:eSign5Step2
Write-Output "Done."
diff --git a/examples/eSignature/eg006EnvelopeDocs.ps1 b/examples/eSignature/eg006EnvelopeDocs.ps1
index b74f59d..0d124ea 100644
--- a/examples/eSignature/eg006EnvelopeDocs.ps1
+++ b/examples/eSignature/eg006EnvelopeDocs.ps1
@@ -6,7 +6,7 @@ $apiUri = "https://demo.docusign.net/restapi"
# can be manually created.
# ***DS.snippet.0.start
-# Step 1. Obtain your Oauth access token
+# Obtain your Oauth access token
$accessToken = Get-Content .\config\ds_access_token.txt
# Obtain your accountId from demo.docusign.net -- the account id is shown in
@@ -23,17 +23,22 @@ else {
exit 1
}
-Write-Output "Sending the EnvelopeDocuments::list request to DocuSign..."
+#ds-snippet-start:eSign6Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+}
+#ds-snippet-end:eSign6Step2
+
+Write-Output "Sending the EnvelopeDocuments::list request to Docusign..."
Write-Output "Results:"
-# Step 2. List envelope documents
+# List envelope documents
+#ds-snippet-start:eSign6Step3
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/documents" `
-Method 'GET' `
- -Headers @{
- 'Authorization' = "Bearer $accessToken";
- 'Content-Type' = "application/json";
-}
-# ***DS.snippet.0.end
+ -Headers $headers | ConvertTo-Json
+#ds-snippet-end:eSign6Step3
Write-Output "Done."
diff --git a/examples/eSignature/eg007EnvelopeGetDoc.ps1 b/examples/eSignature/eg007EnvelopeGetDoc.ps1
index 50297f5..7cefd0b 100644
--- a/examples/eSignature/eg007EnvelopeGetDoc.ps1
+++ b/examples/eSignature/eg007EnvelopeGetDoc.ps1
@@ -6,7 +6,7 @@ $apiUri = "https://demo.docusign.net/restapi"
# can be manually created.
-# Step 1. Obtain your Oauth access token
+# Obtain your Oauth access token
$accessToken = Get-Content .\config\ds_access_token.txt
# Obtain your accountId from demo.docusign.net -- the account id is shown in
@@ -22,10 +22,17 @@ if (Test-Path .\config\ENVELOPE_ID) {
$envelopeId = Get-Content .\config\ENVELOPE_ID
}
else {
- Write-Output "An envelope id is needed. Fix: execute step 2 - Signing_Via_Email"
+ Write-Output "PROBLEM: An envelope id is needed. Fix: execute code example 2 - Signing_Via_Email"
exit 1
}
+#ds-snippet-start:eSign7Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ }
+#ds-snippet-end:eSign7Step2
+
$docChoice = "1"
$outputFileExtension = "pdf"
@@ -36,17 +43,19 @@ Enum listDocs {
CertificateOfCompletion = 4;
DocumentsCombinedTogether = 5;
ZIPfile = 6;
+ PDFPortfolio = 7;
}
$listDocsView = $null;
do {
- Write-Output 'Select the initial sending view: '
+ Write-Output 'Select a document or document set to download:'
Write-Output "$([int][listDocs]::Document1) - Document 1"
Write-Output "$([int][listDocs]::Document2) - Document 2"
Write-Output "$([int][listDocs]::Document3) - Document 3"
Write-Output "$([int][listDocs]::CertificateOfCompletion) - Certificate of Completion"
Write-Output "$([int][listDocs]::DocumentsCombinedTogether) - Documents combined together"
Write-Output "$([int][listDocs]::ZIPfile) - ZIP file"
+ Write-Output "$([int][listDocs]::PDFPortfolio) - PDF Portfolio"
[int]$listDocsView = Read-Host "Please make a selection"
} while (-not [listDocs]::IsDefined([listDocs], $listDocsView));
@@ -62,21 +71,22 @@ elseif ($listDocsView -eq [listDocs]::ZIPfile) {
$docChoice = "archive"
$outputFileExtension = "zip"
}
+elseif ($listDocsView -eq [listDocs]::PDFPortfolio) {
+ $docChoice = "portfolio"
+ $outputFileExtension = "pdf"
+}
else {
$docChoice = $listDocsView
}
-Write-Output "Sending the EnvelopeDocuments::get request to DocuSign..."
-# ***DS.snippet.0.start
-# Step 3. Call the eSignature API
+Write-Output "Sending the EnvelopeDocuments::get request to Docusign..."
+# Call the eSignature API
+#ds-snippet-start:eSign7Step3
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/documents/${docChoice}" `
-Method 'GET' `
- -Headers @{
- 'Authorization' = "Bearer $accessToken";
- 'Content-Type' = "application/json";
-} `
+ -Headers $headers `
-OutFile ${outputFile}${outputFileExtension}
-# ***DS.snippet.0.end
+#ds-snippet-end:eSign7Step3
Write-Output "The document(s) are stored in file ${outputFile}${outputFileExtension}"
-Write-Output "Done."
\ No newline at end of file
+Write-Output "Done."
diff --git a/examples/eSignature/eg008CreateTemplate.ps1 b/examples/eSignature/eg008CreateTemplate.ps1
index 6b41ec5..0603e3b 100644
--- a/examples/eSignature/eg008CreateTemplate.ps1
+++ b/examples/eSignature/eg008CreateTemplate.ps1
@@ -16,7 +16,7 @@ $accountId = Get-Content .\config\API_ACCOUNT_ID
# List the account's templates
Write-Output "Checking to see if the template already exists in your account..."
-$templateName = "Example Signer and CC template"
+$templateName = "Example Signer and CC template v2"
$response = New-TemporaryFile
Invoke-RestMethod `
@@ -30,13 +30,14 @@ Invoke-RestMethod `
-OutFile $response
# pull out the templateId if it was returned
-$templateId = $(Get-Content $response | ConvertFrom-Json).envelopeTemplates.templateId
+$templateIds = $(Get-Content $response | ConvertFrom-Json).envelopeTemplates.templateId
-Write-Output "Did we find any templateIds?: $templateId"
+Write-Output "Did we find any templateIds?: $templateIds"
-if (-not ([string]::IsNullOrEmpty($templateId))) {
+if (-not ([string]::IsNullOrEmpty($templateIds))) {
Write-Output "Your account already includes the '${templateName}' template."
# Save the template id for use by other scripts
+ $templateId = $templateIds -split ' ' | Select-Object -First 1
Write-Output "${templateId}" > .\config\TEMPLATE_ID
Remove-Item $response
Write-Output "Done."
@@ -56,13 +57,17 @@ $requestData = New-TemporaryFile
$requestDataTemp = New-TemporaryFile
$doc1Base64 = New-TemporaryFile
-Write-Output "Sending the template create request to DocuSign..."
+Write-Output "Sending the template create request to Docusign..."
# Fetch document and encode
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_fields.pdf"))) > $doc1Base64
# Concatenate the different parts of the request
+#ds-snippet-start:eSign8Step2
@{
+ description = "Example template created via the eSignature API";
+ name = "Example Signer and CC template v2";
+ shared = "false";
documents = @(
@{
documentBase64 = "$(Get-Content $doc1Base64)";
@@ -72,11 +77,6 @@ Write-Output "Sending the template create request to DocuSign..."
};
);
emailSubject = "Please sign this document";
- envelopeTemplateDefinition = @{
- description = "Example template created via the API";
- name = "Example Signer and CC template";
- shared = "false";
- };
recipients = @{
carbonCopies = @(
@{recipientId = "2"; roleName = "cc"; routingOrder = "2"; };
@@ -161,12 +161,15 @@ Write-Output "Sending the template create request to DocuSign..."
tabLabel = "text"; width = 84;
xPosition = "153"; yPosition = "230";
};
+ );
+ numericalTabs = @(
@{
+ ValidationType = "Currency";
documentId = "1"; font = "helvetica";
fontSize = "size14"; height = 23;
pageNumber = "1"; required = "false";
- tabLabel = "numbersOnly"; width = 84;
- xPosition = "153"; yPosition = "260";
+ tabLabel = "numericalCurrency"; width = 84;
+ xPosition = "153"; yPosition = "230";
};
);
};
@@ -175,7 +178,9 @@ Write-Output "Sending the template create request to DocuSign..."
};
status = "created";
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign8Step2
+#ds-snippet-start:eSign8Step3
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/templates" `
-Method 'POST' `
@@ -185,6 +190,7 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign8Step3
Write-Output "Results:"
Get-Content $response
diff --git a/examples/eSignature/eg009UseTemplate.ps1 b/examples/eSignature/eg009UseTemplate.ps1
index 2c3b65f..d3c2dc5 100644
--- a/examples/eSignature/eg009UseTemplate.ps1
+++ b/examples/eSignature/eg009UseTemplate.ps1
@@ -2,7 +2,7 @@
$apiUri = "https://demo.docusign.net/restapi"
-# Send a signing request via email using a DocuSign template
+# Send a signing request via email using a Docusign template
# Get required environment variables from .\config\settings.json file
$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
@@ -22,14 +22,14 @@ if (-not (Test-Path .\config\TEMPLATE_ID)) {
exit 0
}
-# ***DS.snippet.0.start
# Step 2. Create the envelope definition from a template
# temp files:
$response = New-TemporaryFile
$requestData = New-TemporaryFile
-Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "Sending the envelope request to Docusign..."
+#ds-snippet-start:eSign9Step2
@{
templateId = "$(Get-Content .\config\TEMPLATE_ID)";
templateRoles = @(
@@ -46,8 +46,10 @@ Write-Output "Sending the envelope request to DocuSign..."
);
status = "sent";
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign9Step2
# Step 3. Create and send the envelope
+#ds-snippet-start:eSign9Step3
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
-Method 'POST' `
@@ -57,6 +59,7 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign9Step3
Write-Output "Response:"
diff --git a/examples/eSignature/eg010SendBinaryDocs.ps1 b/examples/eSignature/eg010SendBinaryDocs.ps1
index d5b94f5..18fb0cc 100644
--- a/examples/eSignature/eg010SendBinaryDocs.ps1
+++ b/examples/eSignature/eg010SendBinaryDocs.ps1
@@ -1,3 +1,4 @@
+#ds-snippet-start:eSign10Step3
function Add-OemContent {
param(
$destination,
@@ -5,16 +6,16 @@ function Add-OemContent {
)
Add-Content -Path $destination -Value $content -Encoding oem -NoNewline
}
+#ds-snippet-end:eSign10Step3
# Configuration
-# 1. Get required variables from .\config\settings.json:
+# Get required variables from .\config\settings.json:
$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
$CC_EMAIL = $variables.CC_EMAIL
$CC_NAME = $variables.CC_NAME
$SIGNER_EMAIL = $variables.SIGNER_EMAIL
$SIGNER_NAME = $variables.SIGNER_NAME
-
-# Step 2. Obtain your OAuth access token
+# Obtain your OAuth access token
$accessToken = Get-Content ".\config\ds_access_token.txt"
# Obtain your accountId from demo.docusign.net -- the account id is shown in
@@ -22,9 +23,8 @@ $accessToken = Get-Content ".\config\ds_access_token.txt"
# the default picture.
$accountId = Get-Content ".\config\API_ACCOUNT_ID"
-# ***DS.snippet.0.start
-
-# Step 3. Construct the request body
+#ds-snippet-start:eSign10Step3
+# Construct the request body
# document 1 (html) has tag **signature_1**
# document 2 (docx) has tag /sn1/
# document 3 (pdf) has tag /sn1/
@@ -45,7 +45,7 @@ $doc1 = Get-Item ".\demo_documents\doc_1.html"
$doc2 = Get-Item ".\demo_documents\World_Wide_Corp_Battle_Plan_Trafalgar.docx"
$doc3 = Get-Item ".\demo_documents\World_Wide_Corp_lorem.pdf"
-Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "Sending the envelope request to Docusign..."
Write-Output "The envelope has three documents. Processing time will be about 15 seconds."
Write-Output "Results:"
@@ -142,26 +142,32 @@ Add-OemContent $requestData "${CRLF}"
# Add closing boundary
Add-OemContent $requestData "--$boundary--"
Add-OemContent $requestData "${CRLF}"
+#ds-snippet-end:eSign10Step3
+
+#ds-snippet-start:eSign10Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "multipart/form-data; boundary=${boundary}";
+}
+#ds-snippet-end:eSign10Step2
# Send request
try {
- # Step 4. Call the eSignature REST API
+ # Call the eSignature REST API
+ #ds-snippet-start:eSign10Step4
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
-Method 'POST' `
- -Headers @{
- 'Authorization' = "Bearer $accessToken";
- 'Content-Type' = "multipart/form-data; boundary=${boundary}";
- } `
+ -Headers $headers `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
Write-Output "Response: $(Get-Content -Raw $response)"
+ #ds-snippet-end:eSign10Step4
}
catch {
Write-Error $_
}
-# ***DS.snippet.0.end
Get-Content $response
diff --git a/examples/eSignature/eg011EmbeddedSending.ps1 b/examples/eSignature/eg011EmbeddedSending.ps1
index 33b8c18..d992d70 100644
--- a/examples/eSignature/eg011EmbeddedSending.ps1
+++ b/examples/eSignature/eg011EmbeddedSending.ps1
@@ -2,7 +2,7 @@ $apiUri = "https://demo.docusign.net/restapi"
# Use embedded sending:
# 1. create a draft envelope with three documents
-# 2. Open the sending view of the DocuSign web tool
+# 2. Open the sending view of the Docusign web tool
# Configuration
# 1. Get required variables from .\config\settings.json:
@@ -24,19 +24,19 @@ $accountId = Get-Content .\config\API_ACCOUNT_ID
# The sending editor can be opened in either of two views:
Enum ViewType {
- TaggingView = 1;
- RecipientsAndDocuments = 2;
+ Tagger = 1;
+ Prepare = 2;
}
$startingView = $null;
do {
Write-Output 'Select the initial sending view: '
- Write-Output "$([int][ViewType]::TaggingView) - Tagging view"
- Write-Output "$([int][ViewType]::RecipientsAndDocuments) - Recipients and documents view"
+ Write-Output "$([int][ViewType]::Tagger) - Tagging view"
+ Write-Output "$([int][ViewType]::Prepare) - Prepare view"
[int]$startingView = Read-Host "Please make a selection"
} while (-not [ViewType]::IsDefined([ViewType], $startingView));
+[string]$startingView = [ViewType]::GetName([ViewType], $startingView)
-# ***DS.snippet.0.start
# Step 2. Create the envelope
# Create the document request body
@@ -53,19 +53,26 @@ do {
# The envelope will be sent first to the signer.
# After it is signed, a copy is sent to the cc person.
+#ds-snippet-start:eSign11Step2
# temp files:
$requestData = New-TemporaryFile
+$senderViewRequestData = New-TemporaryFile
$response = New-TemporaryFile
$doc1Base64 = New-TemporaryFile
$doc2Base64 = New-TemporaryFile
$doc3Base64 = New-TemporaryFile
# Fetch docs and encode
-[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\doc_1.html"))) > $doc1Base64
+$doc1String = [System.IO.File]::ReadAllText((Resolve-Path ".\demo_documents\doc_1.html"))
+$doc1String = $doc1String.Replace("{USER_EMAIL}", $SIGNER_EMAIL)
+$doc1String = $doc1String.Replace("{USER_FULLNAME}", $SIGNER_NAME)
+$doc1String = $doc1String.Replace("{CC_EMAIL}", $CC_EMAIL)
+$doc1String = $doc1String.Replace("{CC_NAME}", $CC_NAME)
+[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($doc1String)) > $doc1Base64
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_Battle_Plan_Trafalgar.docx"))) > $doc2Base64
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $doc3Base64
-Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "Sending the envelope request to Docusign..."
Write-Output "The envelope has three documents. Processing time will be about 15 seconds."
Write-Output "Results:"
@@ -136,8 +143,10 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign11Step2
# Step 3. Create the sender view
+#ds-snippet-start:eSign11Step3
# pull out the envelopeId
$envelop = $response | Get-Content | ConvertFrom-Json
Write-Output "Envelope received: $envelop"
@@ -145,10 +154,40 @@ $envelopeId = $envelop.envelopeId
Write-Output "Requesting the sender view url"
-# The returnUrl is normally your own web app. DocuSign will redirect
+@{
+ returnUrl = "http://httpbin.org/get";
+ viewAccess = "envelope";
+ settings = @{
+ startingScreen = $startingView;
+ sendButtonAction = "send";
+ showBackButton = "false";
+ backButtonAction = "previousPage";
+ showHeaderActions = "false";
+ showDiscardAction = "false";
+ lockToken = "";
+ recipientSettings = @{
+ showEditRecipients = "false";
+ showContactsList = "false";
+ };
+ documentSettings = @{
+ showEditDocuments = "false";
+ showEditDocumentVisibility = "false";
+ showEditPages = "false";
+ };
+ taggerSettings = @{
+ paletteSections = "default";
+ paletteDefault = "custom";
+ };
+ templateSettings = @{
+ showMatchingTemplatesPrompt = "true";
+ };
+ };
+} | ConvertTo-Json -Depth 32 >> $senderViewRequestData
+
+# The returnUrl is normally your own web app. Docusign will redirect
# the signer to returnUrl when the embedded sending completes.
# For this example, we'll use http://httpbin.org/get to show the
-# query parameters passed back from DocuSign
+# query parameters passed back from Docusign
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/sender" `
-Method 'POST' `
@@ -156,17 +195,12 @@ Invoke-RestMethod `
'Authorization' = "Bearer $accessToken";
'Content-Type' = "application/json";
} `
- -Body (@{ returnUrl = "http://httpbin.org/get"; } | ConvertTo-Json) `
+ -InFile (Resolve-Path $senderViewRequestData).Path `
-OutFile $response
$sendingObj = $response | Get-Content | ConvertFrom-Json
$sendingUrl = $sendingObj.url
-# Next, we update the returned url if we want to start with the Recipient
-# and Documents view
-if ($startingView -eq [ViewType]::RecipientsAndDocuments) {
- $sendingUrl = $sendingUrl -replace "send=1", "send=0"
-}
-# ***DS.snippet.0.end
+#ds-snippet-end:eSign11Step3
Write-Output "The embedded sending URL is ${sendingUrl}"
Write-Output "It is only valid for five minutes. Attempting to automatically open your browser..."
@@ -175,6 +209,7 @@ Start-Process $sendingUrl
# cleanup
Remove-Item $requestData
+Remove-Item $senderViewRequestData
Remove-Item $response
Remove-Item $doc1Base64
Remove-Item $doc2Base64
diff --git a/examples/eSignature/eg012EmbeddedConsole.ps1 b/examples/eSignature/eg012EmbeddedConsole.ps1
index 49f07b1..dcecf22 100644
--- a/examples/eSignature/eg012EmbeddedConsole.ps1
+++ b/examples/eSignature/eg012EmbeddedConsole.ps1
@@ -1,6 +1,6 @@
$apiUri = "https://demo.docusign.net/restapi"
-# Redirect to the DocuSign console web tool
+# Redirect to the Docusign console web tool
# Step 1. Obtain your Oauth access token
@@ -19,10 +19,10 @@ if (-not (Test-Path .\config\ENVELOPE_ID)) {
# Check that we have an envelope id
$envelopeId = Get-Content .\config\ENVELOPE_ID
-# The returnUrl is normally your own web app. DocuSign will redirect
+# The returnUrl is normally your own web app. Docusign will redirect
# the signer to returnUrl when the embedded signing completes.
# For this example, we'll use http://httpbin.org/get to show the
-# query parameters passed back from DocuSign
+# query parameters passed back from Docusign
# The web tool console can be opened in either of two views:
# The sending editor can be opened in either of two views:
@@ -42,6 +42,7 @@ do {
Write-Output "Requesting the console view url"
+#ds-snippet-start:eSign12Step2
$requestBody = switch ($selectedView) {
{ [ViewType]::FrontPage } {
@{
@@ -58,7 +59,6 @@ $requestBody = switch ($selectedView) {
}
$requestBody
-# Step 2. Call the eSignature REST API
$console = Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/views/console" `
-Method "POST" `
@@ -71,8 +71,8 @@ $console = Invoke-RestMethod `
Write-Output "Results:"
Write-Output "Console received: $console"
$consoleUrl = $console.url
+#ds-snippet-end:eSign12Step2
-# ***DS.snippet.0.end
Write-Output "The console URL is $consoleUrl"
Write-Output "It is only valid for five minutes. Attempting to automatically open your browser..."
Start-Process $consoleUrl
diff --git a/examples/eSignature/eg013AddDocToTemplate.ps1 b/examples/eSignature/eg013AddDocToTemplate.ps1
index 1ea9854..0d0fde5 100644
--- a/examples/eSignature/eg013AddDocToTemplate.ps1
+++ b/examples/eSignature/eg013AddDocToTemplate.ps1
@@ -28,16 +28,16 @@ $requestData = New-TemporaryFile
$response = New-TemporaryFile
$doc1Base64 = New-TemporaryFile
-# ***DS.snippet.0.start
# Fetch docs and encode
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\added_document.html"))) > $doc1Base64
-Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "Sending the envelope request to Docusign..."
Write-Output "A template is used, it has one document. A second document will be"
Write-Output "added by using Composite Templates"
# Concatenate the different parts of the request
# document 1 (html) has tag **signature_1**
+#ds-snippet-start:eSign13Step2
@{
compositeTemplates = @(
@{
@@ -63,7 +63,7 @@ Write-Output "added by using Composite Templates"
};
);
};
- sequence = "1";
+ sequence = "2";
};
);
serverTemplates = @(
@@ -111,14 +111,17 @@ Write-Output "added by using Composite Templates"
};
);
};
- sequence = "2";
+ sequence = "1";
};
);
};
);
status = "sent";
} | ConvertTo-Json -Depth 32 > $requestData
-# Step 3. Call DocuSign to create the envelope
+#ds-snippet-end:eSign13Step2
+
+# Step 3. Call Docusign to create the envelope
+#ds-snippet-start:eSign13Step3
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
-Method 'POST' `
@@ -128,6 +131,7 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign13Step3
Write-Output "Results:"
Get-Content $response
@@ -139,10 +143,11 @@ Write-Output "EnvelopeId: $envelopeId"
# Step 4. Create the recipient view definition
# that the signer will directly open in their browser to sign.
#
-# The returnUrl is normally your own web app. DocuSign will redirect
+# The returnUrl is normally your own web app. Docusign will redirect
# the signer to returnUrl when the signing completes.
# For this example, we'll use http://httpbin.org/get to show the
-# query parameters passed back from DocuSign
+# query parameters passed back from Docusign
+#ds-snippet-start:eSign13Step4
Write-Output "Requesting the url for the embedded signing..."
@{
@@ -167,7 +172,7 @@ Write-Output "Response:"
Get-Content $response
$signingUrl = $(Get-Content $response | ConvertFrom-Json).url
-# ***DS.snippet.0.end
+#ds-snippet-end:eSign13Step4
Write-Output "The embedded signing URL is $signingUrl"
Write-Output "It is only valid for five minutes. Attempting to automatically open your browser..."
diff --git a/examples/eSignature/eg014CollectPayment.ps1 b/examples/eSignature/eg014CollectPayment.ps1
index aabf743..6bb413d 100644
--- a/examples/eSignature/eg014CollectPayment.ps1
+++ b/examples/eSignature/eg014CollectPayment.ps1
@@ -13,12 +13,11 @@ $accessToken = Get-Content .\config\ds_access_token.txt
# the default picture.
$accountId = Get-Content .\config\API_ACCOUNT_ID
-# Step 2. Log in to DocuSign Admin and from the top
+# Step 2. Log in to Docusign Admin and from the top
# navigation, select Admin. From there look
# to the left under INTEGRATIONS and select
# Payments to retrieve your Gateway account ID.
-# ***DS.snippet.0.start
# Step 3. Create the envelope definition
@@ -30,9 +29,10 @@ $doc1Base64 = New-TemporaryFile
# Fetch doc and encode
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\order_form.html"))) > $doc1Base64
-Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "Sending the envelope request to Docusign..."
# Concatenate the different parts of the request
+#ds-snippet-start:eSign14Step3
@{
emailSubject = "Please complete your order";
documents = @(
@@ -159,8 +159,9 @@ Write-Output "Sending the envelope request to DocuSign..."
};
status = "sent";
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign14Step3
-# Step 4. Call the eSignature REST API
+#ds-snippet-start:eSign14Step4
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
-Method 'POST' `
@@ -170,7 +171,7 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
-# ***DS.snippet.0.end
+#ds-snippet-end:eSign14Step4
Write-Output "Results:"
Get-Content $response
diff --git a/examples/eSignature/eg015EnvelopeTabData.ps1 b/examples/eSignature/eg015EnvelopeTabData.ps1
index 7011c5e..a2c8213 100644
--- a/examples/eSignature/eg015EnvelopeTabData.ps1
+++ b/examples/eSignature/eg015EnvelopeTabData.ps1
@@ -20,18 +20,22 @@ else {
}
# Step 2. Create your authorization headers
+#ds-snippet-start:eSign15Step2
$headers = @{
'Authorization' = "Bearer $accessToken";
'Accept' = "application/json";
'Content-Type' = "application/json";
}
+#ds-snippet-end:eSign15Step2
# Step 3. a) Make a GET call to the form_data endpoint to retrieve your envelope tab values
# b) Display the JSON response
+#ds-snippet-start:eSign15Step3
$result = $(Invoke-WebRequest `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/form_data" `
-Method 'GET' `
-Headers $headers)
+#ds-snippet-end:eSign15Step3
if ( $result.StatusCode -gt 201) {
Write-Output "Retrieving envelope form data has failed."
diff --git a/examples/eSignature/eg016SetTabValues.ps1 b/examples/eSignature/eg016SetTabValues.ps1
index 9cdf58b..107e9d0 100644
--- a/examples/eSignature/eg016SetTabValues.ps1
+++ b/examples/eSignature/eg016SetTabValues.ps1
@@ -13,20 +13,29 @@ $accessToken = Get-Content .\config\ds_access_token.txt
# Note: Substitute these values with your own
$accountId = Get-Content .\config\API_ACCOUNT_ID
+# Step 2. Create your authorization headers
+#ds-snippet-start:eSign16Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+}
+#ds-snippet-end:eSign16Step2
+
# Tabs and custom fields shown in the request body in step 4
-# Step 4. Construct the request body
+# Step 3. Construct the request body
# Temp files:
$requestData = New-TemporaryFile
$response = New-TemporaryFile
$doc1Base64 = New-TemporaryFile
-Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "Sending the envelope request to Docusign..."
# Fetch doc and encode
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_salary.docx"))) > $doc1Base64
+#ds-snippet-start:eSign16Step3
@{
customFields = @{
textCustomFields = @(@{
@@ -61,7 +70,28 @@ Write-Output "Sending the envelope request to DocuSign..."
anchorXOffset = "20";
anchorYOffset = "10";
}; );
- textTabs = @(@{
+ numericalTabs = @(@{
+ ValidationType = "Currency";
+ XPosition = "210";
+ YPosition = "235";
+ Height = "20";
+ Width = "70";
+ PageNumber = "1";
+ DocumentId = "1";
+ MinNumericalValue = "0";
+ MaxNumericalValue = "1000000";
+ TabId = "salary";
+ TabLabel = "Salary";
+ NumericalValue = "123000";
+ LocalPolicy = @{
+ CultureName = "en-US";
+ CurrencyCode = "usd";
+ CurrencyPositiveFormat = "csym_1_comma_234_comma_567_period_89";
+ CurrencyNegativeFormat = "minus_csym_1_comma_234_comma_567_period_89";
+ UseLongCurrencyFormat = "true";
+ };
+ }; );
+ textTabs = @(@{
anchorString = "/legal/";
anchorUnits = "pixels";
anchorXOffset = "5";
@@ -85,26 +115,16 @@ Write-Output "Sending the envelope request to DocuSign..."
tabId = "familiar_name";
tabLabel = "Familiar name";
value = $variables.SIGNER_NAME;
- }; @{
- anchorString = "/salary/";
- anchorUnits = "pixels";
- anchorXOffset = "5";
- anchorYOffset = "-9";
- bold = "true";
- font = "helvetica";
- fontSize = "size11";
- locked = "true";
- tabId = "salary";
- tabLabel = "Salary";
- value = "$123,000.00";
- }; );
+ };);
};
}; );
};
status = "Sent";
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign16Step3
-# Step 5. Call the eSignature REST API
+# Step 4. Call the eSignature REST API
+#ds-snippet-start:eSign16Step4
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
-Method 'POST' `
@@ -114,6 +134,7 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign16Step4
Write-Output "Response:"
Get-Content $response
@@ -128,13 +149,14 @@ Write-Output $envelopeId > .\config\ENVELOPE_ID
# Step 6. Create a recipient view (an embedded signing view)
# that the signer will directly open in their browser to sign
#
-# The return URL is normally your own web app. DocuSign will redirect
-# the signer to the return URL when the DocuSign signing completes.
+# The return URL is normally your own web app. Docusign will redirect
+# the signer to the return URL when the Docusign signing completes.
# For this example, we'll use http://httpbin.org/get to show the
-# query parameters passed back from DocuSign
+# query parameters passed back from Docusign
Write-Output "Requesting the url for the embedded signing..."
+#ds-snippet-start:eSign16Step5
@{
returnUrl = "http://httpbin.org/get";
authenticationMethod = "none";
@@ -146,15 +168,13 @@ Write-Output "Requesting the url for the embedded signing..."
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/recipient" `
-Method 'POST' `
- -Headers @{
- 'Authorization' = "Bearer $accessToken";
- 'Content-Type' = "application/json";
-} `
+ -Headers $headers `
-InFile (Resolve-Path $requestData).Path`
-OutFile $response
Write-Output "Response:"
Get-Content $response
+#ds-snippet-end:eSign16Step5
$signingUrl = $(Get-Content $response | ConvertFrom-Json).url
diff --git a/examples/eSignature/eg017SetTemplateTabValues.ps1 b/examples/eSignature/eg017SetTemplateTabValues.ps1
index d2271aa..2129d22 100644
--- a/examples/eSignature/eg017SetTemplateTabValues.ps1
+++ b/examples/eSignature/eg017SetTemplateTabValues.ps1
@@ -17,6 +17,13 @@ $accountId = Get-Content .\config\API_ACCOUNT_ID
$requestData = New-TemporaryFile
$response = New-TemporaryFile
+#ds-snippet-start:eSign17Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ }
+#ds-snippet-end:eSign17Step2
+
# Check that we have a template ID
if (Test-Path .\config\TEMPLATE_ID) {
$templateId = Get-Content .\config\TEMPLATE_ID
@@ -26,17 +33,52 @@ else {
exit 0
}
-Write-Output "Sending the envelope request to DocuSign..."
+Write-Output "Sending the envelope request to Docusign..."
+# Step 3. Create tabs and custom fields
+#ds-snippet-start:eSign17Step3
+$text_custom_fields = @{
+ "name" = "app metadata item"
+ "required" = "false"
+ "show" = "true"
+ "value" = "1234567"
+}
+
+$checkbox_tabs = @{
+ "selected1" = "true"
+ "tabLabel1" = "ckAuthorization"
+ "selected2" = "true"
+ "tabLabel2" = "ckAgreement"
+}
+
+$list_tabs = @{
+ "documentId" = "1"
+ "pageNumber" = "1"
+ "tabLabel" = "list"
+ "value" = "green"
+}
+
+$radio_tabs = @{
+ "selected" = "true"
+ "value" = "white"
+}
+
+$text_tabs = @{
+ "tabLabel" = "text"
+ "value" = "Jabberywocky!"
+}
+#ds-snippet-end:eSign17Step3
+
# Tabs and custom fields shown in the request body on step 4
# Step 4. Construct the request body
+#ds-snippet-start:eSign17Step4
@{
customFields = @{
textCustomFields = @(
@{
- name = "app metadata item";
- required = "false";
- show = "true";
- value = "1234567";
+ name = $($text_custom_fields['name']);
+ required = $($text_custom_fields['required']);
+ show = $($text_custom_fields['show']);
+ value = $($text_custom_fields['value']);
};
);
};
@@ -49,20 +91,20 @@ Write-Output "Sending the envelope request to DocuSign..."
tabs = @{
checkboxTabs = @(
@{
- selected = "true";
- tabLabel = "ckAuthorization";
+ selected = $($checkbox_tabs['selected1']);
+ tabLabel = $($checkbox_tabs['tabLabel1']);
};
@{
- selected = "true";
- tabLabel = "ckAgreement";
+ selected = $($checkbox_tabs['selected2']);
+ tabLabel = $($checkbox_tabs['tabLabel2']);
};
);
listTabs = @(
@{
- documentId = "1";
- pageNumber = "1";
- tabLabel = "list";
- value = "green";
+ documentId = $($list_tabs['documentId']);
+ pageNumber = $($list_tabs['pageNumber']);
+ tabLabel = $($list_tabs['tabLabel']);
+ value = $($list_tabs['value']);
};
);
radioGroupTabs = @(
@@ -70,16 +112,16 @@ Write-Output "Sending the envelope request to DocuSign..."
groupName = "radio1";
radios = @(
@{
- selected = "true";
- value = "white";
+ selected = $($radio_tabs['selected']);
+ value = $($radio_tabs['value']);
};
);
};
);
textTabs = @(
@{
- tabLabel = "text";
- value = "Jabberywocky!";
+ tabLabel = $($text_tabs['tabLabel']);
+ value = $($text_tabs['value']);
};
@{
bold = "true";
@@ -109,17 +151,17 @@ Write-Output "Sending the envelope request to DocuSign..."
status = "Sent";
templateId = "$templateId";
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign17Step4
# Step 5. Call the eSignature REST API
+#ds-snippet-start:eSign17Step5
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
-Method 'POST' `
- -Headers @{
- 'Authorization' = "Bearer $accessToken";
- 'Content-Type' = "application/json";
-} `
+ -Headers $headers `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign17Step5
Write-Output "Response:"
Get-Content $response
@@ -131,13 +173,14 @@ Write-Output "EnvelopeId: $envelopeId"
# Step 6. Create a recipient view (an embedded signing view)
# that the signer will directly open in their browser to sign
#
-# The return URL is normally your own web app. DocuSign will redirect
-# the signer to the return URL when the DocuSign signing completes.
+# The return URL is normally your own web app. Docusign will redirect
+# the signer to the return URL when the Docusign signing completes.
# For this example, we'll use http://httpbin.org/get to show the
-# query parameters passed back from DocuSign
+# query parameters passed back from Docusign
Write-Output "Requesting the url for the embedded signing..."
+#ds-snippet-start:eSign17Step6
@{
returnUrl = "http://httpbin.org/get";
authenticationMethod = "none";
@@ -155,6 +198,7 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path`
-OutFile $response
+#ds-snippet-end:eSign17Step6
Write-Output "Response:"
Get-Content $response
diff --git a/examples/eSignature/eg018EnvelopeCustomFieldData.ps1 b/examples/eSignature/eg018EnvelopeCustomFieldData.ps1
index c5ae849..fb7a7dc 100644
--- a/examples/eSignature/eg018EnvelopeCustomFieldData.ps1
+++ b/examples/eSignature/eg018EnvelopeCustomFieldData.ps1
@@ -25,17 +25,24 @@ else {
exit 1
}
-Write-Output "Sending the EnvelopeCustomFields::list request to DocuSign..."
+Write-Output "Sending the EnvelopeCustomFields::list request to Docusign..."
+
+# Step 2. Create your authorization headers
+#ds-snippet-start:eSign18Step2
+$headers = @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+}
+#ds-snippet-end:eSign18Step2
# Step 3. Call the eSignature REST API
+#ds-snippet-start:eSign18Step3
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/custom_fields" `
-Method 'GET' `
- -Headers @{
- 'Authorization' = "Bearer $accessToken";
- 'Content-Type' = "application/json";
-} `
+ -Headers $headers `
-OutFile $response
+#ds-snippet-end:eSign18Step3
Write-Output "Results:"
diff --git a/examples/eSignature/eg019SigningViaEmailWithAccessCode.ps1 b/examples/eSignature/eg019SigningViaEmailWithAccessCode.ps1
index e65e025..3ab04cf 100644
--- a/examples/eSignature/eg019SigningViaEmailWithAccessCode.ps1
+++ b/examples/eSignature/eg019SigningViaEmailWithAccessCode.ps1
@@ -1,9 +1,8 @@
# https://developers.docusign.com/docs/esign-rest-api/how-to/require-access-code-recipient/
-# Get required environment variables from .\config\settings.json file
-$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
-$SIGNER_EMAIL = $variables.SIGNER_EMAIL
-$SIGNER_NAME = $variables.SIGNER_NAME
+# Get email and name from the user
+$SIGNER_EMAIL = Read-Host "Please enter a signer email address: "
+$SIGNER_NAME = Read-Host "Please enter a signer name: "
# Get the envelope's custom field data
# This script uses the envelope ID stored in ../envelope_id.
@@ -20,10 +19,12 @@ $APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Step 2. Construct your API headers
# Construct your API headers
+#ds-snippet-start:eSign19Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign19Step2
# Step 3. Construct the request body
# temp files:
@@ -35,6 +36,7 @@ $docBase64 = New-TemporaryFile
$AccessCode = Read-Host "Please enter an access code for recipient authentication"
# Construct your envelope JSON body
+#ds-snippet-start:eSign19Step3
$body = @"
{
"documents": [{
@@ -77,6 +79,7 @@ $body = @"
"status": "Sent"
}
"@
+#ds-snippet-end:eSign19Step3
Write-Output ""
Write-Output "Request: "
Write-Output $body
@@ -84,6 +87,7 @@ Write-Output $body
# Step 4. Call the eSignature REST API
# a) Make a POST call to the createEnvelopes endpoint to create a new envelope.
# b) Display the JSON structure of the created envelope
+#ds-snippet-start:eSign19Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/envelopes"
try {
Write-Output "Response:"
@@ -98,4 +102,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:eSign19Step4
diff --git a/examples/eSignature/eg021SigningViaEmailWithPhoneAuthentication.ps1 b/examples/eSignature/eg020SigningViaEmailWithPhoneAuthentication.ps1
similarity index 57%
rename from examples/eSignature/eg021SigningViaEmailWithPhoneAuthentication.ps1
rename to examples/eSignature/eg020SigningViaEmailWithPhoneAuthentication.ps1
index 2938a72..96734fd 100644
--- a/examples/eSignature/eg021SigningViaEmailWithPhoneAuthentication.ps1
+++ b/examples/eSignature/eg020SigningViaEmailWithPhoneAuthentication.ps1
@@ -2,8 +2,6 @@
# Get required environment variables from .\config\settings.json file
$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
-$SIGNER_EMAIL = $variables.SIGNER_EMAIL
-$SIGNER_NAME = $variables.SIGNER_NAME
$PHONE_NUMBER = $variables.PHONE_NUMBER
# Get the envelope's custom field data
@@ -27,16 +25,51 @@ $docBase64 = New-TemporaryFile
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $docBase64
# Construct your API headers
+#ds-snippet-start:eSign20Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign20Step2
+# - Obtain your workflow ID
+#ds-snippet-start:eSign20Step3
+$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/identity_verification"
+
+Write-Output "Attempting to retrieve your account's workflow ID"
+
+Write-Output "Response:"
+$result = Invoke-RestMethod -uri $uri -headers $headers -method GET
+$result.content
+#Obtain the workflow ID from the API response
+$workflowId = [System.Linq.Enumerable]::FirstOrDefault($result.identityVerification, [func[object, bool]] { param($x) $x.defaultName -eq "Phone Authentication"}).workflowId
+#ds-snippet-end:eSign20Step3
+
+if ($null -eq $workflowId)
+{
+ throw "Please contact https://support.docusign.com to enable recipient phone authentication in your account."
+}
+
+$isDataIncorrect = $true
+while($isDataIncorrect)
+{
+ $SIGNER_NAME = Read-Host "Please enter name for the signer"
+ $SIGNER_EMAIL = Read-Host "Please enter email address for the signer"
+
+ if ($SIGNER_EMAIL -eq $variables.SIGNER_EMAIL) {
+ Write-Output ""
+ Write-Output "For recipient authentication you must specify a different recipient from the account owner (sender) in order to ensure recipient authentication is performed."
+ Write-Output ""
+ } else {
+ $isDataIncorrect = $false
+ }
+}
+
+$SIGNER_COUNTRY_CODE = Read-Host "Please enter a country code for recipient authentication for the signer"
+$SIGNER_PHONE_NUMBER = Read-Host "Please enter a phone number for recipient authentication for the signer"
-$PHONE_NUMBER = $(Read-Host "Please enter a phone number for recipient authentication [415-555-1212]"
-if ($PHONE_NUMBER) {$PHONE_NUMBER} else {'415-555-1212'}
-)
# Construct your envelope JSON body
+#ds-snippet-start:eSign20Step4
$body = @"
{
"documents": [{
@@ -63,33 +96,39 @@ $body = @"
"pageNumber": "1",
"recipientId": "1",
"tabLabel": "SignHereTab",
- "xPosition": "75",
- "yPosition": "572"
+ "xPosition": "200",
+ "yPosition": "160"
}]
},
"templateAccessCodeRequired": null,
"deliveryMethod": "email",
"recipientId": "1",
- "phoneAuthentication": {
- "recordVoicePrint": false,
- "validateRecipProvidedNumber": false,
- "recipMayProvideNumber": true,
- "senderProvidedNumbers": ["$PHONE_NUMBER"]
- },
- "smsAuthentication": null,
- "idCheckConfigurationName": "Phone Auth $",
- "requireIdLookup": true
+ "identityVerification":{
+ "workflowId":"$workflowId",
+ "steps":null,"inputOptions":[
+ {"name":"phone_number_list",
+ "valueType":"PhoneNumberList",
+ "phoneNumberList":[
+ {
+ "countryCode":"$SIGNER_COUNTRY_CODE",
+ "number":"$SIGNER_PHONE_NUMBER"
+ }
+ ]
+ }]
+ }
}]
},
"status": "Sent"
}
"@
+#ds-snippet-end:eSign20Step4
Write-Output ""
Write-Output "Request: "
Write-Output $body
# a) Make a POST call to the createEnvelopes endpoint to create a new envelope.
# b) Display the JSON structure of the created envelope
+#ds-snippet-start:eSign20Step5
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/envelopes"
try {
Write-Output "Response:"
@@ -105,6 +144,7 @@ catch {
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
}
+#ds-snippet-end:eSign20Step5
# cleanup
-Remove-Item $docBase64
\ No newline at end of file
+Remove-Item $docBase64
diff --git a/examples/eSignature/eg020SigningViaEmailWithSmsAuthentication.ps1 b/examples/eSignature/eg020SigningViaEmailWithSmsAuthentication.ps1
deleted file mode 100644
index a96f89b..0000000
--- a/examples/eSignature/eg020SigningViaEmailWithSmsAuthentication.ps1
+++ /dev/null
@@ -1,94 +0,0 @@
-# https://developers.docusign.com/docs/esign-rest-api/how-to/sms-auth/
-
-# Get required environment variables from .\config\settings.json file
-$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
-$SIGNER_EMAIL = $variables.SIGNER_EMAIL
-$SIGNER_NAME = $variables.SIGNER_NAME
-
-# Get the envelope's custom field data
-# This script uses the envelope ID stored in ../envelope_id.
-# The envelope_id file is created by example eg016SetTabValues.ps1 or
-# can be manually created.
-
-# Step 1: Obtain your OAuth token
-# Note: Substitute these values with your own
-$oAuthAccessToken = Get-Content .\config\ds_access_token.txt
-
-#Set up variables for full code example
-# Note: Substitute these values with your own
-$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
-
-# Construct your API headers
-$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
-$headers.add("Authorization", "Bearer $oAuthAccessToken")
-$headers.add("Accept", "application/json")
-$headers.add("Content-Type", "application/json")
-
-# temp files:
-$docBase64 = New-TemporaryFile
-
-# Fetch docs and encode
-[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $docBase64
-
-$PHONE_NUMBER = $(Read-Host "Please enter an SMS number for recipient authentication [415-555-1212]"
-if ($PHONE_NUMBER){$PHONE_NUMBER} else {'415-555-1212'}
-)
-# Construct your envelope JSON body
-$body = @"
-{
- "documents": [{
- "documentBase64": "$(Get-Content $docBase64)",
- "documentId": "1",
- "fileExtension": "pdf",
- "name": "Terms of Service"
- }],
- "emailBlurb": "Sample text for email body",
- "emailSubject": "Please Sign",
- "envelopeIdStamping": "true",
- "recipients": {
- "signers": [{
- "name": "$SIGNER_NAME",
- "email": "$SIGNER_EMAIL",
- "roleName": "",
- "note": "",
- "routingOrder": 3,
- "status": "created",
- "templateAccessCodeRequired": null,
- "deliveryMethod": "email",
- "recipientId": "1",
- "accessCode": "",
- "smsAuthentication": {
- "senderProvidedNumbers": ["$PHONE_NUMBER"]
- },
- "idCheckConfigurationName": "SMS Auth $",
- "requireIdLookup": true
- }]
- },
- "status": "Sent"
-}
-"@
-Write-Output ""
-Write-Output "Request: "
-Write-Output $body
-
-$uri = "https://demo.docusign.net/restapi/v2.1/accounts/${APIAccountId}/envelopes"
-
-# a) Make a POST call to the createEnvelopes endpoint to create a new envelope.
-# b) Display the JSON structure of the created envelope
-try {
- Write-Output "Response:"
- $result = Invoke-WebRequest -uri $uri -headers $headers -body $body -method POST
- $result.content
-}
-catch {
- $int = 0
- foreach ($header in $_.Exception.Response.Headers) {
- if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
- $int++
- }
- Write-Output "Error : "$_.ErrorDetails.Message
- Write-Output "Command : "$_.InvocationInfo.Line
-}
-
-# cleanup
-Remove-Item $docBase64
\ No newline at end of file
diff --git a/examples/eSignature/eg022SigningViaEmailWithKnoweldgeBasedAuthentication.ps1 b/examples/eSignature/eg022SigningViaEmailWithKnowledgeBasedAuthentication.ps1
similarity index 80%
rename from examples/eSignature/eg022SigningViaEmailWithKnoweldgeBasedAuthentication.ps1
rename to examples/eSignature/eg022SigningViaEmailWithKnowledgeBasedAuthentication.ps1
index 47b2f55..1d10b93 100644
--- a/examples/eSignature/eg022SigningViaEmailWithKnoweldgeBasedAuthentication.ps1
+++ b/examples/eSignature/eg022SigningViaEmailWithKnowledgeBasedAuthentication.ps1
@@ -2,8 +2,6 @@
# Get required environment variables from .\config\settings.json file
$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
-$SIGNER_EMAIL = $variables.SIGNER_EMAIL
-$SIGNER_NAME = $variables.SIGNER_NAME
# Get the envelope's custom field data
# This script uses the envelope ID stored in ../envelope_id.
@@ -26,12 +24,30 @@ $docBase64 = New-TemporaryFile
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $docBase64
# Construct your API headers
+#ds-snippet-start:eSign22Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign22Step2
+
+$isDataIncorrect = $true
+while($isDataIncorrect)
+{
+ $SIGNER_NAME = Read-Host "Please enter name for the signer"
+ $SIGNER_EMAIL = Read-Host "Please enter email address for the signer"
+
+ if ($SIGNER_EMAIL -eq $variables.SIGNER_EMAIL) {
+ Write-Output ""
+ Write-Output "For recipient authentication you must specify a different recipient from the account owner (sender) in order to ensure recipient authentication is performed."
+ Write-Output ""
+ } else {
+ $isDataIncorrect = $false
+ }
+}
# Construct your envelope JSON body
+#ds-snippet-start:eSign22Step3
$body = @"
{
"documents": [{
@@ -69,12 +85,14 @@ $body = @"
"status": "Sent"
}
"@
+#ds-snippet-end:eSign22Step3
Write-Output ""
Write-Output "Request: "
Write-Output $body
# a) Make a POST call to the createEnvelopes endpoint to create a new envelope.
# b) Display the JSON structure of the created envelope
+#ds-snippet-start:eSign22Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/envelopes"
try {
Write-Output "Response:"
@@ -90,6 +108,7 @@ catch {
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
}
+#ds-snippet-end:eSign22Step4
# cleanup
Remove-Item $docBase64
\ No newline at end of file
diff --git a/examples/eSignature/eg023SigningViaEmailWithIDVAuthentication.ps1 b/examples/eSignature/eg023SigningViaEmailWithIDVAuthentication.ps1
index 8df5d62..f6414a6 100644
--- a/examples/eSignature/eg023SigningViaEmailWithIDVAuthentication.ps1
+++ b/examples/eSignature/eg023SigningViaEmailWithIDVAuthentication.ps1
@@ -26,38 +26,50 @@ $docBase64 = New-TemporaryFile
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $docBase64
# - Construct your API headers
+#ds-snippet-start:eSign23Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json, text/plain, */*")
$headers.add("Content-Type", "application/json;charset=UTF-8")
$headers.add("Accept-Encoding", "gzip, deflate, br")
$headers.add("Accept-Language", "en-US,en;q=0.9")
+#ds-snippet-end:eSign23Step2
# - Obtain your workflow ID
+#ds-snippet-start:eSign23Step3
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/identity_verification"
-
Write-Output "Attempting to retrieve your account's workflow ID"
-try {
- Write-Output "Response:"
- $result = Invoke-RestMethod -uri $uri -headers $headers -method GET
- $result.content
- #Obtain the workflow ID from the API response
- $workflowId = $result.identityVerification.workflowId
+Write-Output "Response:"
+$result = Invoke-RestMethod -uri $uri -headers $headers -method GET
+$result.content
+#Obtain the workflow ID from the API response
+$workflowId = [System.Linq.Enumerable]::FirstOrDefault($result.identityVerification, [func[object, bool]] { param($x) $x.defaultName -eq "DocuSign ID Verification"}).workflowId
+#ds-snippet-end:eSign23Step3
+
+if ($null -eq $workflowId)
+{
+ throw "Please contact https://support.docusign.com to enable IDV in your account."
}
-catch {
- $int = 0
- foreach ($header in $_.Exception.Response.Headers) {
- #On error, display the error, the line that triggered the error, and the TraceToken
- if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
- $int++
+
+$isDataIncorrect = $true
+while($isDataIncorrect)
+{
+ $SIGNER_NAME = Read-Host "Please enter name for the signer"
+ $SIGNER_EMAIL = Read-Host "Please enter email address for the signer"
+
+ if ($SIGNER_EMAIL -eq $variables.SIGNER_EMAIL) {
+ Write-Output ""
+ Write-Output "For recipient authentication you must specify a different recipient from the account owner (sender) in order to ensure recipient authentication is performed."
+ Write-Output ""
+ } else {
+ $isDataIncorrect = $false
}
- Write-Output "Error : "$_.ErrorDetails.Message
- Write-Output "Command : "$_.InvocationInfo.Line
}
# - Construct your envelope JSON body
# Note: If you did not successfully obtain your workflow ID, this step will fail.
+#ds-snippet-start:eSign23Step4
$body = @"
{
"documents": [{
@@ -82,8 +94,8 @@ $body = @"
"pageNumber": "1",
"recipientId":"1",
"tabLabel": "SignHereTab",
- "xPosition": "75",
- "yPosition": "572"
+ "xPosition": "200",
+ "yPosition": "160"
}]
},
"templateAccessCodeRequired": null,
@@ -100,17 +112,25 @@ $body = @"
"status": "Sent"
}
"@
+#ds-snippet-end:eSign23Step4
Write-Output ""
Write-Output "Request: "
Write-Output $body
# a) Make a POST call to the createEnvelopes endpoint to create a new envelope.
# b) Display the JSON structure of the created envelope
+#ds-snippet-start:eSign23Step5
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/envelopes"
try {
Write-Output "Response:"
- $result = Invoke-WebRequest -uri $uri -headers $headers -body $body -method POST
- $result.content
+ $result = Invoke-WebRequest -uri $uri -headers $headers -body $body -method POST
+ $response = $result.content | ConvertFrom-Json
+
+ $envelopeId = $response.envelopeId
+
+ # Save the IDV envelope id for use by other scripts
+ Write-Output "IDV EnvelopeId: " $envelopeId
+ Write-Output $envelopeId > .\config\IDV_ENVELOPE_ID
}
catch {
$int = 0
@@ -121,6 +141,7 @@ catch {
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
}
+#ds-snippet-end:eSign23Step5
# cleanup
Remove-Item $docBase64
\ No newline at end of file
diff --git a/examples/eSignature/eg024CreatingPermissionProfiles.ps1 b/examples/eSignature/eg024CreatingPermissionProfiles.ps1
index fb7f5ca..6b3c8e3 100644
--- a/examples/eSignature/eg024CreatingPermissionProfiles.ps1
+++ b/examples/eSignature/eg024CreatingPermissionProfiles.ps1
@@ -8,16 +8,19 @@ $oAuthAccessToken = Get-Content .\config\ds_access_token.txt
# Note: Substitute these values with your own
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
-$PROFILE_NAME = Read-Host "Please enter a new permission profile name"
+$PROFILE_NAME = Read-Host "Please enter a new permission profile name: "
$PROFILE_NAME > .\config\PROFILE_NAME
# Construct your API headers
+#ds-snippet-start:eSign24Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign24Step2
# Construct the request body for your permission profile
+#ds-snippet-start:eSign24Step3
$body = @"
{
"permissionProfileName": "${PROFILE_NAME}",
@@ -31,7 +34,6 @@ $body = @"
"allowedAddressBookAccess":"personalAndShared",
"allowedTemplateAccess":"share",
"enableRecipientViewingNotifications":"true",
- "enableRecipientViewingNotifications":"true",
"enableSequentialSigningInterface":"true",
"receiveCompletedSelfSignedDocumentsAsEmailLinks":"false",
"signingUiVersion":"v2",
@@ -51,9 +53,11 @@ $body = @"
}
}
"@
+#ds-snippet-end:eSign24Step3
# a) Call the eSignature API
# b) Display the JSON response
+#ds-snippet-start:eSign24Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/permission_profiles/"
try {
@@ -71,4 +75,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:eSign24Step4
\ No newline at end of file
diff --git a/examples/eSignature/eg025SettingPermissionProfiles.ps1 b/examples/eSignature/eg025SettingPermissionProfiles.ps1
index 8848f74..192d76f 100644
--- a/examples/eSignature/eg025SettingPermissionProfiles.ps1
+++ b/examples/eSignature/eg025SettingPermissionProfiles.ps1
@@ -19,15 +19,18 @@ else {
# Step 2. Construct your API headers
# Construct your API headers
+#ds-snippet-start:eSign25Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign25Step2
$GROUP_NAME = Read-Host "Please enter a NEW group name"
# Step 3. Construct the request body
# Create a Group and get a Group ID
+#ds-snippet-start:eSign25Step3
$body = @"
{
"groups": [
@@ -37,6 +40,7 @@ $body = @"
]
}
"@
+#ds-snippet-end:eSign25Step3
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/groups"
$response = Invoke-WebRequest -uri $uri -headers $headers -body $body -method POST
$groupId = $($response.Content | ConvertFrom-Json).groups.groupId
@@ -57,6 +61,7 @@ $body = @"
# a) Call the eSignature API
# b) Display the JSON response
+#ds-snippet-start:eSign25Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/groups"
$response = $null
@@ -74,4 +79,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:eSign25Step4
\ No newline at end of file
diff --git a/examples/eSignature/eg026UpdatingIndividualPermission.ps1 b/examples/eSignature/eg026UpdatingIndividualPermission.ps1
index 3b514f3..f07ff02 100644
--- a/examples/eSignature/eg026UpdatingIndividualPermission.ps1
+++ b/examples/eSignature/eg026UpdatingIndividualPermission.ps1
@@ -9,10 +9,12 @@ $oAuthAccessToken = Get-Content .\config\ds_access_token.txt
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Construct your API headers
+#ds-snippet-start:eSign26Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign26Step2
# Check that we have an profile name
if (Test-Path .\config\PROFILE_NAME) {
@@ -33,6 +35,7 @@ else {
}
# Construct your request body
+#ds-snippet-start:eSign26Step3
$body = @"
{
"permissionProfileName": "${profileName}",
@@ -65,9 +68,11 @@ $body = @"
}
}
"@
+#ds-snippet-end:eSign26Step3
# a) Call the eSignature API
# b) Display the JSON response
+#ds-snippet-start:eSign26Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/permission_profiles/${profileId}"
try {
@@ -84,4 +89,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:eSign26Step4
\ No newline at end of file
diff --git a/examples/eSignature/eg027DeletingPermissions.ps1 b/examples/eSignature/eg027DeletingPermissions.ps1
index 9dfbdac..6d062da 100644
--- a/examples/eSignature/eg027DeletingPermissions.ps1
+++ b/examples/eSignature/eg027DeletingPermissions.ps1
@@ -18,13 +18,16 @@ else {
}
# Construct your API headers
+#ds-snippet-start:eSign27Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign27Step2
# a) Call the eSignature API
# b) Display the JSON response
+#ds-snippet-start:eSign27Step3
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/permission_profiles/$profileID"
try {
@@ -40,4 +43,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:eSign27Step3
\ No newline at end of file
diff --git a/examples/eSignature/eg028CreatingABrand.ps1 b/examples/eSignature/eg028CreatingABrand.ps1
index ce8bb36..92d4a9b 100644
--- a/examples/eSignature/eg028CreatingABrand.ps1
+++ b/examples/eSignature/eg028CreatingABrand.ps1
@@ -9,23 +9,28 @@ $oAuthAccessToken = Get-Content .\config\ds_access_token.txt
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Construct your API headers
+#ds-snippet-start:eSign28Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign28Step2
$brandName = Read-Host "Please enter a NEW brand name"
# Construct the request body
+#ds-snippet-start:eSign28Step3
$body = @"
{
"brandName": "${brandName}",
"defaultBrandLanguage": "en"
}
"@
+#ds-snippet-end:eSign28Step3
# a) Call the eSignature API
# b) Display the JSON response
+#ds-snippet-start:eSign28Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/brands"
try {
@@ -43,4 +48,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:eSign28Step4
\ No newline at end of file
diff --git a/examples/eSignature/eg029ApplyingBrandEnvelope.ps1 b/examples/eSignature/eg029ApplyingBrandEnvelope.ps1
index ac62de5..3607d69 100644
--- a/examples/eSignature/eg029ApplyingBrandEnvelope.ps1
+++ b/examples/eSignature/eg029ApplyingBrandEnvelope.ps1
@@ -23,12 +23,15 @@ else {
}
# Construct your API headers
+#ds-snippet-start:eSign29Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign29Step2
# Construct your request body
+#ds-snippet-start:eSign29Step3
$body = @"
{
"documents": [{
@@ -65,12 +68,14 @@ $body = @"
"status": "Sent"
}
"@
+#ds-snippet-end:eSign29Step3
Write-Output ""
Write-Output "Request: "
Write-Output $body
# a) Make a POST call to the createEnvelopes endpoint to create a new envelope.
# b) Display the JSON structure of the created envelope
+#ds-snippet-start:eSign29Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/envelopes"
try {
Write-Output "Response:"
@@ -85,4 +90,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:eSign29Step4
\ No newline at end of file
diff --git a/examples/eSignature/eg030ApplyingBrandTemplate.ps1 b/examples/eSignature/eg030ApplyingBrandTemplate.ps1
index c220e10..b47058e 100644
--- a/examples/eSignature/eg030ApplyingBrandTemplate.ps1
+++ b/examples/eSignature/eg030ApplyingBrandTemplate.ps1
@@ -34,12 +34,15 @@ else {
}
# Construct your API headers
+#ds-snippet-start:eSign30Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign30Step2
# Construct your request body
+#ds-snippet-start:eSign30Step3
$body = @"
{
"templateId": "${templateID}",
@@ -59,9 +62,11 @@ $body = @"
"status": "sent"
}
"@
+#ds-snippet-end:eSign30Step3
# a) Make a POST call to the createEnvelopes endpoint to create a new envelope.
# b) Display the JSON structure of the created envelope
+#ds-snippet-start:eSign30Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/envelopes"
try {
@@ -77,4 +82,5 @@ catch {
}
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
-}
\ No newline at end of file
+}
+#ds-snippet-end:eSign30Step4
\ No newline at end of file
diff --git a/examples/eSignature/eg031BulkSending.ps1 b/examples/eSignature/eg031BulkSending.ps1
index 21a759a..abcbf11 100644
--- a/examples/eSignature/eg031BulkSending.ps1
+++ b/examples/eSignature/eg031BulkSending.ps1
@@ -10,18 +10,28 @@ $APIAccountId = Get-Content .\config\API_ACCOUNT_ID
# Get required environment variables from .\config\settings.json file
$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
-$CC_EMAIL = $variables.CC_EMAIL
-$CC_NAME = $variables.CC_NAME
-$SIGNER_EMAIL = $variables.SIGNER_EMAIL
-$SIGNER_NAME = $variables.SIGNER_NAME
+$SIGNER1_EMAIL = Read-Host "Please enter Bulk copy #1 signer email address"
+$SIGNER1_NAME = Read-Host "Please enter Bulk copy #1 signer name"
+$CC1_EMAIL = Read-Host "Please enter Bulk copy #1 carbon copy email address"
+$CC1_NAME = Read-Host "Please enter Bulk copy #1 carbon copy name"
+$SIGNER2_EMAIL = Read-Host "Please enter Bulk copy #2 signer email address"
+$SIGNER2_NAME = Read-Host "Please enter Bulk copy #2 signer name"
+$CC2_EMAIL = Read-Host "Please enter Bulk copy #2 carbon copy email address"
+$CC2_NAME = Read-Host "Please enter Bulk copy #2 carbon copy name"
+
+$doc1Base64 = New-TemporaryFile
+# Fetch doc and encode
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $doc1Base64
# Construct your API headers
+#ds-snippet-start:eSign31Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json, text/plain, */*")
$headers.add("Content-Type", "application/json;charset=UTF-8")
$headers.add("Accept-Encoding", "gzip, deflate, br")
$headers.add("Accept-Language", "en-US,en;q=0.9")
+#ds-snippet-end:eSign31Step2
$continue = $true
@@ -29,40 +39,33 @@ $continue = $true
# Submit the Bulk List
# Create a temporary file to store the JSON body
# The JSON body must contain the recipient role, recipientId, name, and email.
+#ds-snippet-start:eSign31Step3
$body = @"
{
"name": "sample.csv",
"bulkCopies": [{
"recipients": [{
- "recipientId": "39542944",
- "role": "signer",
- "tabs": [],
- "name": "${SIGNER_NAME}",
- "email": "${SIGNER_EMAIL}"
+ "roleName": "signer",
+ "name": "${SIGNER1_NAME}",
+ "email": "${SIGNER1_EMAIL}"
},
{
- "recipientId": "84754526",
- "role": "cc",
- "tabs": [],
- "name": "${CC_NAME}",
- "email": "${CC_EMAIL}"
+ "roleName": "cc",
+ "name": "${CC1_NAME}",
+ "email": "${CC1_EMAIL}"
}],
"customFields": []
},
{
"recipients": [{
- "recipientId": "39542944",
- "role": "signer",
- "tabs": [],
- "name": "${SIGNER_NAME}",
- "email": "${SIGNER_EMAIL}"
+ "roleName": "signer",
+ "name": "${SIGNER2_NAME}",
+ "email": "${SIGNER2_EMAIL}"
},
{
- "recipientId": "84754526",
- "role": "cc",
- "tabs": [],
- "name": "${CC_NAME}",
- "email": "${CC_EMAIL}"
+ "roleName": "cc",
+ "name": "${CC2_NAME}",
+ "email": "${CC2_EMAIL}"
}],
"customFields": []
}]
@@ -96,23 +99,52 @@ catch {
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
}
-
+#ds-snippet-end:eSign31Step3
# Step 4. Create an envelope
# Create your draft envelope
-$base = "DQoNCg0KCQkJCXRleHQgZG9jDQoNCg0KDQoNCg0KUk0gIwlSTSAjCVJNICMNCg0KDQoNClxzMVwNCg0KLy9hbmNoMSANCgkvL2FuY2gyDQoJCS8vYW5jaDM="
+#ds-snippet-start:eSign31Step4
$body = @"
{
"documents": [{
- "documentBase64": "$base",
+ "documentBase64": "$(Get-Content $doc1Base64)",
"documentId": "1",
"fileExtension": "txt",
"name": "NDA"
}],
"envelopeIdStamping": "true",
"emailSubject": "Please sign",
- "cdse_mode": "true",
"recipients": {
- },
+ "signers": [{
+ "name": "Multi Bulk Recipient::signer",
+ "email": "multiBulkRecipients-signer@docusign.com",
+ "roleName": "signer",
+ "routingOrder": "1",
+ "recipientId" : "1",
+ "recipientType" : "signer",
+ "delieveryMethod" : "Email",
+ "status": "created",
+ "tabs": {
+ "signHereTabs": [{
+ "documentId": "1",
+ "name": "SignHereTab",
+ "pageNumber": "1",
+ "recipientId": "1",
+ "tabLabel": "SignHereTab",
+ "xPosition": "200",
+ "yPosition": "160"
+ }]}
+ }],
+ "carbonCopies": [{
+ "name": "Multi Bulk Recipient::cc",
+ "email": "multiBulkRecipients-cc@docusign.com",
+ "roleName": "cc",
+ "routingOrder": "2",
+ "recipientId" : "2",
+ "recipientType" : "cc",
+ "delieveryMethod" : "Email",
+ "status": "created"
+ }]
+ },
"status": "created"
}
"@
@@ -143,11 +175,12 @@ if ($continue -eq $true) {
Write-Output "Command : "$_.InvocationInfo.Line
}
}
-
+#ds-snippet-end:eSign31Step4
# Step 5. Attach your bulk list ID to the envelope
# Add an envelope custom field set to the value of your listId
# This Custom Field is used for tracking your Bulk Send via the Envelopes::Get method
# Create a temporary file to store the JSON body
+#ds-snippet-start:eSign31Step5
$body = @"
{
"listCustomFields": [],
@@ -181,67 +214,11 @@ catch {
Write-Output "Error : "$_.ErrorDetails.Message
Write-Output "Command : "$_.InvocationInfo.Line
}
-
-# Step 6. Add placeholder recipients
-# Add placeholder recipients.
-# Note: The name / email format used is:
-# Name: Multi Bulk Recipients::{rolename}
-# Email: MultiBulkRecipients-{rolename}@docusign.com
-$body = @"
-{
- "signers": [{
- "name": "Multi Bulk Recipient::cc",
- "email": "multiBulkRecipients-cc@docusign.com",
- "roleName": "cc",
- "routingOrder": 1,
- "status": "created",
- "templateAccessCodeRequired": null,
- "deliveryMethod": "email",
- "recipientId": "84754526",
- "recipientType": "signer"
- },
- {
- "name": "Multi Bulk Recipient::signer",
- "email": "multiBulkRecipients-signer@docusign.com",
- "roleName": "signer",
- "routingOrder": 1,
- "status": "created",
- "templateAccessCodeRequired": null,
- "deliveryMethod": "email",
- "recipientId": "39542944",
- "recipientType": "signer"
- }]
-}
-"@
-
-$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/envelopes/$envelopeId/recipients"
-
-if ($continue -eq $true) {
- try {
- Write-Output @"
-
- Adding placeholder recipients to the envelope
-"@
- $response = Invoke-RestMethod -uri $uri -headers $headers -body $body -method POST
- $response | ConvertTo-Json
- }
- catch {
- Write-Output "Adding placeholder recipients has failed"
- #On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error #On failure, display a notification, X-DocuSign-TraceToken, error message, and the command that triggered the error
- $continue = $false
- $int = 0
- foreach ($header in $_.Exception.Response.Headers) {
- if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
- $int++
- }
- Write-Output "Error : "$_.ErrorDetails.Message
- Write-Output "Command : "$_.InvocationInfo.Line
- }
-}
-
-# Step 7. Initiate bulk send
+#ds-snippet-end:eSign31Step5
+# Step 6. Initiate bulk send
# Initiate the Bulk Send
# Target endpoint: {ACCOUNT_ID}/bulk_send_lists/{LIST_ID}/send
+#ds-snippet-start:eSign31Step6
$body = @"
{
"listId": "${listId}",
@@ -273,10 +250,11 @@ if ($continue -eq $true) {
Write-Output "Command : "$_.InvocationInfo.Line
}
}
-
-# Step 8. Confirm successful batch send
+#ds-snippet-end:eSign31Step6
+# Step 7. Confirm successful batch send
# Confirm successful batch send
# Note: Depending on the number of Bulk Recipients, it may take some time for the Bulk Send to complete. For 2000 recipients this can take ~1 hour.
+#ds-snippet-start:eSign31Step7
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/bulk_send_batch/$bulkBatchId"
if ($continue -eq $true) {
$response = $null
@@ -300,3 +278,4 @@ if ($continue -eq $true) {
Write-Output "Command : "$_.InvocationInfo.Line
}
}
+#ds-snippet-end:eSign31Step7
diff --git a/examples/eSignature/eg032PauseSignatureWorkflow.ps1 b/examples/eSignature/eg032PauseSignatureWorkflow.ps1
index 490df95..eb4ef1d 100644
--- a/examples/eSignature/eg032PauseSignatureWorkflow.ps1
+++ b/examples/eSignature/eg032PauseSignatureWorkflow.ps1
@@ -20,12 +20,15 @@ $requestData = New-TemporaryFile
$response = New-TemporaryFile
# Step 2. Construct your API headers
+#ds-snippet-start:eSign32Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign32Step2
# Step 3. Construct the request body
+#ds-snippet-start:eSign32Step3
@{
documents =
@(
@@ -91,8 +94,10 @@ $headers.add("Content-Type", "application/json")
};
status = "sent"
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign32Step3
# Step 4. Call the eSignature API
+#ds-snippet-start:eSign32Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/envelopes"
Invoke-RestMethod `
-Uri $uri `
@@ -103,6 +108,7 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign32Step4
# Get EnvelopeID
$envelopeId = $($(Get-Content $response) | ConvertFrom-Json).envelopeId
diff --git a/examples/eSignature/eg033UnpauseSignatureWorkflow.ps1 b/examples/eSignature/eg033UnpauseSignatureWorkflow.ps1
index 485befe..c0df3de 100644
--- a/examples/eSignature/eg033UnpauseSignatureWorkflow.ps1
+++ b/examples/eSignature/eg033UnpauseSignatureWorkflow.ps1
@@ -22,20 +22,25 @@ else {
}
# Step 2. Construct your API headers
+#ds-snippet-start:eSign33Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign33Step2
# Step 3.Construct the JSON body for your envelope
+#ds-snippet-start:eSign33Step3
@{
workflow =
@{
workflowStatus = "in_progress";
};
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign33Step3
# Step 4. Call the eSignature API
+#ds-snippet-start:eSign33Step4
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/${APIaccountId}/envelopes/${envelopeId}?resend_envelope=true"
Invoke-RestMethod `
-Uri $uri `
@@ -47,6 +52,7 @@ Invoke-RestMethod `
} `
-InFile (Resolve-Path $requestData).Path `
-OutFile $response
+#ds-snippet-end:eSign33Step4
Write-Output ""
Write-Output "Request: $(Get-Content -Raw $requestData)"
diff --git a/examples/eSignature/eg034UseConditionalRecipients.ps1 b/examples/eSignature/eg034UseConditionalRecipients.ps1
index 2f9cd20..ff86d11 100644
--- a/examples/eSignature/eg034UseConditionalRecipients.ps1
+++ b/examples/eSignature/eg034UseConditionalRecipients.ps1
@@ -8,26 +8,43 @@ $oAuthAccessToken = Get-Content .\config\ds_access_token.txt
# Note: Substitute these values with your own
$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+# Get required environment variables from .\config\settings.json file
+$configFile = ".\config\settings.json"
+$config = Get-Content $configFile -Raw | ConvertFrom-Json
+
+if($config.SIGNER_NOT_CHECKED_EMAIL -eq "{SIGNER_NOT_CHECKED_EMAIL}" ){
+ $config.SIGNER_NOT_CHECKED_EMAIL = Read-Host "Enter an email address to route to when the checkbox is not checked"
+ $config.SIGNER_NOT_CHECKED_NAME = Read-Host "Enter a name to route to when the checkbox is not checked"
+ Write-Output ""
+ write-output $config | ConvertTo-Json | Set-Content $configFile
+ }
+
# Get required environment variables from .\config\settings.json file
$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
-$SIGNER1_EMAIL = $variables.CC_EMAIL
-$SIGNER1_NAME = $variables.CC_NAME
+$SIGNER1_EMAIL = $variables.SIGNER_EMAIL
+$SIGNER1_NAME = $variables.SIGNER_NAME
$SIGNER_WHEN_CHECKED_EMAIL = $variables.CC_EMAIL
$SIGNER_WHEN_CHECKED_NAME = $variables.CC_NAME
$SIGNER_NOT_CHECKED_EMAIL = $variables.SIGNER_NOT_CHECKED_EMAIL
$SIGNER_NOT_CHECKED_NAME = $variables.SIGNER_NOT_CHECKED_NAME
+Write-Output "SIGNER_NOT_CHECKED_EMAIL is $SIGNER_NOT_CHECKED_EMAIL"
+Write-Output "SIGNER_NOT_CHECKED_NAME is $SIGNER_NOT_CHECKED_NAME"
+
# Step 2. Construct your API headers
+#ds-snippet-start:eSign34Step2
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.add("Authorization", "Bearer $oAuthAccessToken")
$headers.add("Accept", "application/json")
$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign34Step2
# Create temp files
$requestData = New-TemporaryFile
$response = New-TemporaryFile
# Step 3. Construct the request body
+#ds-snippet-start:eSign34Step3
@{
documents =
@(
@@ -90,6 +107,7 @@ $response = New-TemporaryFile
tabId = "ApprovalTab";
operator = "equals";
value = "false";
+ tabType = "checkbox";
tabLabel = "ApproveWhenChecked"
};
);
@@ -105,6 +123,7 @@ $response = New-TemporaryFile
tabId = "ApprovalTab";
operator = "equals";
value = "true";
+ tabType = "checkbox";
tabLabel = "ApproveWhenChecked"
};
);
@@ -180,9 +199,13 @@ $response = New-TemporaryFile
};
status = "Sent"
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign34Step3
# Step 4. Call the eSignature API
+#ds-snippet-start:eSign34Step4
try {
+ Write-Output "Request: "
+ Write-Output $requestData
$uri = "https://demo.docusign.net/restapi/v2.1/accounts/${APIaccountId}/envelopes"
Invoke-RestMethod `
-Uri $uri `
@@ -201,7 +224,7 @@ catch [System.Net.WebException] {
if ( $errorCode -eq "WORKFLOW_UPDATE_RECIPIENTROUTING_NOT_ALLOWED" ) {
Write-Output ""
Write-Output "The following Error happened: WORKFLOW_UPDATE_RECIPIENTROUTING_NOT_ALLOWED"
- Write-Output "Please contact DocuSign support..."
+ Write-Output "Please contact Docusign support..."
}
else {
$_
@@ -210,7 +233,8 @@ catch [System.Net.WebException] {
catch {
Write-Output $_
}
+#ds-snippet-end:eSign34Step4
# Delete temp files
Remove-Item $requestData
-Remove-Item $response
\ No newline at end of file
+Remove-Item $response
diff --git a/examples/eSignature/eg035ScheduledSending.ps1 b/examples/eSignature/eg035ScheduledSending.ps1
new file mode 100644
index 0000000..1397119
--- /dev/null
+++ b/examples/eSignature/eg035ScheduledSending.ps1
@@ -0,0 +1,113 @@
+#Scheduled Sending
+$apiUri = "https://demo.docusign.net/restapi"
+
+# Send an envelope with one document
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Obtain your accountId from demo.docusign.net -- the account id is shown in
+# the drop down on the upper right corner of the screen by your picture or
+# the default picture.
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# document 1 (pdf) has tag /sn1/
+#
+# The envelope has one recipient.
+# recipient 1 - signer
+# The envelope will be scheduled to go to the signer.
+
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$docBase64 = New-TemporaryFile
+
+# Fetch docs and encode
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $docBase64
+
+Write-Output "Sending the envelope request to Docusign..."
+Write-Output "The envelope has one document. Processing time will be about 15 seconds."
+Write-Output "Results:"
+
+# Step 2. Create the envelope definition
+$ResumeDate = Read-Host "Please enter the future date for when you want to schedule this envelope as YYYY-MM-DD: "
+
+#ds-snippet-start:eSign35Step2
+@{
+ emailSubject = "Please sign this document set";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $docBase64)";
+ name = "Lorem Ipsum";
+ fileExtension = "pdf";
+ documentId = "1";
+ }; );
+ workflow = @{
+ scheduledSending = @{
+ rules = @(
+ @{
+ resumeDate = $ResumeDate;
+ }; );
+ };
+ };
+ recipients = @{
+ signers = @(
+ @{
+ email = $variables.SIGNER_EMAIL;
+ name = $variables.SIGNER_NAME;
+ recipientId = "1";
+ routingOrder = "1";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "**signature_1**";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ @{
+ anchorString = "/sn1/";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ );
+ };
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign35Step2
+
+# Step 3. Create and send the envelope
+#ds-snippet-start:eSign35Step3
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+#ds-snippet-end:eSign35Step3
+
+# pull out the envelopeId
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+
+# Save the envelope id for use by other scripts
+Write-Output "EnvelopeId: $envelopeId"
+Write-Output $envelopeId > .\config\ENVELOPE_ID
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $docBase64
+
+Write-Output "Done."
diff --git a/examples/eSignature/eg036DelayedRouting.ps1 b/examples/eSignature/eg036DelayedRouting.ps1
new file mode 100644
index 0000000..89a7e4c
--- /dev/null
+++ b/examples/eSignature/eg036DelayedRouting.ps1
@@ -0,0 +1,135 @@
+#Delayed Routing
+$apiUri = "https://demo.docusign.net/restapi"
+
+# Send an envelope with one document
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Obtain your accountId from demo.docusign.net -- the account id is shown in
+# the drop down on the upper right corner of the screen by your picture or
+# the default picture.
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# document (pdf) has tag /sn1/
+#
+# The envelope has two recipients.
+# recipient 1 - signer
+# recipient 2 - signer
+# The envelope will be sent first to the signer.
+# After it is signed, a copy is sent to the cc person.
+
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$docBase64 = New-TemporaryFile
+
+# Fetch doc and encode
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $docBase64
+
+Write-Output "Sending the envelope request to Docusign..."
+Write-Output "The envelope has three documents. Processing time will be about 15 seconds."
+Write-Output "Results:"
+
+$Signer2Email = Read-Host "Please enter the email address for the second signer: "
+$Signer2Name = Read-Host "Please enter the name for the second signer: "
+$DelayInHours= Read-Host "Please enter the delay (in hours): "
+$DelayTimeSpan = New-TimeSpan -Hours $DelayInHours -Minutes 0
+
+#ds-snippet-start:eSign36Step2
+@{
+ emailSubject = "Please sign this document set";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $docBase64)";
+ name = "Lorem Ipsum";
+ fileExtension = "pdf";
+ documentId = "1";
+ }; );
+ workflow = @{
+ workflowSteps = @(
+ @{
+ action = "pause_before";
+ triggerOnItem = "routing_order";
+ itemId = "2";
+ delayedRouting = @{
+ rules = @(
+ @{
+ delay = $DelayTimeSpan.ToString();
+ };
+ );
+ };
+ };
+ );
+ };
+ recipients = @{
+ signers = @(
+ @{
+ email = $variables.SIGNER_EMAIL;
+ name = $variables.SIGNER_NAME;
+ recipientId = "1";
+ routingOrder = "1";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "/sn1/";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ );
+ };
+ };
+ @{
+ email = $Signer2Email;
+ name = $Signer2Name;
+ recipientId = "2";
+ routingOrder = "2";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "/sn1/";
+ anchorUnits = "pixels";
+ anchorXOffset = "120";
+ anchorYOffset = "10";
+ };
+ );
+ };
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign36Step2
+
+# Create and send the envelope
+#ds-snippet-start:eSign36Step3
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:eSign36Step3
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+# pull out the envelopeId
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+
+# Save the envelope id for use by other scripts
+Write-Output "EnvelopeId: $envelopeId"
+Write-Output $envelopeId > .\config\ENVELOPE_ID
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $docBase64
+
+Write-Output "Done."
diff --git a/examples/eSignature/eg035SMSDelivery.ps1 b/examples/eSignature/eg037SMSDelivery.ps1
similarity index 77%
rename from examples/eSignature/eg035SMSDelivery.ps1
rename to examples/eSignature/eg037SMSDelivery.ps1
index a5875b9..75c3904 100644
--- a/examples/eSignature/eg035SMSDelivery.ps1
+++ b/examples/eSignature/eg037SMSDelivery.ps1
@@ -1,4 +1,4 @@
-#SMS Delivery
+#SMS or WhatsApp Delivery
$apiUri = "https://demo.docusign.net/restapi"
# Send an envelope with three documents
@@ -13,7 +13,6 @@ $accessToken = Get-Content .\config\ds_access_token.txt
# the default picture.
$accountId = Get-Content .\config\API_ACCOUNT_ID
-# ***DS.snippet.0.start
# document 1 (html) has tag **signature_1**
# document 2 (docx) has tag /sn1/
# document 3 (pdf) has tag /sn1/
@@ -37,16 +36,28 @@ $doc3Base64 = New-TemporaryFile
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_Battle_Plan_Trafalgar.docx"))) > $doc2Base64
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $doc3Base64
-Write-Output "Sending the envelope request to DocuSign..."
-Write-Output "The envelope has three documents. Processing time will be about 15 seconds."
-Write-Output "Results:"
-
# Step 2. Create the envelope definition
-$SMSCountryPrefix = Read-Host "Please enter a country phone number prefix for the Signer"
-$SMSNumber = Read-Host "Please enter an SMS-enabled Phone number for the Signer"
-$SMSCCCountryPrefix = Read-Host "Please enter a country phone number prefix for the Carbon Copied recipient"
-$SMSNumberCC = Read-Host "Please enter an SMS-enabled Phone number for the Carbon Copied recipient"
+Write-Output 'Please choose a message delivery type: '
+Write-Output "$(1) SMS"
+Write-Output "$(2) WhatsApp"
+
+[int]$MSGType = Read-Host "Select 1 or 2"
+
+if ($MSGType -eq 1){
+ $selected = "SMS"
+}
+else {
+ $selected = "WhatsApp"
+}
+
+$MSGCountryPrefix = Read-Host "Please enter a country phone number prefix for the Signer"
+$MSGNumber = Read-Host "Please enter a Mobile number for the Signer"
+$MSGCCCountryPrefix = Read-Host "Please enter a country phone number prefix for the Carbon Copied recipient"
+$MSGNumberCC = Read-Host "Please enter a Mobile number for the Carbon Copied recipient"
+
+
+#ds-snippet-start:eSign37Step2
@{
emailSubject = "Please sign this document set";
documents = @(
@@ -71,37 +82,28 @@ $SMSNumberCC = Read-Host "Please enter an SMS-enabled Phone number for the Carbo
recipients = @{
carbonCopies = @(
@{
- email = $variables.CC_EMAIL;
+ phoneNumber = @{
+ countryCode = $MSGCCCountryPrefix;
+ number = $MSGNumberCC;
+ }
name = $variables.CC_NAME;
recipientId = "2";
routingOrder = "2";
- additionalNotifications = @(
- @{
- secondaryDeliveryMethod = "SMS";
- phoneNumber = @{
- countryCode = $SMSCCCountryPrefix;
- number = $SMSNumberCC;
- }
- }
- );
+ deliveryMethod = $selected;
};
);
signers = @(
@{
- email = $variables.SIGNER_EMAIL;
+ phoneNumber = @{
+ countryCode = $MSGCountryPrefix;
+ number = $MSGNumber;
+
+ }
name = $variables.SIGNER_NAME;
recipientId = "1";
routingOrder = "1";
- additionalNotifications = @(
- @{
- secondaryDeliveryMethod = "SMS";
- phoneNumber = @{
- countryCode = $SMSCountryPrefix;
- number = $SMSNumber;
- }
- }
- );
+ deliveryMethod = $selected;
tabs = @{
signHereTabs = @(
@{
@@ -123,8 +125,16 @@ $SMSNumberCC = Read-Host "Please enter an SMS-enabled Phone number for the Carbo
};
status = "sent";
} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign37Step2
+
+Write-Output "Sending the envelope request to Docusign..."
+Write-Output "The envelope has three documents. Processing time will be about 15 seconds."
+Write-Output "Results:"
+Write-Output $requestData
# Step 3. Create and send the envelope
+# Create and send the envelope
+#ds-snippet-start:eSign37Step3
Invoke-RestMethod `
-Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
-Method 'POST' `
@@ -136,11 +146,11 @@ Invoke-RestMethod `
-OutFile $response
Write-Output "Response: $(Get-Content -Raw $response)"
+#ds-snippet-end:eSign37Step3
# pull out the envelopeId
$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
-# ***DS.snippet.0.end
# Save the envelope id for use by other scripts
Write-Output "EnvelopeId: $envelopeId"
Write-Output $envelopeId > .\config\ENVELOPE_ID
diff --git a/examples/eSignature/eg038ResponsiveSigning.ps1 b/examples/eSignature/eg038ResponsiveSigning.ps1
new file mode 100644
index 0000000..0395b34
--- /dev/null
+++ b/examples/eSignature/eg038ResponsiveSigning.ps1
@@ -0,0 +1,191 @@
+$apiUri = "https://demo.docusign.net/restapi"
+
+# Responsive signing
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+# 1. Obtain your OAuth token
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Obtain your accountId from demo.docusign.net -- the account id is shown in
+# the drop down on the upper right corner of the screen by your picture or
+# the default picture.
+$accountID = Get-Content .\config\API_ACCOUNT_ID
+
+# Step 2. Create the envelope definition.
+# The signer recipient includes a clientUserId setting
+#
+# The envelope will be sent first to the signer.
+# After it is signed, a copy is sent to the cc person.
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$doc_html = New-TemporaryFile
+
+# Fetch doc
+[IO.File]::ReadAllText(".\demo_documents\order_form.html") > $doc_html
+
+# Insert inner HTML
+
+((Get-Content $doc_html) `
+ -replace '/sn1/', ' ' `
+ -replace '/l1q/', ' ' `
+ -replace '/l2q/', ' ') | Set-Content $doc_html
+
+Write-Output "Sending the envelope request to Docusign..."
+
+$price1 = 5
+$price2 = 150
+
+# Concatenate the different parts of the request
+#ds-snippet-start:eSign38Step2
+@{
+ emailSubject = "Example Signing Document";
+ documents = @(
+ @{
+ name = "doc1.html";
+ documentId = "1";
+ htmlDefinition = @{
+ source = "$(Get-Content $doc_html)";
+ };
+ };
+ );
+ recipients = @{
+ signers = @(
+ @{
+ email = $variables.SIGNER_EMAIL;
+ name = $variables.SIGNER_NAME;
+ recipientId = "1";
+ routingOrder = "1";
+ clientUserId = "1000";
+ roleName = "Signer";
+ tabs = @{
+ formulaTabs = @(
+ @{
+ font = "helvetica";
+ fontSize = "size11";
+ fontColor = "black";
+ anchorString = "/l1e/";
+ anchorYOffset = "-8";
+ anchorUnits = "pixels";
+ anchorXOffset = "105";
+ tabLabel = "l1e";
+ formula = "[l1q] * $price1";
+ roundDecimalPlaces = "0";
+ required = "true";
+ locked = "true";
+ disableAutoSize = "false";
+ };
+ @{
+ font = "helvetica";
+ fontSize = "size11";
+ fontColor = "black";
+ anchorString = "/l2e/";
+ anchorYOffset = "-8";
+ anchorUnits = "pixels";
+ anchorXOffset = "105";
+ tabLabel = "l2e";
+ formula = "[l2q] * $price2";
+ roundDecimalPlaces = "0";
+ required = "true";
+ locked = "true";
+ disableAutoSize = "false";
+ };
+ @{
+ font = "helvetica";
+ fontSize = "size11";
+ fontColor = "black";
+ anchorString = "/l3t/";
+ anchorYOffset = "-8";
+ anchorUnits = "pixels";
+ anchorXOffset = "105";
+ tabLabel = "l3t";
+ formula = "[l1e] + [l2e]";
+ roundDecimalPlaces = "0";
+ required = "true";
+ locked = "true";
+ disableAutoSize = "false";
+ bold = "true";
+ };
+ );
+ };
+ };
+ );
+ carbonCopies = @(
+ @{
+ email = $variables.CC_EMAIL;
+ name = $variables.CC_NAME;
+ recipientId = "2";
+ routingOrder = "2";
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign38Step2
+
+# Step 3. Call Docusign to create the envelope
+#ds-snippet-start:eSign38Step3
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:eSign38Step3
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+# pull out the envelopeId
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+Write-Output "EnvelopeId: $envelopeId"
+
+# Step 4. Create a recipient view definition
+# The signer will directly open this link from the browser to sign.
+#
+# The returnUrl is normally your own web app. Docusign will redirect
+# the signer to returnUrl when the signing completes.
+# For this example, we'll use http://httpbin.org/get to show the
+# query parameters passed back from Docusign
+
+Write-Output "Requesting the url for the embedded signing..."
+
+$json = [ordered]@{
+ 'returnUrl' = 'http://httpbin.org/get';
+ 'authenticationMethod' = 'none';
+ 'email' = $variables.SIGNER_EMAIL;
+ 'userName' = $variables.SIGNER_NAME;
+ 'clientUserId' = 1000
+} | ConvertTo-Json -Compress
+
+
+# Step 5. Create the recipient view and begin the Docusign signing
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/recipient" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -Body $json `
+ -OutFile $response
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+$signingUrl = $(Get-Content $response | ConvertFrom-Json).url
+
+Write-Output "The embedded signing URL is $signingUrl"
+Write-Output "It is only valid for five minutes. Attempting to automatically open your browser..."
+
+Start-Process $signingUrl
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $doc_html
+
+Write-Output "Done."
diff --git a/examples/eSignature/eg039SigningInPerson.ps1 b/examples/eSignature/eg039SigningInPerson.ps1
new file mode 100644
index 0000000..9a0b805
--- /dev/null
+++ b/examples/eSignature/eg039SigningInPerson.ps1
@@ -0,0 +1,146 @@
+$apiUri = "https://demo.docusign.net/restapi"
+$authorizationEndpoint = "https://account-d.docusign.com/oauth"
+
+# Step 1: Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Step 2. Create the envelope definition.
+#
+# document 1 (PDF) has tag /sn1/
+# recipient 1 - signer
+# The envelope will be sent first to the signer.
+# After it is signed, a copy is sent to the cc person.
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$docBase64 = New-TemporaryFile
+
+# Fetch doc and encode
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $docBase64
+
+$signerName = Read-Host "Please enter the name of the in person signer"
+
+# Get the current user email
+Invoke-RestMethod `
+ -Uri "${authorizationEndpoint}/userinfo" `
+ -Method 'GET' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Cache-Control' = "no-store";
+ 'Pragma' = "no-cache";
+} `
+ -OutFile $response
+
+$hostEmail = $(Get-Content $response | ConvertFrom-Json).email
+$hostName = $(Get-Content $response | ConvertFrom-Json).name
+
+Write-Output "Sending the envelope request to Docusign..."
+
+# Concatenate the different parts of the request
+#ds-snippet-start:eSign39Step2
+@{
+ emailSubject = "Please sign this document set";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $docBase64)";
+ name = "Lorem Ipsum";
+ fileExtension = "pdf";
+ documentId = "1";
+ };
+ );
+ recipients = @{
+ inPersonSigners = @(
+ @{
+ hostEmail = $hostEmail;
+ hostName = $hostName;
+ signerName = $signerName;
+ recipientId = "1";
+ routingOrder = "1";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "/sn1/";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ );
+ };
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign39Step2
+
+# Step 3. Call Docusign to create the envelope
+#ds-snippet-start:eSign39Step3
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+# pull out the envelopeId
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+Write-Output "EnvelopeId: $envelopeId"
+#ds-snippet-end:eSign39Step3
+
+# Step 4. Create a recipient view definition
+# The signer will directly open this link from the browser to sign.
+#
+# The returnUrl is normally your own web app. Docusign will redirect
+# the signer to returnUrl when the signing completes.
+# For this example, we'll use http://httpbin.org/get to show the
+# query parameters passed back from Docusign
+
+Write-Output "Requesting the url for the embedded signing..."
+
+#ds-snippet-start:eSign39Step4
+$json = [ordered]@{
+ 'returnUrl' = 'http://httpbin.org/get';
+ 'authenticationMethod' = 'none';
+ 'email' = $hostEmail;
+ 'userName' = $hostName;
+} | ConvertTo-Json -Compress
+#ds-snippet-end:eSign39Step4
+
+# Step 5. Create the recipient view and begin the Docusign signing
+#ds-snippet-start:eSign39Step5
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/recipient" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -Body $json `
+ -OutFile $response
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+$signingUrl = $(Get-Content $response | ConvertFrom-Json).url
+#ds-snippet-end:eSign39Step4
+
+Write-Output "The embedded signing URL is $signingUrl"
+Write-Output "It is only valid for five minutes. Attempting to automatically open your browser..."
+
+Start-Process $signingUrl
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $docBase64
+
+Write-Output "Done."
diff --git a/examples/eSignature/eg040SetDocumentVisibility.ps1 b/examples/eSignature/eg040SetDocumentVisibility.ps1
new file mode 100644
index 0000000..a44ef2a
--- /dev/null
+++ b/examples/eSignature/eg040SetDocumentVisibility.ps1
@@ -0,0 +1,173 @@
+$apiUri = "https://demo.docusign.net/restapi"
+
+# Send an envelope and set document visibility
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+
+# Step 1: Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# document 1 (html) has tag **signature_1**
+# document 2 (docx) has tag /sn1/
+# document 3 (pdf) has tag /sn1/
+#
+# The envelope has two recipients.
+# recipient 1 - signer 1
+# recipient 2 - signer 2
+# recipient 3 - cc
+# The envelope will be sent first to the signer.
+# After it is signed, a copy is sent to the cc person.
+
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$doc1Base64 = New-TemporaryFile
+$doc2Base64 = New-TemporaryFile
+$doc3Base64 = New-TemporaryFile
+
+$SIGNER1_EMAIL = Read-Host 'Please enter signer #1 email address'
+$SIGNER1_NAME = Read-Host 'Please enter signer #1 name'
+$SIGNER2_EMAIL = Read-Host 'Please enter signer #2 email address'
+$SIGNER2_NAME = Read-Host 'Please enter signer #2 name'
+$CC_EMAIL = Read-Host 'Please enter carbon copy email address'
+$CC_NAME = Read-Host 'Please enter carbon copy name'
+
+#ds-snippet-start:eSign40Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign40Step2
+
+
+# Fetch docs and encode
+$doc1String = [System.IO.File]::ReadAllText((Resolve-Path ".\demo_documents\doc_1.html"))
+$doc1String = $doc1String.Replace("{USER_EMAIL}", $SIGNER1_EMAIL)
+$doc1String = $doc1String.Replace("{USER_FULLNAME}", $SIGNER1_NAME)
+$doc1String = $doc1String.Replace("{CC_EMAIL}", $CC_EMAIL)
+$doc1String = $doc1String.Replace("{CC_NAME}", $CC_NAME)
+[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($doc1String)) > $doc1Base64
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_Battle_Plan_Trafalgar.docx"))) > $doc2Base64
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $doc3Base64
+
+Write-Output "Sending the envelope request to Docusign..."
+Write-Output "The envelope has three documents. Processing time will be about 15 seconds."
+Write-Output "Results:"
+
+# Concatenate the different parts of the request
+#ds-snippet-start:eSign40Step3
+@{
+ emailSubject = "Please sign this document set";
+ enforceSignerVisibility = "true";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $doc1Base64)";
+ name = "Order acknowledgement";
+ fileExtension = "html";
+ documentId = "1";
+ };
+ @{
+ documentBase64 = "$(Get-Content $doc2Base64)";
+ name = "Battle Plan";
+ fileExtension = "docx";
+ documentId = "2";
+ };
+ @{
+ documentBase64 = "$(Get-Content $doc3Base64)";
+ name = "Lorem Ipsum";
+ fileExtension = "pdf";
+ documentId = "3";
+ }; );
+ recipients = @{
+ carbonCopies = @(
+ @{
+ email = $CC_EMAIL;
+ name = $CC_NAME;
+ recipientId = "3";
+ routingOrder = "3";
+ };
+ );
+ signers = @(
+ @{
+ email = $SIGNER1_EMAIL;
+ name = $SIGNER1_NAME;
+ recipientId = "1";
+ routingOrder = "1";
+ excludedDocuments = @(2, 3)
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "**signature_1**";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ );
+ };
+ };
+ @{
+ email = $SIGNER2_EMAIL;
+ name = $SIGNER2_NAME;
+ recipientId = "2";
+ routingOrder = "2";
+ excludedDocuments = @(1)
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "/sn1/";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ );
+ };
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign40Step3
+
+# Step 3. Create and send the envelope'
+#ds-snippet-start:eSign40Step4
+try {
+ Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers $headers `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:eSign40Step4
+
+ Write-Output "Response: $(Get-Content -Raw $response)"
+
+ # pull out the envelopeId
+ $envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+
+ Write-Output "EnvelopeId: $envelopeId"
+}
+catch {
+ $errorMessage = $_.ErrorDetails.Message
+ Write-Host $errorMessage
+ Write-Host ""
+
+ if ( $errorMessage.Contains("ACCOUNT_LACKS_PERMISSIONS") ) {
+ Write-Host "See https://developers.docusign.com/docs/esign-rest-api/how-to/set-document-visibility in the Docusign Developer Center for instructions on how to enable document visibility in your developer account."
+ }
+}
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $doc1Base64
+Remove-Item $doc2Base64
+Remove-Item $doc3Base64
+
+Write-Output "Done."
diff --git a/examples/eSignature/eg041EmbeddedSigningCFR.ps1 b/examples/eSignature/eg041EmbeddedSigningCFR.ps1
new file mode 100644
index 0000000..feb582e
--- /dev/null
+++ b/examples/eSignature/eg041EmbeddedSigningCFR.ps1
@@ -0,0 +1,191 @@
+$apiUri = "https://demo.docusign.net/restapi"
+$configPath = ".\config\settings.json"
+$tokenPath = ".\config\ds_access_token.txt"
+$accountIdPath = ".\config\API_ACCOUNT_ID"
+
+
+# Check the folder structure to switch paths for Quick ACG
+if ((Test-Path $configPath) -eq $false) {
+ $configPath = "..\config\settings.json"
+}
+if ((Test-Path $tokenPath) -eq $false) {
+ $tokenPath = "..\config\ds_access_token.txt"
+}
+if ((Test-Path $accountIdPath) -eq $false) {
+ $accountIdPath = "..\config\API_ACCOUNT_ID"
+}
+
+# Use embedded signing
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content $configPath -Raw | ConvertFrom-Json
+$SIGNER_EMAIL = $variables.SIGNER_EMAIL
+$SIGNER_NAME = $variables.SIGNER_NAME
+$PHONE_NUMBER = $variables.PHONE_NUMBER
+
+# 1. Obtain your OAuth token
+$oAuthAccessToken = Get-Content .\config\ds_access_token.txt
+
+# Obtain your accountId from demo.docusign.net -- the account id is shown in
+# the drop down on the upper right corner of the screen by your picture or
+# the default picture.
+$accountID = Get-Content $accountIdPath
+$APIAccountId = Get-Content .\config\API_ACCOUNT_ID
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$doc1Base64 = New-TemporaryFile
+
+$docPath = ".\demo_documents\World_Wide_Corp_lorem.pdf"
+
+# Check the folder structure to switch paths for Quick ACG
+if ((Test-Path $docPath) -eq $false) {
+ $docPath = "..\demo_documents\World_Wide_Corp_lorem.pdf"
+}
+
+# Fetch doc and encode
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path $docPath))) > $doc1Base64
+# - Obtain your workflow ID
+#ds-snippet-start:eSign41Step2
+$uri = "https://demo.docusign.net/restapi/v2.1/accounts/$APIAccountId/identity_verification"
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $oAuthAccessToken")
+$headers.add("Accept", "application/json")
+$headers.add("Content-Type", "application/json")
+Write-Output "Attempting to retrieve your account's workflow ID"
+
+$result = Invoke-RestMethod -uri $uri -headers $headers -method GET
+$result.content
+#Obtain the workflow ID from the API response
+$workflowId = [System.Linq.Enumerable]::FirstOrDefault($result.identityVerification, [func[object, bool]] { param($x) $x.defaultName -eq "SMS for Access & Signatures"}).workflowId
+#ds-snippet-end:eSign41Step2
+
+if ($null -eq $workflowId)
+{
+ throw "Please contact https://support.docusign.com to enable recipient phone authentication in your account."
+}
+
+# Concatenate the different parts of the request
+$SIGNER_COUNTRY_CODE = Read-Host "Please enter a country phone number prefix for the Signer"
+
+$SIGNER_PHONE_NUMBER = Read-Host "Please enter an SMS-enabled Phone number for the Signer"
+
+Write-Output "Sending the envelope request to Docusign..."
+
+# Construct your envelope JSON body
+#ds-snippet-start:eSign41Step3
+$body = @"
+{
+ "documents": [{
+ "documentBase64": "$(Get-Content $doc1Base64)",
+ "documentId": "1",
+ "fileExtension": "pdf",
+ "name": "Lorem"
+ }],
+ "emailBlurb": "Please let us know if you have any questions.",
+ "emailSubject": "Part 11 Example Consent Form",
+ "envelopeIdStamping": "true",
+ "recipients": {
+ "signers": [{
+ "name": "$SIGNER_NAME",
+ "email": "$SIGNER_EMAIL",
+ "roleName": "",
+ "note": "",
+ "routingOrder": 2,
+ "clientUserID": 1000,
+ "status": "created",
+ "tabs": {
+ "signHereTabs": [{
+ "documentId": "1",
+ "name": "SignHereTab",
+ "pageNumber": "1",
+ "recipientId": "1",
+ "tabLabel": "SignHereTab",
+ "xPosition": "200",
+ "yPosition": "150"
+ }]
+ },
+ "templateAccessCodeRequired": null,
+ "deliveryMethod": "email",
+ "recipientId": "1",
+ "identityVerification":{
+ "workflowId":"$workflowId",
+ "steps":null,"inputOptions":[
+ {"name":"phone_number_list",
+ "valueType":"PhoneNumberList",
+ "phoneNumberList":[
+ {
+ "countryCode":"$SIGNER_COUNTRY_CODE",
+ "number":"$SIGNER_PHONE_NUMBER"
+ }
+ ]
+ }]
+ }
+ }]
+ },
+ "status": "Sent"
+}
+"@
+#ds-snippet-end:eSign41Step3
+Write-Output ""
+
+#ds-snippet-start:eSign41Step4
+$uri = "${apiUri}/v2.1/accounts/$APIAccountId/envelopes"
+$result = Invoke-WebRequest -uri $uri -headers $headers -body $body -method POST -UseBasicParsing -OutFile $response
+$result.content
+
+# pull out the envelopeId
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+#ds-snippet-end:eSign41Step4
+
+# Create a recipient view definition
+# The signer will directly open this link from the browser to sign.
+#
+# The returnUrl is normally your own web app. Docusign will redirect
+# the signer to returnUrl when the signing completes.
+# For this example, we'll use http://httpbin.org/get to show the
+# query parameters passed back from Docusign
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+
+Write-Output "Requesting the url for the embedded signing..."
+#ds-snippet-start:eSign41Step5
+$json = [ordered]@{
+ 'returnUrl' = 'http://httpbin.org/get';
+ 'authenticationMethod' = 'none';
+ 'email' = $variables.SIGNER_EMAIL;
+ 'userName' = $variables.SIGNER_NAME;
+ 'clientUserId' = 1000
+} | ConvertTo-Json -Compress
+#ds-snippet-end:eSign41Step5
+
+# Create the recipient view and begin the Docusign signing
+#ds-snippet-start:eSign41Step6
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/recipient" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $oAuthAccessToken";
+ 'Content-Type' = "application/json";
+} `
+ -Body $json `
+ -OutFile $response
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+$signingUrl = $(Get-Content $response | ConvertFrom-Json).url
+#ds-snippet-end:eSign41Step6
+
+Write-Output "The embedded signing URL is $signingUrl"
+Write-Output "It is only valid for five minutes. Attempting to automatically open your browser..."
+
+Start-Process $signingUrl
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $doc1Base64
+
+Write-Output "Done."
diff --git a/examples/eSignature/eg042DocumentGeneration.ps1 b/examples/eSignature/eg042DocumentGeneration.ps1
new file mode 100644
index 0000000..a0902e6
--- /dev/null
+++ b/examples/eSignature/eg042DocumentGeneration.ps1
@@ -0,0 +1,316 @@
+$apiUri = "https://demo.docusign.net/restapi"
+
+# Step 1= Obtain your OAuth token
+# Note= Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note= Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+
+# Create a template
+#
+# The envelope has one document and one signer/recipient
+# The document must be a Word docx file
+# Adding five DocGen fields that will be dynamically set later
+
+# temp files=
+$requestData = New-TemporaryFile
+$requestDataTemp = New-TemporaryFile
+$doc1Base64 = New-TemporaryFile
+$response = New-TemporaryFile
+
+
+$templateName = "Example document generation template"
+
+Write-Output "Sending the template create request to Docusign..."
+
+# Fetch document and encode
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\Offer_Letter_Dynamic_Table.docx"))) > $doc1Base64
+
+# Concatenate the different parts of the request
+#ds-snippet-start:eSign42Step2
+@{
+ description = "Example template created via the API";
+ name = "${templateName}";
+ shared = "false";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $doc1Base64)";
+ documentId = "1";
+ fileExtension = "docx";
+ order = "1";
+ pages = "1";
+ name = "Offer Letter Demo";
+ isDocGenDocument = "true";
+
+ };
+ );
+ emailSubject = "Please sign this document";
+ recipients = @{
+ signers = @(
+ @{
+ recipientId = "1";
+ roleName = "signer";
+ routingOrder = "1";
+ };
+ );
+ };
+ status = "created";
+ } | ConvertTo-Json -Depth 32 > $requestData
+
+Write-Output "${apiUri}/v2.1/accounts/${accountId}/templates"
+
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/templates" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+
+# pull out the template id
+$templateId = $(Get-Content $response | ConvertFrom-Json).templateId
+#ds-snippet-end:eSign42Step2
+Write-Output "Template '${templateName}' was created! Template ID ${templateId}."
+
+# Add a document with merge fields to your template
+#ds-snippet-start:eSign42Step3
+@{
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $doc1Base64)";
+ documentId = "1";
+ fileExtension = "docx";
+ order = "1";
+ pages = "1";
+ name = "Offer Letter Demo";
+
+ };
+ );
+} | ConvertTo-Json -Depth 32 > $requestData
+
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/templates/${templateId}/documents/1" `
+ -Method 'PUT' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:eSign42Step3
+
+# Add tabs to the template
+#ds-snippet-start:eSign42Step4
+@{
+ signHereTabs = @(
+ @{
+ anchorString = "Employee Signature";
+ anchorUnits = "pixels";
+ anchorXOffset = "5";
+ anchorYOffset = "-22";
+ };
+ );
+ dateSignedTabs = @(
+ @{
+ anchorString = "Date Signed";
+ anchorUnits = "pixels";
+ anchorYOffset = "-22";
+ };
+ );
+} | ConvertTo-Json -Depth 32 > $requestData
+
+
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/templates/${templateId}/recipients/1/tabs" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:eSign42Step4
+
+# Create an envelope draft from a template
+# Leave envelope in "draft"/"created" status, don't send it yet
+#ds-snippet-start:eSign42Step5
+@{
+ templateId = "${templateId}";
+ templateRoles = @(
+ @{
+ email = $variables.SIGNER_EMAIL;
+ name = $variables.SIGNER_NAME;
+ roleName = "signer";
+ };
+ );
+ status = "created";
+} | ConvertTo-Json -Depth 32 > $requestData
+
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+
+# pull out the envelope id
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+#ds-snippet-end:eSign42Step5
+
+Write-Output "Envelope '${templateName}' draft was created! Envelope ID ${envelopeId}."
+
+# Get DocGenFormFields
+#ds-snippet-start:eSign42Step6
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/docGenFormFields" `
+ -Method 'GET' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+-OutFile $response
+
+Write-Output "Response:"
+Get-Content $response
+
+# pull out the document id value
+$documentId = $(Get-Content $response | ConvertFrom-Json).docGenFormFields[0].documentId
+#ds-snippet-end:eSign42Step6
+
+Write-Output "Document ID ${documentId}."
+
+# Build the request to update the data fields in the envelope that we created from the template
+# Collect user data to send to API/Document fields
+$CandidateName = Read-Host "Enter candidate name"
+$ManagerName = Read-Host "Enter manager name"
+$StartDate = Read-Host "Enter start date"
+Write-Host "Enter salary: $" -NoNewLine
+$Salary = Read-Host
+$Rsus = Read-Host "Enter RSUs"
+Write-Output "Choose job title"
+Write-Output "1 - Software Engineer"
+Write-Output "2 - Account Executive"
+$JobTitle = "Software Engineer"
+$JobNumber = Read-Host
+if ($JobNumber -eq "2") {
+ $JobTitle = "Account Executive"
+}
+
+#ds-snippet-start:eSign42Step7
+@{
+ docGenFormFields = @(
+ @{
+ documentId = "${documentId}";
+ docGenFormFieldList = @(
+ @{
+ name = "Candidate_Name";
+ value = "${CandidateName}";
+ };
+ @{
+ name = "Job_Title";
+ value = "${JobTitle}";
+ };
+ @{
+ name = "Manager_Name";
+ value = "${ManagerName}";
+ };
+ @{
+ name = "Start_Date";
+ value = "${StartDate}";
+ };
+ @{
+ name = "Compensation_Package";
+ type = "TableRow";
+ rowValues = @(
+ @{
+ docGenFormFieldList = @(
+ @{
+ name = "Compensation_Component";
+ value = "Salary";
+ };
+ @{
+ name = "Details";
+ value = "$" + "${Salary}";
+ }
+ )
+ };
+ @{
+ docGenFormFieldList = @(
+ @{
+ name = "Compensation_Component";
+ value = "Bonus";
+ };
+ @{
+ name = "Details";
+ value = "20%";
+ }
+ )
+ };
+ @{
+ docGenFormFieldList = @(
+ @{
+ name = "Compensation_Component";
+ value = "RSUs";
+ };
+ @{
+ name = "Details";
+ value = $rsus;
+ }
+ )
+ }
+ )
+ }
+ )
+ }
+ )
+} | ConvertTo-Json -Depth 32 > $requestData
+
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/docgenformfields" `
+ -Method 'PUT' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:eSign42Step7
+
+# Send the envelope
+#ds-snippet-start:eSign42Step8
+@{
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/" `
+ -Method 'PUT' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:eSign42Step8
+Write-Output "Response:"
+Get-Content $response
+
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $requestDataTemp
+Remove-Item $response
+Remove-Item $doc1Base64
+
+Write-Output "Done."
diff --git a/examples/eSignature/eg043SharedAccess.ps1 b/examples/eSignature/eg043SharedAccess.ps1
new file mode 100644
index 0000000..f9104bc
--- /dev/null
+++ b/examples/eSignature/eg043SharedAccess.ps1
@@ -0,0 +1,223 @@
+. "utils/invokeScript.ps1"
+
+$apiUri = "https://demo.docusign.net/restapi"
+$accountUri = "https://account-d.docusign.com"
+
+$accessToken = Get-Content .\config\ds_access_token.txt
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+$requestData = New-TemporaryFile
+$requestDataTemp = New-TemporaryFile
+$response = New-TemporaryFile
+
+#ds-snippet-start:eSign43Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign43Step2
+
+Write-Output ""
+$agentName = Read-Host "Please enter the name of the new agent"
+Write-Output ""
+$agentEmail = Read-Host "Please enter the email address of the new agent"
+Write-Output ""
+$activation = Read-Host "Please input an activation code for the new agent. Save this code. You'll need it when activating the new agent."
+
+#ds-snippet-start:eSign43Step3
+try {
+ # Check, if the agent already exists
+ Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/users?email=${agentEmail}&status=Active" `
+ -Method 'GET' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ } `
+ -OutFile $response
+
+ Write-Output ""
+ Write-Output "Response:"
+ Write-Output ""
+ Get-Content $response
+
+ $agentUserId = $(Get-Content $response | ConvertFrom-Json).users.userId
+} catch {
+ # Create a new agent in the account
+ @{
+ newUsers = @(
+ @{
+ activationAccessCode = $activation;
+ userName = $agentName;
+ email = $agentEmail;
+ };
+ );
+ } | ConvertTo-Json -Depth 32 > $requestData
+
+ Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/users" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ } `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+
+ Write-Output ""
+ Write-Output "Response:"
+ Write-Output ""
+ Get-Content $response
+
+ $agentUserId = $(Get-Content $response | ConvertFrom-Json).newUsers.userId
+ #ds-snippet-end:eSign43Step3
+}
+
+Write-Output ""
+Write-Output "Agent has been created. Please go to the agent's email to activate the agent, and press 1 to continue the example: "
+
+$choice = Read-Host
+if ($choice -ne "1") {
+ Write-Output "Closing the example... "
+ exit 1
+}
+
+try {
+ # Get user id of the currently logged user
+ Invoke-RestMethod `
+ -Uri "${accountUri}/oauth/userinfo" `
+ -Method 'GET' `
+ -Headers @{
+ 'Cache-Control' = "no-store";
+ 'Pragma' = "cache";
+ 'Authorization' = "Bearer $accessToken";
+ } `
+ -Body @{ "from_date" = ${fromDate} } `
+ -OutFile $response
+
+ $userId = $(Get-Content $response | ConvertFrom-Json).sub
+} catch {
+ Write-Output "Unable to retrieve Bulk Status."
+
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+}
+
+#ds-snippet-start:eSign43Step4
+$isUserActivated = 0;
+
+do {
+ try {
+ # Check, if authorization exists
+ Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/users/${agentUserId}/authorizations/agent?permissions=manage" `
+ -Method 'GET' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ } `
+ -OutFile $response
+
+ if ([string]::IsNullOrEmpty($(Get-Content $response | ConvertFrom-Json).authorizations)) {
+ # Sharing the envelope with the agent
+ $body = @"
+ {
+ "agentUser":
+ {
+ "userId": "${agentUserId}",
+ "accountId": "${accountId}"
+ },
+ "permission": "manage"
+ }
+"@
+
+ Write-Output ""
+ $uri = "${apiUri}/v2.1/accounts/${accountId}/users/${userId}/authorization"
+
+ $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+ $headers.add("Authorization", "Bearer $accessToken")
+ $headers.add("Content-Type", "application/json")
+
+ Invoke-WebRequest -uri $uri -headers $headers -body $body -method POST -UseBasicParsing -OutFile $response
+
+ Write-Output "Response:"
+ Write-Output "$(Get-Content -Raw $response)"
+ }
+
+ $isUserActivated = 1;
+ #ds-snippet-end:eSign43Step4
+ } catch {
+ Write-Output "Agent has been created. Please go to the agent's email to activate the agent, and press 1 to continue the example: "
+
+ $choice = Read-Host
+ if ($choice -ne "1") {
+ Write-Output "Closing the example... "
+ exit 1
+ }
+ }
+} while (!$isUserActivated)
+
+# Principal is told to log out and log in as the new agent
+Write-Output ""
+Write-Output "Please go to the principal's developer account at admindemo.docusign.com and log out, then come back to this terminal. Press 1 to continue: "
+
+$choice = Read-Host
+if ($choice -ne "1") {
+ Write-Output "Closing the example... "
+ exit 1
+}
+
+Invoke-Script -Command "`".\utils\sharedAccess.ps1`""
+
+#ds-snippet-start:eSign43Step5
+try {
+ # Make the API call to check the envelope
+ # Get date in the ISO 8601 format
+ $fromDate = ((Get-Date).AddDays(-10d)).ToString("yyyy-MM-ddThh:mm:ssK")
+
+ $response = New-TemporaryFile
+
+ Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'GET' `
+ -Headers @{
+ 'X-DocuSign-Act-On-Behalf' = $userId;
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ } `
+ -Body @{ "from_date" = ${fromDate} } `
+ -OutFile $response
+
+ if ([string]::IsNullOrEmpty($response))
+ {
+ Write-Output ""
+ Write-Output "Response body is empty because there are no envelopes in the account. Please run example 2 and re-run this example."
+ } else {
+ Write-Output ""
+ Write-Output "Response:"
+ Write-Output ""
+
+ Get-Content $response
+ }
+ #ds-snippet-end:eSign43Step5
+} catch {
+ Write-Output "Unable to retrieve Bulk Status."
+
+ foreach ($header in $_.Exception.Response.Headers) {
+ if ($header -eq "X-DocuSign-TraceToken") { Write-Output "TraceToken : " $_.Exception.Response.Headers[$int] }
+ $int++
+ }
+ Write-Output "Error : "$_.ErrorDetails.Message
+ Write-Output "Command : "$_.InvocationInfo.Line
+}
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $requestDataTemp
+Remove-Item $response
+
+Write-Output ""
+Write-Output "Done."
diff --git a/examples/eSignature/eg044FocusedView.ps1 b/examples/eSignature/eg044FocusedView.ps1
new file mode 100644
index 0000000..fe7f569
--- /dev/null
+++ b/examples/eSignature/eg044FocusedView.ps1
@@ -0,0 +1,145 @@
+$apiUri = "https://demo.docusign.net/restapi"
+$configPath = ".\config\settings.json"
+$tokenPath = ".\config\ds_access_token.txt"
+$accountIdPath = ".\config\API_ACCOUNT_ID"
+
+# Get required variables from .\config\settings.json file
+$variables = Get-Content $configPath -Raw | ConvertFrom-Json
+
+# 1. Obtain your OAuth token
+$accessToken = Get-Content $tokenPath
+
+# Obtain your accountId from demo.docusign.net -- the account id is shown in
+# the drop down on the upper right corner of the screen by your picture or
+# the default picture.
+$accountID = Get-Content $accountIdPath
+
+# Step 2. Create the envelope definition.
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+$doc1Base64 = New-TemporaryFile
+
+$docPath = ".\demo_documents\World_Wide_Corp_lorem.pdf"
+
+# Check the folder structure to switch paths for Quick ACG
+if ((Test-Path $docPath) -eq $false) {
+ $docPath = "..\demo_documents\World_Wide_Corp_lorem.pdf"
+}
+
+# Fetch doc and encode
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path $docPath))) > $doc1Base64
+
+Write-Output "Sending the envelope request to Docusign..."
+Write-Output ""
+
+# Concatenate the different parts of the request
+#ds-snippet-start:eSign44Step2
+@{
+ emailSubject = "Please sign this document set";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $doc1Base64)";
+ name = "Lorem Ipsum";
+ fileExtension = "pdf";
+ documentId = "1";
+ };
+ );
+ recipients = @{
+ signers = @(
+ @{
+ email = $variables.SIGNER_EMAIL;
+ name = $variables.SIGNER_NAME;
+ recipientId = "1";
+ routingOrder = "1";
+ clientUserId = "1000";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "/sn1/";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ );
+ };
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign44Step2
+
+# Step 3. Call Docusign to create the envelope
+#ds-snippet-start:eSign44Step3
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:eSign44Step3
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+Write-Output ""
+
+# pull out the envelopeId
+$envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+Write-Output "EnvelopeId: $envelopeId"
+Write-Output ""
+
+# Step 4. Create a recipient view definition
+# The signer will directly open this link from the browser to sign.
+#
+# The returnUrl is normally your own web app. Docusign will redirect
+# the signer to returnUrl when the signing completes.
+# For this example, we'll use http://httpbin.org/get to show the
+# query parameters passed back from Docusign
+
+#ds-snippet-start:eSign44Step4
+Write-Output "Requesting the url for the embedded signing..."
+Write-Output ""
+
+$json = @{
+ returnUrl = "http://httpbin.org/get"
+ authenticationMethod = "none"
+ email = $variables.SIGNER_EMAIL
+ userName = $variables.SIGNER_NAME
+ clientUserId = 1000
+ frameAncestors = @("http://localhost:8080", "https://apps-d.docusign.com")
+ messageOrigins = @("https://apps-d.docusign.com")
+}
+
+$jsonString = $json | ConvertTo-Json
+#ds-snippet-end:eSign44Step4
+
+# Step 5. Create the recipient view and begin the Docusign signing
+#ds-snippet-start:eSign44Step5
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes/${envelopeId}/views/recipient" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -Body $jsonString `
+ -OutFile $response
+
+Write-Output "Response: $(Get-Content -Raw $response)"
+
+$signingUrl = $(Get-Content $response | ConvertFrom-Json).url
+#ds-snippet-end:eSign44Step5
+
+Start-Process -NoNewWindow -FilePath "powershell" -ArgumentList "-File .\utils\startServerForFocusedView.ps1 -signingURL $signingUrl"
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $doc1Base64
+
+Write-Output ""
+Write-Output "Done."
\ No newline at end of file
diff --git a/examples/eSignature/eg045DeleteRestoreEnvelope.ps1 b/examples/eSignature/eg045DeleteRestoreEnvelope.ps1
new file mode 100644
index 0000000..8b8114d
--- /dev/null
+++ b/examples/eSignature/eg045DeleteRestoreEnvelope.ps1
@@ -0,0 +1,152 @@
+$apiUri = "https://demo.docusign.net/restapi"
+
+# Delete and Undelete an Envelope
+
+# Get required environment variables from .\config\settings.json file
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+
+
+# Obtain your OAuth token
+# Note: Substitute these values with your own
+$accessToken = Get-Content .\config\ds_access_token.txt
+
+# Set up variables for full code example
+# Note: Substitute these values with your own
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+# temp files:
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+
+$recycle_bin_folder_id = "recyclebin"
+
+Write-Output "Select the envelope ID to use for the delete and undelete operations."
+if (Test-Path .\config\ENVELOPE_ID) {
+ $envelopeIdFromFile = Get-Content .\config\ENVELOPE_ID
+
+ $userSavedEnvelope = Read-Host "Use the envelope ID from 'config/ENVELOPE_ID' (${envelopeIdFromFile})? (y/n)"
+ switch ($userSavedEnvelope.ToLower()) {
+ "y" {
+ $envelopeId = $envelopeIdFromFile
+ }
+ default {
+ $envelopeId = Read-Host "Please enter the new envelope ID"
+ }
+ }
+} else {
+ $envelopeId = Read-Host "No envelope ID found. Please enter the envelope ID"
+}
+
+if (-not $envelopeId) {
+ Write-Output "ERROR: No envelope ID was provided"
+ exit 1
+}
+
+Write-Output "Deleting the Envelope with ID: ${envelopeId}"
+Write-Output "Sending PUT request to Docusign..."
+Write-Output "Results:"
+
+#ds-snippet-start:eSign45Step2
+$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
+$headers.add("Authorization", "Bearer $accessToken")
+$headers.add("Content-Type", "application/json")
+#ds-snippet-end:eSign45Step2
+
+# Concatenate the different parts of the request
+#ds-snippet-start:eSign45Step3
+@{
+ envelopeIds = @("$envelopeId")
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign45Step3
+
+# Create and send the folders request
+#ds-snippet-start:eSign45Step4
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/folders/${recycle_bin_folder_id}" `
+ -Method 'PUT' `
+ -Headers $headers `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response `
+#ds-snippet-end:eSign45Step4
+
+Write-Output "The deleted envelope is now in your Docusign Recycle Bin."
+Write-Output "You can check your web app to confirm the deletion."
+
+Read-Host "Press Enter to proceed with undeleting the envelope from the Recycle Bin..."
+$destinationFolderName = Read-Host "Please enter the name of the folder to undelete the envelope to (e.g., 'Sent Items') or press Enter to use the default"
+
+if (-not $destinationFolderName) {
+ $destinationFolderName = "Sent Items"
+ Write-Output "The undeleted item will be moved to the Sent Items folder"
+}
+
+Write-Output "Searching for folder with name: '${destinationFolderName}'..."
+
+#ds-snippet-start:eSign45Step5
+function Get-FolderIdByName {
+ param (
+ [object]$folders,
+ [string]$targetName
+ )
+
+ foreach ($folder in $folders) {
+ # Check this folder
+ if ($folder.name -eq $targetName) {
+ return $folder.folderId
+ }
+
+ # If this folder has subfolders, search inside them
+ if ($folder.folders) {
+ $result = Get-FolderIdByName -folders $folder.folders -targetName $targetName
+ if ($result) {
+ return $result
+ }
+ }
+ }
+
+ return $null
+}
+
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/folders" `
+ -Method 'GET' `
+ -Headers $headers `
+ -OutFile $response
+
+$folders = $(Get-Content $response | ConvertFrom-Json).folders
+$folderId = Get-FolderIdByName -folders $folders -targetName $destinationFolderName
+#ds-snippet-end:eSign45Step5
+
+if (-not $folderId) {
+ Write-Output "ERROR: Could not find a folder with the name '${destinationFolderName}'. Please check the spelling."
+ exit 1
+}
+
+Write-Output "Found folder ID: ${folderId} for folder name: '${destinationFolderName}'"
+
+Write-Output "Undeleting the Envelope from Recycle Bin to the '${destinationFolderName}' folder."
+Write-Output "Sending PUT request to Docusign..."
+Write-Output "Results:"
+
+#ds-snippet-start:eSign45Step6
+@{
+ envelopeIds = @("$envelopeId");
+ fromFolderId = "$recycle_bin_folder_id"
+} | ConvertTo-Json -Depth 32 > $requestData
+
+# Create and send the folders request
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/folders/${folderId}" `
+ -Method 'PUT' `
+ -Headers $headers `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+#ds-snippet-end:eSign45Step6
+
+Write-Output "The envelope has been undeleted and is now in your '${destinationFolderName}' folder."
+
+# cleanup
+Remove-Item $requestData
+Remove-Item $response
+
+Write-Output "Done."
diff --git a/examples/eSignature/eg046MultipleDelivery.ps1 b/examples/eSignature/eg046MultipleDelivery.ps1
new file mode 100644
index 0000000..2c5ba39
--- /dev/null
+++ b/examples/eSignature/eg046MultipleDelivery.ps1
@@ -0,0 +1,163 @@
+#Email and SMS or WhatsApp Delivery
+$apiUri = "https://demo.docusign.net/restapi"
+
+$variables = Get-Content .\config\settings.json -Raw | ConvertFrom-Json
+$accessToken = Get-Content .\config\ds_access_token.txt
+$accountId = Get-Content .\config\API_ACCOUNT_ID
+
+$doc1Base64 = New-TemporaryFile
+$doc2Base64 = New-TemporaryFile
+$doc3Base64 = New-TemporaryFile
+
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\doc_1.html"))) > $doc1Base64
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_Battle_Plan_Trafalgar.docx"))) > $doc2Base64
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents\World_Wide_Corp_lorem.pdf"))) > $doc3Base64
+
+Write-Host "Choose a message delivery type:"
+Write-Host "1 - SMS"
+Write-Host "2 - WhatsApp"
+
+do {
+ $choice = Read-Host "Select 1 or 2"
+} while ($choice -notin @("1", "2"))
+
+if ($choice -eq "1") {
+ $deliveryMethod = "SMS"
+}
+else {
+ $deliveryMethod = "WhatsApp"
+}
+
+$signerCountry = Read-Host "Please enter a country phone number prefix for the Signer"
+$signerNumber = Read-Host "Please enter a Mobile number for the Signer"
+
+$ccCountry = Read-Host "Please enter a country phone number prefix for the Carbon Copied recipient"
+$ccNumber = Read-Host "Please enter a Mobile number for the Carbon Copied recipient"
+
+#ds-snippet-start:eSign46Step2
+$requestData = New-TemporaryFile
+$response = New-TemporaryFile
+
+@{
+ emailSubject = "Please sign this document set";
+ documents = @(
+ @{
+ documentBase64 = "$(Get-Content $doc1Base64)";
+ name = "Order acknowledgement";
+ fileExtension = "html";
+ documentId = "1";
+ };
+ @{
+ documentBase64 = "$(Get-Content $doc2Base64)";
+ name = "Battle Plan";
+ fileExtension = "docx";
+ documentId = "2";
+ };
+ @{
+ documentBase64 = "$(Get-Content $doc3Base64)";
+ name = "Lorem Ipsum";
+ fileExtension = "pdf";
+ documentId = "3";
+ };
+ );
+ recipients = @{
+ carbonCopies = @(
+ @{
+ additionalNotifications = @(
+ @{
+ secondaryDeliveryMethod = $deliveryMethod;
+ phoneNumber = @{
+ countryCode = $ccCountry;
+ number = $ccNumber;
+ };
+ };
+ );
+ name = $variables.CC_NAME;
+ email = $variables.CC_EMAIL;
+ recipientId = "2";
+ routingOrder = "2";
+ deliveryMethod = "Email";
+ };
+ );
+ signers = @(
+ @{
+ additionalNotifications = @(
+ @{
+ secondaryDeliveryMethod = $deliveryMethod;
+ phoneNumber = @{
+ countryCode = $signerCountry;
+ number = $signerNumber;
+ };
+ };
+ );
+ name = $variables.SIGNER_NAME;
+ email = $variables.SIGNER_EMAIL;
+ recipientId = "1";
+ routingOrder = "1";
+ deliveryMethod = "Email";
+ tabs = @{
+ signHereTabs = @(
+ @{
+ anchorString = "**signature_1**";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ @{
+ anchorString = "/sn1/";
+ anchorUnits = "pixels";
+ anchorXOffset = "20";
+ anchorYOffset = "10";
+ };
+ );
+ };
+ };
+ );
+ };
+ status = "sent";
+} | ConvertTo-Json -Depth 32 > $requestData
+#ds-snippet-end:eSign46Step2
+
+Write-Output "Sending the envelope request to Docusign..."
+Write-Output "The envelope has three documents. Processing time will be about 15 seconds."
+Write-Output "Results:"
+Write-Output $requestData
+
+try {
+ #ds-snippet-start:eSign46Step3
+ Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ } `
+ -InFile (Resolve-Path $requestData).Path `
+ -OutFile $response
+
+ Write-Output "Response: $(Get-Content -Raw $response)"
+
+ $envelopeId = $(Get-Content $response | ConvertFrom-Json).envelopeId
+ #ds-snippet-end:eSign46Step3
+ Write-Output "Response: $response"
+
+ $envelopeId = $($response.envelopeId)
+
+ Write-Output "EnvelopeId: $envelopeId"
+ Write-Output $envelopeId > .\config\ENVELOPE_ID
+} catch {
+ Write-Error (
+ "This account does not have sufficient permissions to send envelopes via SMS. " +
+ "To enable multi-channel delivery, please contact DocuSign Support: " +
+ "https://developers.docusign.com/support"
+ )
+ exit 1
+}
+
+Remove-Item $requestData
+Remove-Item $response
+Remove-Item $doc1Base64
+Remove-Item $doc2Base64
+Remove-Item $doc3Base64
+
+Write-Output "Done."
diff --git a/launcher.ps1 b/launcher.ps1
index 43d7284..57cb624 100644
--- a/launcher.ps1
+++ b/launcher.ps1
@@ -1,6 +1,9 @@
+. "utils/invokeScript.ps1"
+
$ErrorActionPreference = "Stop" # force stop on failure
$configFile = ".\config\settings.json"
+$emailAddressFile = ".\config\ESIGN_CLM_USER_EMAIL"
if ((Test-Path $configFile) -eq $False) {
Write-Output "Error: "
@@ -8,21 +11,85 @@ if ((Test-Path $configFile) -eq $False) {
Write-Output "Next, fill in your API credentials, Signer name and email to continue."
}
+# Check that we have an email address stored after running the 2 Admin code example
+# in case the file was created before - delete it
+if (Test-Path $emailAddressFile) {
+ Remove-Item $emailAddressFile
+}
+
# Get required environment variables from .\config\settings.json file
$config = Get-Content $configFile -Raw | ConvertFrom-Json
+function isCFR {
+ $response = New-TemporaryFile
+ $accessToken = Get-Content .\config\ds_access_token.txt
+ $accountId = Get-Content .\config\API_ACCOUNT_ID
+
+ Invoke-RestMethod `
+ -Uri "https://demo.docusign.net/restapi/v2.1/accounts/$accountId/settings" `
+ -Method 'GET' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+ } `
+ -OutFile $response
+ $env:CFR_STATUS = Select-String -Pattern '"require21CFRpt11Compliance":"true"' -Path $response
+}
-# Fill in Quickstart Carbon Copy config values
-if($config.CC_EMAIL -eq "{CC_EMAIL}" ){
- Write-Output "It looks like this is your first time running the launcher from Quickstart. "
- $config.CC_EMAIL = Read-Host "Enter a CC email address to receive copies of envelopes"
- $config.CC_NAME = Read-Host "Enter a name for your CC recipient"
- $config.SIGNER_NOT_CHECKED_EMAIL = "Enter an email address to route to when the checkbox is not checked"
- $config.SIGNER_NOT_CHECKED_NAME = "Enter a name address to route to when the checkbox is not checked"
- Write-Output ""
- write-output $config | ConvertTo-Json | Set-Content $configFile
+function checkEmailAddresses {
+
+ if (-not [system.Text.RegularExpressions.Regex]::IsMatch($config.SIGNER_EMAIL,
+ "^(?("")("".+?(? .\config\WEB_FORM_TEMPLATE_ID
+ Remove-Item $response
+ Write-Output "Done."
+ exit 0
+}
+
+$requestData = New-TemporaryFile
+$requestDataTemp = New-TemporaryFile
+$doc1Base64 = New-TemporaryFile
+
+Write-Output "Sending the template create request to Docusign..."
+
+[Convert]::ToBase64String([System.IO.File]::ReadAllBytes((Resolve-Path ".\demo_documents/World_Wide_Corp_Web_Form.pdf"))) > $doc1Base64
+
+$json = @"
+{
+ "description": "Example template created via the API",
+ "name": "Web Form Example Template",
+ "shared": "false",
+ "documents": [
+ {
+ "documentBase64": "$(Get-Content $doc1Base64)",
+ "documentId": "1",
+ "fileExtension": "pdf",
+ "name": "World_Wide_Web_Form"
+ }
+ ],
+ "emailSubject": "Please sign this document",
+ "recipients": {
+ "signers": [
+ {
+ "recipientId": "1",
+ "roleName": "signer",
+ "routingOrder": "1",
+ "tabs": {
+ "checkboxTabs": [
+ {
+ "documentId": "1",
+ "tabLabel": "Yes",
+ "anchorString": "/SMS/",
+ "anchorUnits": "pixels",
+ "anchorXOffset": "0",
+ "anchorYOffset": "0"
+ }
+ ],
+ "signHereTabs": [
+ {
+ "documentId": "1",
+ "tabLabel": "Signature",
+ "anchorString": "/SignHere/",
+ "anchorUnits": "pixels",
+ "anchorXOffset": "20",
+ "anchorYOffset": "10"
+ }
+ ],
+ "textTabs": [
+ {
+ "documentId": "1",
+ "tabLabel": "FullName",
+ "anchorString": "/FullName/",
+ "anchorUnits": "pixels",
+ "anchorXOffset": "0",
+ "anchorYOffset": "0"
+ },
+ {
+ "documentId": "1",
+ "tabLabel": "PhoneNumber",
+ "anchorString": "/PhoneNumber/",
+ "anchorUnits": "pixels",
+ "anchorXOffset": "0",
+ "anchorYOffset": "0"
+ },
+ {
+ "documentId": "1",
+ "tabLabel": "Company",
+ "anchorString": "/Company/",
+ "anchorUnits": "pixels",
+ "anchorXOffset": "0",
+ "anchorYOffset": "0"
+ },
+ {
+ "documentId": "1",
+ "tabLabel": "JobTitle",
+ "anchorString": "/Title/",
+ "anchorUnits": "pixels",
+ "anchorXOffset": "0",
+ "anchorYOffset": "0"
+ }
+ ],
+ "dateSignedTabs": [
+ {
+ "documentId": "1",
+ "tabLabel": "DateSigned",
+ "anchorString": "/Date/",
+ "anchorUnits": "pixels",
+ "anchorXOffset": "0",
+ "anchorYOffset": "0"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "status": "created"
+}
+"@
+
+Invoke-RestMethod `
+ -Uri "${apiUri}/v2.1/accounts/${accountId}/templates" `
+ -Method 'POST' `
+ -Headers @{
+ 'Authorization' = "Bearer $accessToken";
+ 'Content-Type' = "application/json";
+} `
+ -Body $json `
+ -OutFile $response
+
+Write-Output "Results:"
+Get-Content $response
+
+$templateId = $(Get-Content $response | ConvertFrom-Json).templateId
+
+Write-Output "Template '${templateName}' was created! Template ID ${templateId}."
+Write-Output ${templateId} > .\config\WEB_FORM_TEMPLATE_ID
+
+Remove-Item $requestData
+Remove-Item $requestDataTemp
+Remove-Item $response
+Remove-Item $doc1Base64
+
+Write-Output "Done."
diff --git a/utils/invokeScript.ps1 b/utils/invokeScript.ps1
new file mode 100644
index 0000000..838a894
--- /dev/null
+++ b/utils/invokeScript.ps1
@@ -0,0 +1,28 @@
+function Invoke-Script {
+ param (
+ [string]$Command
+ )
+
+ # Get the path to the PowerShell executable
+ $powershellPath = if ([System.Environment]::OSVersion.Platform -eq "Win32NT") {
+ try {
+ (Get-Command powershell.exe -ErrorAction Stop).Source
+ } catch {
+ "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
+ }
+ } else {
+ try {
+ (Get-Command pwsh -ErrorAction Stop).Source
+ } catch {
+ "/usr/local/bin/pwsh"
+ }
+ }
+
+ $powershellPath = $powershellPath -replace ' ', '` ' # add ` if the path has spaces
+
+ # Execute the script using the appropriate PowerShell executable
+ $fullCommand = "$powershellPath -File $Command"
+
+ # Execute the command
+ Invoke-Expression $fullCommand
+}
diff --git a/utils/sharedAccess.ps1 b/utils/sharedAccess.ps1
new file mode 100644
index 0000000..482a630
--- /dev/null
+++ b/utils/sharedAccess.ps1
@@ -0,0 +1,44 @@
+. "utils/invokeScript.ps1"
+
+$configFile = ".\config\settings.json"
+
+if ((Test-Path $configFile) -eq $False) {
+ Write-Output "Error: "
+ Write-Output "First copy the file '.\config\settings.example.json' to '$configFile'."
+ Write-Output "Next, fill in your API credentials, Signer name and email to continue."
+}
+
+# Get required environment variables from .\config\settings.json file
+$config = Get-Content $configFile -Raw | ConvertFrom-Json
+
+Enum AuthType {
+ CodeGrant = 1;
+ JWT = 2;
+ Exit = 3;
+}
+
+$AuthTypeView = $null;
+do {
+ Write-Output ""
+ Write-Output 'Choose an OAuth Strategy: '
+ Write-Output "$([int][AuthType]::CodeGrant)) Authorization Code Grant"
+ Write-Output "$([int][AuthType]::JWT)) Json Web Token (JWT)"
+ Write-Output "$([int][AuthType]::Exit)) Exit"
+ [int]$AuthTypeView = Read-Host "Choose an OAuth Strategy. Then log in as the new user that you just created."
+} while (-not [AuthType]::IsDefined([AuthType], $AuthTypeView));
+
+if ($AuthTypeView -eq [AuthType]::Exit) {
+ exit 1;
+}
+elseif ($AuthTypeView -eq [AuthType]::CodeGrant) {
+ Invoke-Script -Command "`".\OAuth\code_grant.ps1`" -clientId $($config.INTEGRATION_KEY_AUTH_CODE) -clientSecret $($config.SECRET_KEY) -apiVersion $("eSignature") -targetAccountId $($config.TARGET_ACCOUNT_ID)"
+ if ((Test-Path "./config/ds_access_token.txt") -eq $false) {
+ Write-Error "Failed to retrieve OAuth Access token, check your settings.json and that port 8080 is not in use" -ErrorAction Stop
+ }
+}
+elseif ($AuthTypeView -eq [AuthType]::JWT) {
+ Invoke-Script -Command "`".\OAuth\jwt.ps1`" -clientId $($config.INTEGRATION_KEY_AUTH_CODE) -apiVersion $("eSignature") -targetAccountId $($config.TARGET_ACCOUNT_ID)"
+ if ((Test-Path "./config/ds_access_token.txt") -eq $false) {
+ Write-Error "Failed to retrieve OAuth Access token, check your settings.json and that port 8080 is not in use" -ErrorAction Stop
+ }
+}
diff --git a/utils/startServerForFocusedView.ps1 b/utils/startServerForFocusedView.ps1
new file mode 100644
index 0000000..2a14c14
--- /dev/null
+++ b/utils/startServerForFocusedView.ps1
@@ -0,0 +1,108 @@
+param(
+ [Parameter(Mandatory = $true)]
+ [string]$signingURL
+ )
+
+$port = '8080'
+$ip = 'localhost'
+
+# Get required environment variables from ..\config\settings.json file
+$configFile = ".\config\settings.json"
+$config = Get-Content $configFile -Raw | ConvertFrom-Json
+$integrationKey = $config.INTEGRATION_KEY_AUTH_CODE
+
+$socket = 'http://' + $ip + ':' + $port + '/'
+
+$responseOk = @"
+
+
+The document has been embedded with focused view.
+
+
+
+
+
+ Signing
+
+
+
+
+
+
+Continue
+
+
+
+
+"@
+
+[Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
+
+$listener = New-Object System.Net.HttpListener
+$listener.Prefixes.Add($socket)
+$listener.Start()
+Start-Process $socket
+
+$context = $listener.GetContext()
+$response = $context.Response
+
+$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseOk)
+$response.ContentType = "text/html"
+$response.ContentLength64 = $buffer.Length
+$output = $response.OutputStream
+$output.Write($buffer, 0, $buffer.Length)
+$output.Close()
diff --git a/utils/startServerForWebFormsExample.ps1 b/utils/startServerForWebFormsExample.ps1
new file mode 100644
index 0000000..627ac23
--- /dev/null
+++ b/utils/startServerForWebFormsExample.ps1
@@ -0,0 +1,122 @@
+param(
+ [Parameter(Mandatory = $true)]
+ [string]$integrationKey,
+ [Parameter(Mandatory = $true)]
+ [string]$url,
+ [Parameter(Mandatory = $true)]
+ [string]$instanceToken
+ )
+
+$port = '8080'
+$ip = 'localhost'
+
+$socket = 'http://' + $ip + ':' + $port + '/'
+
+$responseOk = @"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+"@
+
+[Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
+
+$listener = New-Object System.Net.HttpListener
+$listener.Prefixes.Add($socket)
+$listener.Start()
+Start-Process $socket
+
+$context = $listener.GetContext()
+$response = $context.Response
+
+$buffer = [System.Text.Encoding]::UTF8.GetBytes($responseOk)
+$response.ContentType = "text/html"
+$response.ContentLength64 = $buffer.Length
+$output = $response.OutputStream
+$output.Write($buffer, 0, $buffer.Length)
+$output.Close()