diff --git a/pkg/deploy/assets/gateway-production.json b/pkg/deploy/assets/gateway-production.json index b6d70b4ac0f..143151a55b4 100644 --- a/pkg/deploy/assets/gateway-production.json +++ b/pkg/deploy/assets/gateway-production.json @@ -299,7 +299,7 @@ "autoUpgradeMinorVersion": true, "settings": {}, "protectedSettings": { - "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'ACRRESOURCEID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('acrResourceId')),''')\n','AZURECLOUDNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureCloudName')),''')\n','AZURESECPACKQUALYSURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackQualysUrl')),''')\n','AZURESECPACKVSATENANTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackVSATenantId')),''')\n','DATABASEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('databaseAccountName')),''')\n','MDMFRONTENDURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdmFrontendUrl')),''')\n','MDSDENVIRONMENT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdsdEnvironment')),''')\n','FLUENTBITIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fluentbitImage')),''')\n','GATEWAYMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayMdsdConfigVersion')),''')\n','GATEWAYDOMAINS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayDomains')),''')\n','GATEWAYFEATURES=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayFeatures')),''')\n','KEYVAULTDNSSUFFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultDNSSuffix')),''')\n','KEYVAULTPREFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultPrefix')),''')\n','RPIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpImage')),''')\n','RPMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdmAccount')),''')\n','RPMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdAccount')),''')\n','RPMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdNamespace')),''')\n','MDMIMAGE=''/distroless/genevamdm:2.2024.626.1539-d1a6e7-20240715t0935@sha256:372fbc981bbfdf2b9a9d0ffdca2c51ed389b291a3bcff0401e9afb0c01605823''\n','LOCATION=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().location),''')\n','SUBSCRIPTIONID=$(base64 -d \u003c\u003c\u003c''',base64(subscription().subscriptionId),''')\n','RESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().name),''')\n','\n',base64ToString('IyEvYmluL2Jhc2gKIyBJbnRlcm5hbCBGdW5jdGlvbnMgYW5kIENvbnN0YW50cwoKIyBlbXB0eV9zdHIgLSBjb25zdGFudDsgdXNlZCBieSBmdW5jdGlvbnMgZm9yIG9wdGlvbmFsIG5hbWVyZWYgc3RyaW5nIGFyZ3VlbWVudHMKIyBlbXB0eV9zdHI9IiIKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CmRlY2xhcmUgLXIgZW1wdHlfc3RyPSIiCgojIHJvbGVfZ2F0ZXdheSAtIGNvbnN0YW50OyBJcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHRoaXMgc2hvdWxkIGJlIHJlZmVyZW5jZWQgYnkgc2NyaXB0cyBzb3VyY2luZyB0aGlzIGZpbGUKIyByb2xlX2dhdGV3YXk9ImdhdGV3YXkiCmRlY2xhcmUgLXIgcm9sZV9nYXRld2F5PSJnYXRld2F5IgojIHJvbGVfcnAgLSBjb25zdGFudDsgSXMgdXNlZCB0byBkZXRlcm1pbmUgd2hpY2ggVk1TUyBpcyBiZWluZyBib290c3RyYXBwZWQKIyB0aGlzIHNob3VsZCBiZSByZWZlcmVuY2VkIGJ5IHNjcmlwdHMgc291cmNpbmcgdGhpcyBmaWxlCiMgcm9sZV9ycD0icnAiCmRlY2xhcmUgLXIgcm9sZV9ycD0icnAiCiMgcm9sZV9kZXZwcm94eSAtIGNvbnN0YW50OyBJcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHJvbGVfZGV2cHJveHk9ImRldnByb3h5IgpkZWNsYXJlIC1yIHJvbGVfZGV2cHJveHk9ImRldnByb3h5IgoKIyBsb2cgaXMgYSB3cmFwcGVyIGZvciBlY2hvIHRoYXQgaW5jbHVkZXMgdGhlIGZ1bmN0aW9uIG5hbWUKIyBBcmdzCiMgMSkgbXNnIC0gc3RyaW5nCiMgMikgc3RhY2tfbGV2ZWwgLSBpbnQ7IG9wdGlvbmFsLCBkZWZhdWx0cyB0byB0aGUgZnVuY3Rpb24gYXQgdGhlIGJvdHRvbSBvZiB0aGUgY2FsbCBzdGFjawpsb2coKSB7CiAgICBsb2NhbCAtciBtc2c9IiR7MTotImxvZyBtZXNzYWdlIGlzIGVtcHR5In0iCiAgICBsb2NhbCAtciBzdGFja19sZXZlbD0iJHsyOi0xfSIKICAgIGVjaG8gIiR7RlVOQ05BTUVbJHtzdGFja19sZXZlbH1dfTogJHttc2d9Igp9CgojIGFib3J0IGlzIGEgd3JhcHBlciBmb3IgbG9nIHRoYXQgZXhpdHMgd2l0aCBhbiBlcnJvciBjb2RlCmFib3J0KCkgewogICAgbG9jYWwgLXJpIG9yaWdpbl9zdGFja2xldmVsPTIKICAgIGxvZyAiJHsxfSIgIiRvcmlnaW5fc3RhY2tsZXZlbCIKICAgIGxvZyAiRXhpdGluZyIKICAgIGV4aXQgMQp9CgojIHdyaXRlX2ZpbGUKIyBBcmdzCiMgMSkgZmlsZW5hbWUgLSBzdHJpbmcKIyAyKSBmaWxlX2NvbnRlbnRzIC0gc3RyaW5nCiMgMykgY2xvYmJlciAtIGJvb2xlYW47IG9wdGlvbmFsIC0gZGVmYXVsdHMgdG8gZmFsc2UKd3JpdGVfZmlsZSgpIHsKICAgIGxvY2FsIC1uIGZpbGVuYW1lPSIkMSIKICAgIGxvY2FsIC1uIGZpbGVfY29udGVudHM9IiQyIgogICAgbG9jYWwgLXIgY2xvYmJlcj0iJHszOi1mYWxzZX0iCgogICAgaWYgJGNsb2JiZXI7IHRoZW4KICAgICAgICBsb2cgIk92ZXJ3cml0aW5nIGZpbGUgJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+ICIkZmlsZW5hbWUiCiAgICBlbHNlCiAgICAgICAgbG9nICJBcHBlbmRpbmcgdG8gJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+PiAiJGZpbGVuYW1lIgogICAgZmkKfQoKIyByZXRyeSBBZGRpbmcgcmV0cnkgbG9naWMgdG8geXVtIGNvbW1hbmRzIGluIG9yZGVyIHRvIGF2b2lkIHN0YWxsaW5nIG91dCBvbiByZXNvdXJjZSBsb2NrcwojIGFyZ3M6CiMgMSkgY21kX3JldHJ5IC0gbmFtZXJlZiwgYXJyYXk7IENvbW1hbmQgYW5kIGFyZ3VlbWVudChzKSB0byByZXRyeQojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CnJldHJ5KCkgewogICAgbG9jYWwgLW4gY21kX3JldHJ5PSIkMSIKICAgIGxvY2FsIC1uIHdhaXRfdGltZT0iJDIiCiAgICBsb2NhbCAtcmkgcmV0cmllcz0iJHszOi01fSIKCiAgICAKICAgIGZvciBhdHRlbXB0IGluICQoc2VxIDEgJHJldHJpZXMpOyBkbwogICAgICAgIGxvZyAiYXR0ZW1wdCAjJHthdHRlbXB0fSAtICR7RlVOQ05BTUVbMl19IgogICAgICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgICAgICR7Y21kX3JldHJ5W0BdfSAmCgogICAgICAgIHdhaXQgLWYgJCEgJiYgcmV0dXJuIDAKICAgICAgICBzbGVlcCAiJHdhaXRfdGltZSIKICAgIGRvbmUKCiAgICBhYm9ydCAiJHtjbWRfcmV0cnlbKl19IGZhaWxlZCBhZnRlciAjJHJldHJpZXMgYXR0ZW1wdHMiCn0KCiMgdmVyaWZ5X3JvbGUKIyBhcmdzOgojIDEpIHRlc3Rfcm9sZSAtIG5hbWVyZWY7IHJvbGUgYmVpbmcgdmVyaWZpZWQKdmVyaWZ5X3JvbGUoKSB7CiAgICBsb2NhbCAtbiB0ZXN0X3JvbGU9IiQxIgoKICAgIGFsbG93ZWRfcm9sZXNfZ2xvYj0iKCRyb2xlX3JwfCRyb2xlX2dhdGV3YXl8JHJvbGVfZGV2cHJveHkpIgogICAgaWYgW1sgIiR0ZXN0X3JvbGUiID1+ICRhbGxvd2VkX3JvbGVzX2dsb2IgXV07IHRoZW4KICAgICAgICBsb2cgIlZlcmlmaWVkIHJvbGUgXCIkdGVzdF9yb2xlXCIiCiAgICBlbHNlCiAgICAgICAgYWJvcnQgImZhaWxlZCB0byB2ZXJpZnkgcm9sZSwgcm9sZSBcIiR7dGVzdF9yb2xlfVwiIG5vdCBpbiBcIiR7YWxsb3dlZF9yb2xlc19nbG9ifVwiIgogICAgZmkKfQoKIyBnZXRfa2V5dmF1bHRfc3VmZml4CiMgYXJnczoKIyAxKSBybCAtIG5hbWVyZWYsIHN0cmluZzsgcm9sZSB0byBnZXQgc2hvcnQgcm9sZSBmb3IKIyAyKSBrdl9zdWZmaXggLSBuYW1lcmVmLCBzdHJpbmc7IHNob3J0IHJvbGUgd2lsbCBiZSBhc3NpZ25lZCB0byB0aGlzIG5hbWVyZWYKIyAzKSBzZWNfcHJlZml4IC0gbmFtZXJlZiwgc3RyaW5nOyBrZXl2YXVsdCBjZXJ0aWZpY2F0ZSBwcmVmaXggd2lsbCBiZSBhc3NpZ25lZCB0byB0aGlzIG5hbWVyZWYKZ2V0X2tleXZhdWx0X3N1ZmZpeCgpIHsKICAgIGxvY2FsIC1uIHJsPSIkMSIKICAgIGxvY2FsIC1uIGt2X3N1ZmZpeD0iJDIiCiAgICBsb2NhbCAtbiBzZWNfcHJlZml4PSIkMyIKCiAgICBsb2NhbCAtciBrZXl2YXVsdF9zdWZmaXhfcnA9InN2YyIKICAgIGxvY2FsIC1yIGtleXZhdWx0X3ByZWZpeF9nYXRld2F5PSJnd3kiCgogICAgY2FzZSAiJHJsIiBpbgogICAgICAgICIkcm9sZV9nYXRld2F5IikKICAgICAgICAgICAga3Zfc3VmZml4PSIka2V5dmF1bHRfcHJlZml4X2dhdGV3YXkiCiAgICAgICAgICAgIHNlY19wcmVmaXg9IiRrZXl2YXVsdF9wcmVmaXhfZ2F0ZXdheSIKICAgICAgICAgICAgOzsKICAgICAgICAiJHJvbGVfcnAiKQogICAgICAgICAgICBrdl9zdWZmaXg9IiRrZXl2YXVsdF9zdWZmaXhfcnAiCiAgICAgICAgICAgIHNlY19wcmVmaXg9IiRyb2xlX3JwIgogICAgICAgICAgICA7OwogICAgICAgICopCiAgICAgICAgICAgIGFib3J0ICJ1bmtvd24gcm9sZSAkcmwiCiAgICAgICAgICAgIDs7CiAgICBlc2FjCn0KCiMgcmVib290X3ZtIHJlc3RvcmVzIGNhbGxzIHNodXRkb3duIC1yIGluIGEgc3Vic2hlbGwKIyBSZWJvb3RzIHNob3VsZCBzY2hlZHVsZWQgYWZ0ZXIgYWxsIFZNIGV4dGVuc2lvbnMgaGF2ZSBoYWQgdGltZSB0byBjb21wbGV0ZQojIFJlZmVyZW5jZTogaHR0cHM6Ly9sZWFybi5taWNyb3NvZnQuY29tL2VuLXVzL2F6dXJlL3ZpcnR1YWwtbWFjaGluZXMvZXh0ZW5zaW9ucy9jdXN0b20tc2NyaXB0LWxpbnV4I3RpcHMKcmVib290X3ZtKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICAoc2h1dGRvd24gLXIgbm93ICYpCn0KIyEvYmluL2Jhc2gKIyBSZXBvc2l0b3J5IGFuZCBwYWNrYWdlIG1hbmFnZW1lbnQgcmVsYXRlZCBmdW5jdGlvbnMKCmNvbmZpZ3VyZV9yZXBvX21hcmluZXJfZXh0ZW5kZWQoKSB7CiAgICBsb2NhbCAtciBleHRlbmRlZF9yZXBvX2NvbmZpZz0iaHR0cHM6Ly9wYWNrYWdlcy5taWNyb3NvZnQuY29tL2NibC1tYXJpbmVyLzIuMC9wcm9kL2V4dGVuZGVkL3g4Nl82NC9jb25maWcucmVwbyIKICAgIGN1cmwgLXNTTCAiJGV4dGVuZGVkX3JlcG9fY29uZmlnIiAtbyAvZXRjL3l1bS5yZXBvcy5kL21hcmluZXItZXh0ZW5kZWQucmVwbwoKICAgIGxvY2FsIC1yIHJlcG9fbmFtZT0iY2JsLW1hcmluZXIyLjBwcm9kZXh0ZW5kZWR4ODZfNjQiCgogICAgbG9jYWwgLXJhIGNtZD0oCiAgICAgICAgZG5mCiAgICAgICAgdXBkYXRlCiAgICAgICAgLXkKICAgICAgICAtLWVuYWJsZXJlcG89IiRyZXBvX25hbWUiCiAgICApCgogICAgbG9nICJFbmFibGluZyByZXBvICRyZXBvX25hbWUiCiAgICByZXRyeSBjbWQgIiQxIiAiJHsyOi19Igp9CgojIGNvbmZpZ3VyZV9ycG1fcmVwb3MKIyBOZXcgcmVwb3NpdG9yaWVzIHNob3VsZCBiZSBhZGRlZCBpbiB0aGVpciBvd24gZnVuY3Rpb25zLCBhbmQgY2FsbGVkIGhlcmUKIyBhcmdzOgojIDEpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDIpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1vdW50IG9mIHRpbWVzIHRvIHJldHJ5IGNvbW1hbmQsIGRlZmF1bHRzIHRvIDUKY29uZmlndXJlX3JwbV9yZXBvcygpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgY29uZmlndXJlX3JlcG9fbWFyaW5lcl9leHRlbmRlZCAiJDEiICIkezI6LTF9Igp9CgojIGRuZl9pbnN0YWxsX3BrZ3MKIyBhcmdzOgojIDEpIHBrZ3MgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IFBhY2thZ2VzIHRvIGJlIGluc3RhbGxlZAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1vdW50IG9mIHRpbWVzIHRvIHJldHJ5IGNvbW1hbmQsIGRlZmF1bHRzIHRvIDUKZG5mX2luc3RhbGxfcGtncygpIHsKICAgIGxvY2FsIC1uIHBrZ3M9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgIGRuZgogICAgICAgIC15CiAgICAgICAgaW5zdGFsbAogICAgKQogICAgCiAgICAjIFJlZmVyZW5jZTogaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIyMDYKICAgICMgYXBwZW5kIHBrZ3MgYXJyYXkgdG8gY21kCiAgICBtYXBmaWxlIC1PICQoKCAkeyNjbWRbQF19ICsgMSApKSAtZCAnICcgY21kIDw8PCAiJHtwa2dzW0BdfSIKICAgIGxvY2FsIC1yIGNtZAoKICAgIGxvZyAiQXR0ZW1wdGluZyB0byBpbnN0YWxsIHBhY2thZ2VzOiAke3BrZ3NbKl19IgogICAgcmV0cnkgY21kICIkMiIgIiR7MzotfSIKfQoKCiMgZG5mX3VwZGF0ZV9wa2dzCiMgYXJnczoKIyAxKSBleGNsdWRlcyAtIG5hbWVyZWYsIHN0cmluZyBhcnJheSwgb3B0aW9uYWw7IFBhY2thZ2VzIHRvIGV4Y2x1ZGUgZnJvbSB1cGRhdGluZwojICAgICAgIEVhY2ggaW5kZXggbXVzdCBiZSBwcmVmaXhlZCB3aXRoIC14IAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CmRuZl91cGRhdGVfcGtncygpIHsKICAgIGxvY2FsIC1uIGV4Y2x1ZGVzPSIkezE6LWVtcHR5X3N0cn0iCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGxvY2FsIC1hIGNtZD0oCiAgICAgICAgZG5mCiAgICAgICAgLXkKICAgICAgICAjIFJlcGxhY2VkIHdpdGggZXhjbHVkZXMKICAgICAgICAiIgogICAgICAgIHVwZGF0ZQogICAgICAgIC0tYWxsb3dlcmFzaW5nCiAgICApCgogICAgaWYgWyAtbiAiJHtleGNsdWRlc30iIF07IHRoZW4KICAgICAgICAjIFJlZmVyZW5jZSBodHRwczovL3d3dy5zaGVsbGNoZWNrLm5ldC93aWtpL1NDMjIwNgogICAgICAgIG1hcGZpbGUgLU8gMiBjbWQgPDw8ICIke2V4Y2x1ZGVzW0BdfSIKICAgIGVsc2UKICAgICAgICAjIFJlbW92ZSBlbXB0eSBzdHJpbmcgaWYgd2UgYXJlbid0IHJlcGxhY2luZyB0aGVtLCBwcm9iYWJseSBkb2Vzbid0IG1hdHRlciwgYnV0IHdoeSBub3QgYmUgc2FmZQogICAgICAgIHVuc2V0ICJjbWRbMl0iCiAgICBmaQogICAgbG9jYWwgLXIgY21kCgogICAgbG9nICJVcGRhdGluZyBhbGwgcGFja2FnZXMgZXhjbHVkaW5nIFwiJHtleGNsdWRlc1sqXTotfVwiIgogICAgcmV0cnkgY21kICIkMiIgIiR7MzotfSIKfQoKIyBycG1faW1wb3J0X2tleXMKIyBhcmdzOgojIDEpIGtleXMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IHJwbSBrZXlzIHRvIGJlIGltcG9ydGVkCiMgMikgd2FpdF90aW1lIC0gbmFtZXJlZiwgaW50ZWdlcjsgVGltZSB0byB3YWl0IGJlZm9yZSByZXRyeWluZyBjb21tYW5kCnJwbV9pbXBvcnRfa2V5cygpIHsKICAgIGxvY2FsIC1uIGtleXM9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBrZXkgaW4gJHtrZXlzW0BdfTsgZG8KICAgICAgICBpZiBbICR7I2tleXNbQF19IC1lcSAwIF07IHRoZW4KICAgICAgICAgICAgYnJlYWsKICAgICAgICBmaQoKICAgICAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgICAgICBycG0KICAgICAgICAgICAgLS1pbXBvcnQKICAgICAgICAgICAgLXYKICAgICAgICAgICAgIiRrZXkiCiAgICAgICAgKQoKICAgICAgICBsb2cgIkltcG9ydGluZyBycG0gcmVwb3NpdG9yeSBrZXkgJGtleSIKICAgICAgICByZXRyeSBjbWQgIiQyIiAiJHszOi19IiAmJiB1bnNldCBrZXkKICAgIGRvbmUKfQoKIyB1dGlsLWNvbW1vbi5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQojIS9iaW4vYmFzaAojIEFSTyBzZXJ2aWNlIHNldHVwIGZ1bmN0aW9ucwoKIyBlbmFibGVfc2VydmljZXMgZW5hYmxlcyB0aGUgc3lzdGVtZCBzZXJ2aWNlcyB0aGF0IGFyZSBwYXNzZWQgaW4KIyBhcmdzOgojIDEpIHNlcnZpY2VzIC0gYXJyYXk7IHNlcnZpY2VzIHRvIGJlIGVuYWJsZWQKZW5hYmxlX3NlcnZpY2VzKCkgewogICAgbG9jYWwgLW4gc3Zjcz0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHN5c3RlbWN0bCBkYWVtb24tcmVsb2FkCgogICAgbG9nICJlbmFibGluZyBzZXJ2aWNlcyAke3N2Y3NbKl19IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3Igc3ZjIGluICR7c3Zjc1tAXX07IGRvCiAgICAgICAgbG9nICJFbmFibGluZyBhbmQgc3RhcnRpbmcgJHN2YyBub3ciCiAgICAgICAgc3lzdGVtY3RsIGVuYWJsZSBcCiAgICAgICAgICAgICAgICAgIC0tbm93IFwKICAgICAgICAgICAgICAgICAgIiRzdmMiCiAgICBkb25lCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBjb250YWluZXIgaW1hZ2UKIyAyKSByb2xlIC0gbmFtZXJlZiwgc3RyaW5nOyBWTVNTIHJvbGUKIyAzKSBjb25mX2ZpbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGFybyBnYXRld2F5IGVudmlyb25tZW50IGZpbGUKY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiByb2xlPSIkMiIKICAgIGxvY2FsIC1uIGNvbmZfZmlsZT0iJDMiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tZ2F0ZXdheSBzZXJ2aWNlIgoKICAgIGxvY2FsIC1yIGFyb19nYXRld2F5X2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1nYXRld2F5JwoKICAgIHdyaXRlX2ZpbGUgYXJvX2dhdGV3YXlfY29uZl9maWxlbmFtZSBjb25mX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX2dhdGV3YXlfc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9hcm8tZ2F0ZXdheS5zZXJ2aWNlJwoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX2dhdGV3YXlfc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0ke2Fyb19nYXRld2F5X2NvbmZfZmlsZW5hbWV9CkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLWUgQUNSX1JFU09VUkNFX0lEIFwKICAtZSBEQVRBQkFTRV9BQ0NPVU5UX05BTUUgXAogIC1lIEdBVEVXQVlfRE9NQUlOUyBcCiAgLWUgR0FURVdBWV9GRUFUVVJFUyBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1tIDJnIFwKICAtcCA4MDo4MDgwIFwKICAtcCA4MDgxOjgwODEgXAogIC1wIDQ0Mzo4NDQzIFwKICAtdiAvcnVuL3N5c3RlbWQvam91cm5hbDovcnVuL3N5c3RlbWQvam91cm5hbCBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJGltYWdlIFwKICAke3JvbGUsLH0KRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgLXQgMzYwMCAlTgpUaW1lb3V0U3RvcFNlYz0zNjAwClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAiCgogICAgd3JpdGVfZmlsZSBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19nYXRld2F5X3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX3JwCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCiMgMikgcm9sZSAtIG5hbWVyZWYsIHN0cmluZzsgVk1TUyByb2xlCiMgMykgY29uZl9maWxlIC0gbmFtZXJlZiwgc3RyaW5nOyBhcm8gcnAgZW52aXJvbm1lbnQgZmlsZQpjb25maWd1cmVfc2VydmljZV9hcm9fcnAoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiByb2xlPSIkMiIKICAgIGxvY2FsIC1uIGNvbmZfZmlsZT0iJDMiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tcnAgc2VydmljZSIKCiAgICBsb2NhbCAtciBhcm9fcnBfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLXJwJwoKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX2NvbmZfZmlsZW5hbWUgY29uZl9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19ycF9zZXJ2aWNlX2ZpbGVuYW1lPScvZXRjL3N5c3RlbWQvc3lzdGVtL2Fyby1ycC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcnBfc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0ke2Fyb19ycF9jb25mX2ZpbGVuYW1lfQpFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC1lIEFDUl9SRVNPVVJDRV9JRCBcCiAgLWUgQURNSU5fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FIFwKICAtZSBBUk1fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FIFwKICAtZSBBWlVSRV9BUk1fQ0xJRU5UX0lEIFwKICAtZSBBWlVSRV9GUF9DTElFTlRfSUQgXAogIC1lIENMVVNURVJfTURNX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURNX05BTUVTUEFDRSBcCiAgLWUgQ0xVU1RFUl9NRFNEX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTiBcCiAgLWUgQ0xVU1RFUl9NRFNEX05BTUVTUEFDRSBcCiAgLWUgREFUQUJBU0VfQUNDT1VOVF9OQU1FIFwKICAtZSBET01BSU5fTkFNRSBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX1JFU09VUkNFR1JPVVAgXAogIC1lIEtFWVZBVUxUX1BSRUZJWCBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1lIE1EU0RfRU5WSVJPTk1FTlQgXAogIC1lIFJQX0ZFQVRVUkVTIFwKICAtZSBBUk9fSU5TVEFMTF9WSUFfSElWRSBcCiAgLWUgQVJPX0hJVkVfREVGQVVMVF9JTlNUQUxMRVJfUFVMTFNQRUMgXAogIC1lIEFST19BRE9QVF9CWV9ISVZFIFwKICAtZSBPSURDX0FGRF9FTkRQT0lOVCBcCiAgLWUgT0lEQ19TVE9SQUdFX0FDQ09VTlRfTkFNRSBcCiAgLWUgTVNJX1JQX0VORFBPSU5UIFwKICAtbSAyZyBcCiAgLXAgNDQzOjg0NDMgXAogIC12IC9ldGMvYXJvLXJwOi9ldGMvYXJvLXJwIFwKICAtdiAvcnVuL3N5c3RlbWQvam91cm5hbDovcnVuL3N5c3RlbWQvam91cm5hbCBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJGltYWdlIFwKICAke3JvbGUsLH0KRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgLXQgMzYwMCAlTgpUaW1lb3V0U3RvcFNlYz0zNjAwClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX3NlcnZpY2VfZmlsZW5hbWUgYXJvX3JwX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX21vbml0b3IKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBSUCBjb250YWluZXIgaW1hZ2UKY29uZmlndXJlX3NlcnZpY2VfYXJvX21vbml0b3IoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tbW9uaXRvciBzZXJ2aWNlIgoKICAgICMgRE9NQUlOX05BTUUsIENMVVNURVJfTURTRF9BQ0NPVU5ULCBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04sIEdBVEVXQVlfRE9NQUlOUywgR0FURVdBWV9SRVNPVVJDRUdST1VQLCBNRFNEX0VOVklST05NRU5UIENMVVNURVJfTURTRF9OQU1FU1BBQ0UKICAgICMgYXJlIG5vdCB1c2VkLCBidXQgY2FuJ3QgZWFzaWx5IGJlIHJlZmFjdG9yZWQgb3V0LiBTaG91bGQgYmUgcmV2aXNpdGVkIGluIHRoZSBmdXR1cmUuCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLW1vbml0b3InCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlPSJBWlVSRV9GUF9DTElFTlRfSUQ9JyRGUENMSUVOVElEJwpET01BSU5fTkFNRT0nJExPQ0FUSU9OLiRDTFVTVEVSUEFSRU5URE9NQUlOTkFNRScKQ0xVU1RFUl9NRFNEX0FDQ09VTlQ9JyRDTFVTVEVSTURTREFDQ09VTlQnCkNMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTj0nJENMVVNURVJNRFNEQ09ORklHVkVSU0lPTicKR0FURVdBWV9ET01BSU5TPSckR0FURVdBWURPTUFJTlMnCkdBVEVXQVlfUkVTT1VSQ0VHUk9VUD0nJEdBVEVXQVlSRVNPVVJDRUdST1VQTkFNRScKTURTRF9FTlZJUk9OTUVOVD0nJE1EU0RFTlZJUk9OTUVOVCcKQ0xVU1RFUl9NRFNEX05BTUVTUEFDRT0nJENMVVNURVJNRFNETkFNRVNQQUNFJwpDTFVTVEVSX01ETV9BQ0NPVU5UPSckQ0xVU1RFUk1ETUFDQ09VTlQnCkNMVVNURVJfTURNX05BTUVTUEFDRT1CQk0KREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPUJCTQpSUElNQUdFPSckaW1hZ2UnIgoKICAgIHdyaXRlX2ZpbGUgYXJvX21vbml0b3Jfc2VydmljZV9jb25mX2ZpbGVuYW1lIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLW1vbml0b3Iuc2VydmljZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21vbml0b3Jfc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9hcm8tbW9uaXRvcgpFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC1lIEFaVVJFX0ZQX0NMSUVOVF9JRCBcCiAgLWUgRE9NQUlOX05BTUUgXAogIC1lIENMVVNURVJfTURTRF9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04gXAogIC1lIEdBVEVXQVlfRE9NQUlOUyBcCiAgLWUgR0FURVdBWV9SRVNPVVJDRUdST1VQIFwKICAtZSBNRFNEX0VOVklST05NRU5UIFwKICAtZSBDTFVTVEVSX01EU0RfTkFNRVNQQUNFIFwKICAtZSBDTFVTVEVSX01ETV9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01ETV9OQU1FU1BBQ0UgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgS0VZVkFVTFRfUFJFRklYIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLW0gMi41ZyBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgbW9uaXRvcgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZW5hbWUgYXJvX21vbml0b3Jfc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9hcm9fcG9ydGFsCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCmNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19wb3J0YWwoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8gcG9ydGFsIHNlcnZpY2UiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZT0iQVpVUkVfUE9SVEFMX0FDQ0VTU19HUk9VUF9JRFM9JyRQT1JUQUxBQ0NFU1NHUk9VUElEUycKQVpVUkVfUE9SVEFMX0NMSUVOVF9JRD0nJFBPUlRBTENMSUVOVElEJwpBWlVSRV9QT1JUQUxfRUxFVkFURURfR1JPVVBfSURTPSckUE9SVEFMRUxFVkFURURHUk9VUElEUycKREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPVBvcnRhbApQT1JUQUxfSE9TVE5BTUU9JyRMT0NBVElPTi5hZG1pbi4kUlBQQVJFTlRET01BSU5OQU1FJwpSUElNQUdFPSckaW1hZ2UnIgoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLXBvcnRhbC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKU3RhcnRMaW1pdEludGVydmFsPTAKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC1lIEFaVVJFX1BPUlRBTF9BQ0NFU1NfR1JPVVBfSURTIFwKICAtZSBBWlVSRV9QT1JUQUxfQ0xJRU5UX0lEIFwKICAtZSBBWlVSRV9QT1JUQUxfRUxFVkFURURfR1JPVVBfSURTIFwKICAtZSBEQVRBQkFTRV9BQ0NPVU5UX05BTUUgXAogIC1lIEtFWVZBVUxUX1BSRUZJWCBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1lIFBPUlRBTF9IT1NUTkFNRSBcCiAgLW0gMmcgXAogIC1wIDQ0NDo4NDQ0IFwKICAtcCAyMjIyOjIyMjIgXAogIC12IC9ydW4vc3lzdGVtZC9qb3VybmFsOi9ydW4vc3lzdGVtZC9qb3VybmFsIFwKICAtdiAvdmFyL2V0dzovdmFyL2V0dzp6IFwKICAkaW1hZ2UgXAogIHBvcnRhbApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIGFyb19wb3J0YWxfc2VydmljZV9maWxlbmFtZSBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfbWRzZAojIGFyZ3M6CiMgMSkgbW9uaXRvcmluZ19yb2xlIC0gbmFtZXJlZiwgc3RyaW5nOyBjYW4gYmUgImdhdGV3YXkiIG9yICJycCIKIyAyKSBtb25pdG9yX2NvbmZpZ192ZXJzaW9uIC0gbmFtZXJlZiwgc3RyaW5nOyBtZHNkIGNvbmZpZyB2ZXJzaW9uCmNvbmZpZ3VyZV9zZXJ2aWNlX21kc2QoKSB7CiAgICBsb2NhbCAtbiByb2xlPSIkMSIKICAgIGxvY2FsIC1uIG1vbml0b3JfY29uZmlnX3ZlcnNpb249IiQyIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiY29uZmlndXJpbmcgbWRzZCBzZXJ2aWNlIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICBsb2NhbCAtciBtZHNkX3NlcnZpY2VfZGlyPSIvZXRjL3N5c3RlbWQvc3lzdGVtL21kc2Quc2VydmljZS5kIgogICAgbWtkaXIgLXAgIiRtZHNkX3NlcnZpY2VfZGlyIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRzZF9vdmVycmlkZV9jb25mX2ZpbGVuYW1lPSIkbWRzZF9zZXJ2aWNlX2Rpci9vdmVycmlkZS5jb25mIgogICAgbG9jYWwgLXIgbWRzZF9jZXJ0aWZpY2F0ZV9zYW49IiQob3BlbnNzbCB4NTA5IC1pbiAvdmFyL2xpYi93YWFnZW50L01pY3Jvc29mdC5BenVyZS5LZXlWYXVsdC5TdG9yZS9tZHNkLnBlbSAtbm9vdXQgLXN1YmplY3QgfCBzZWQgLWUgJ3MvLipDTiA9IC8vJykiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kc2Rfb3ZlcnJpZGVfY29uZl9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgbWRzZF9vdmVycmlkZV9jb25mX2ZpbGVuYW1lIG1kc2Rfb3ZlcnJpZGVfY29uZl9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGRlZmF1bHRfbWRzZF9maWxlbmFtZT0iL2V0Yy9kZWZhdWx0L21kc2QiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGRlZmF1bHRfbWRzZF9maWxlPSJNRFNEX1JPTEVfUFJFRklYPS92YXIvcnVuL21kc2QvZGVmYXVsdApNRFNEX09QVElPTlM9XCItQSAtZCAtciBcJE1EU0RfUk9MRV9QUkVGSVhcIgoKZXhwb3J0IE1PTklUT1JJTkdfR0NTX0VOVklST05NRU5UPSckTURTREVOVklST05NRU5UJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfQUNDT1VOVD0nJFJQTURTREFDQ09VTlQnCmV4cG9ydCBNT05JVE9SSU5HX0dDU19SRUdJT049JyRMT0NBVElPTicKZXhwb3J0IE1PTklUT1JJTkdfR0NTX0FVVEhfSURfVFlQRT1BdXRoS2V5VmF1bHQKZXhwb3J0IE1PTklUT1JJTkdfR0NTX0FVVEhfSUQ9JyRtZHNkX2NlcnRpZmljYXRlX3NhbicKZXhwb3J0IE1PTklUT1JJTkdfR0NTX05BTUVTUEFDRT0nJFJQTURTRE5BTUVTUEFDRScKZXhwb3J0IE1PTklUT1JJTkdfQ09ORklHX1ZFUlNJT049JyRtb25pdG9yX2NvbmZpZ192ZXJzaW9uJwpleHBvcnQgTU9OSVRPUklOR19VU0VfR0VORVZBX0NPTkZJR19TRVJWSUNFPXRydWUKCmV4cG9ydCBNT05JVE9SSU5HX1RFTkFOVD0nJExPQ0FUSU9OJwpleHBvcnQgTU9OSVRPUklOR19ST0xFPSckcm9sZScKZXhwb3J0IE1PTklUT1JJTkdfUk9MRV9JTlNUQU5DRT1cIiQoaG9zdG5hbWUpXCIKCmV4cG9ydCBNRFNEX01TR1BBQ0tfU09SVF9DT0xVTU5TPVwiMVwiIgoKICAgIHdyaXRlX2ZpbGUgZGVmYXVsdF9tZHNkX2ZpbGVuYW1lIGRlZmF1bHRfbWRzZF9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9mbHVlbnRiaXQKIyBhcmdzOgojIDEpIGNvbmZfZmlsZSAtIHN0cmluZzsgZmx1ZW5iaXQgY29uZmlndXJhdGlvbiBmaWxlCiMgMikgaW1hZ2UgLSBzdHJpbmc7IGZsdWVudGJpdCBjb250YWluZXIgaW1hZ2UgdG8gcnVuCmNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdCgpIHsKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIGZsdWVudGJpdCBzZXJ2aWNlIgoKICAgIG1rZGlyIC1wIC9ldGMvZmx1ZW50Yml0LwogICAgbWtkaXIgLXAgL3Zhci9saWIvZmx1ZW50CgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBjb25mX2ZpbGVuYW1lPScvZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZicKICAgIHdyaXRlX2ZpbGUgY29uZl9maWxlbmFtZSBjb25mX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX2ZpbGVuYW1lPScvZXRjL3N5c2NvbmZpZy9mbHVlbnRiaXQnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHN5c2NvbmZpZ19maWxlPSJGTFVFTlRCSVRJTUFHRT0kaW1hZ2UiCgogICAgd3JpdGVfZmlsZSBzeXNjb25maWdfZmlsZW5hbWUgc3lzY29uZmlnX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9mbHVlbnRiaXQuc2VydmljZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldApTdGFydExpbWl0SW50ZXJ2YWxTZWM9MAoKW1NlcnZpY2VdClJlc3RhcnRTZWM9MXMKRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2ZsdWVudGJpdApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1zZWN1cml0eS1vcHQgbGFiZWw9ZGlzYWJsZSBcCiAgLS1lbnRyeXBvaW50IC9vcHQvdGQtYWdlbnQtYml0L2Jpbi90ZC1hZ2VudC1iaXQgXAogIC0tbmV0PWhvc3QgXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtdiAvZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZjovZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZiBcCiAgLXYgL3Zhci9saWIvZmx1ZW50Oi92YXIvbGliL2ZsdWVudDp6IFwKICAtdiAvdmFyL2xvZy9qb3VybmFsOi92YXIvbG9nL2pvdXJuYWw6cm8gXAogIC12IC9ldGMvbWFjaGluZS1pZDovZXRjL21hY2hpbmUtaWQ6cm8gXAogICRpbWFnZSBcCiAgLWMgL2V0Yy9mbHVlbnRiaXQvZmx1ZW50Yml0LmNvbmYKCkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9NQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgc2VydmljZV9maWxlbmFtZSBzZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV90aW1lcnNfbWRtX21kc2QKIyBhcmdzOgojIDEpIHJvbGUgLSBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgpjb25maWd1cmVfdGltZXJzX21kbV9tZHNkKCkgewogICAgbG9jYWwgLW4gcm9sZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICBsb2NhbCBrZXl2YXVsdF9zdWZmaXggc2VjcmV0X3ByZWZpeAogICAgZ2V0X2tleXZhdWx0X3N1ZmZpeCByb2xlIGtleXZhdWx0X3N1ZmZpeCBzZWNyZXRfcHJlZml4CgogICAgZm9yIHZhciBpbiAibWRzZCIgIm1kbSI7IGRvCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9kb3dubG9hZC0kdmFyLWNyZWRlbnRpYWxzLnNlcnZpY2UiCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlPSJbVW5pdF0KRGVzY3JpcHRpb249UGVyaW9kaWMgJHZhciBjcmVkZW50aWFscyByZWZyZXNoCgpbU2VydmljZV0KVHlwZT1vbmVzaG90CkV4ZWNTdGFydD0vdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaCAkdmFyIgoKICAgICAgICB3cml0ZV9maWxlIGRvd25sb2FkX2NyZWRzX3NlcnZpY2VfZmlsZW5hbWUgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlIHRydWUKCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfdGltZXJfZmlsZW5hbWU9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vZG93bmxvYWQtJHZhci1jcmVkZW50aWFscy50aW1lciIKICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlPSJbVW5pdF0KRGVzY3JpcHRpb249UGVyaW9kaWMgJHZhciBjcmVkZW50aWFscyByZWZyZXNoCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltUaW1lcl0KT25Cb290U2VjPTBtaW4KT25DYWxlbmRhcj0wLzEyOjAwOjAwCkFjY3VyYWN5U2VjPTVzCgpbSW5zdGFsbF0KV2FudGVkQnk9dGltZXJzLnRhcmdldCIKCiAgICAgICAgd3JpdGVfZmlsZSBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlbmFtZSBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlIHRydWUKICAgIGRvbmUKCiAgICBsb2NhbCAtciBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWU9Ii91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZT0iIyEvYmluL2Jhc2gKc2V0IC1ldQoKQ09NUE9ORU5UPVwkMQplY2hvIFwiRG93bmxvYWQgXCRDT01QT05FTlQgY3JlZGVudGlhbHNcIgoKVEVNUF9ESVI9XCJcJChta3RlbXAgLWQpXCIKZXhwb3J0IEFaVVJFX0NPTkZJR19ESVI9XCJcJChta3RlbXAgLWQpXCIKCmVjaG8gXCJMb2dnaW5nIGludG8gQXp1cmUuLi5cIgpSRVRSSUVTPTMKd2hpbGUgW1sgXCRSRVRSSUVTIC1ndCAwIF1dOyBkbwogICAgaWYgYXogbG9naW4gLWkgLS1hbGxvdy1uby1zdWJzY3JpcHRpb25zCiAgICB0aGVuCiAgICAgICAgZWNobyBcImF6IGxvZ2luIHN1Y2Nlc3NmdWxcIgogICAgICAgIGJyZWFrCiAgICBlbHNlCiAgICAgICAgZWNobyBcImF6IGxvZ2luIGZhaWxlZC4gUmV0cnlpbmcuLi5cIgogICAgICAgIGxldCBSRVRSSUVTLT0xCiAgICAgICAgc2xlZXAgNQogICAgZmkKZG9uZQoKdHJhcCBcImNsZWFudXBcIiBFWElUCgpjbGVhbnVwKCkgewogIGF6IGxvZ291dAogIFtbIFwkVEVNUF9ESVIgPX4gL3RtcC8uKyBdXSAmJiBybSAtcmYgXCRURU1QX0RJUgogIFtbIFwkQVpVUkVfQ09ORklHX0RJUiA9fiAvdG1wLy4rIF1dICYmIHJtIC1yZiBcJEFaVVJFX0NPTkZJR19ESVIKfQoKaWYgW1sgXCRDT01QT05FTlQgPSBcIm1kbVwiIF1dOyB0aGVuCiAgQ1VSUkVOVF9DRVJUX0ZJTEU9XCIvZXRjL21kbS5wZW1cIgplbGlmIFtbIFwkQ09NUE9ORU5UID0gXCJtZHNkXCIgXV07IHRoZW4KICBDVVJSRU5UX0NFUlRfRklMRT1cIi92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlL21kc2QucGVtXCIKZWxzZQogIGVjaG8gSW52YWxpZCB1c2FnZSAmJiBleGl0IDEKZmkKClNFQ1JFVF9OQU1FPVwiJHNlY3JldF9wcmVmaXgtXCR7Q09NUE9ORU5UfVwiCk5FV19DRVJUX0ZJTEU9XCJcJFRFTVBfRElSL1wkQ09NUE9ORU5ULnBlbVwiCmZvciBhdHRlbXB0IGluIHsxLi41fTsgZG8KICBheiBrZXl2YXVsdCBcCiAgICBzZWNyZXQgXAogICAgZG93bmxvYWQgXAogICAgLS1maWxlIFwiXCRORVdfQ0VSVF9GSUxFXCIgXAogICAgLS1pZCBcImh0dHBzOi8vJEtFWVZBVUxUUFJFRklYLSRrZXl2YXVsdF9zdWZmaXguJEtFWVZBVUxURE5TU1VGRklYL3NlY3JldHMvXCRTRUNSRVRfTkFNRVwiIFwKICAgICYmIGJyZWFrCiAgaWYgW1sgXCRhdHRlbXB0IC1sdCA1IF1dOyB0aGVuIHNsZWVwIDEwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKaWYgWyAtZiBcJE5FV19DRVJUX0ZJTEUgXTsgdGhlbgogIGlmIFtbIFwkQ09NUE9ORU5UID0gXCJtZHNkXCIgXV07IHRoZW4KICAgIGNob3duIHN5c2xvZzpzeXNsb2cgXCRORVdfQ0VSVF9GSUxFCiAgZWxzZQogICAgc2VkIC1pIC1uZSAnMSwvRU5EIENFUlRJRklDQVRFLyBwJyBcJE5FV19DRVJUX0ZJTEUKICBmaQoKICBuZXdfY2VydF9zbj1cIlwkKG9wZW5zc2wgeDUwOSAtaW4gXCJcJE5FV19DRVJUX0ZJTEVcIiAtbm9vdXQgLXNlcmlhbCB8IGF3ayAtRj0gJ3twcmludCBcJDJ9JylcIgogIGN1cnJlbnRfY2VydF9zbj1cIlwkKG9wZW5zc2wgeDUwOSAtaW4gXCJcJENVUlJFTlRfQ0VSVF9GSUxFXCIgLW5vb3V0IC1zZXJpYWwgfCBhd2sgLUY9ICd7cHJpbnQgXCQyfScpXCIKICBpZiBbWyAhIC16IFwkbmV3X2NlcnRfc24gXV0gJiYgW1sgXCRuZXdfY2VydF9zbiAhPSBcIlwkY3VycmVudF9jZXJ0X3NuXCIgXV07IHRoZW4KICAgIGVjaG8gdXBkYXRpbmcgY2VydGlmaWNhdGUgZm9yIFwkQ09NUE9ORU5UCiAgICBjaG1vZCAwNjAwIFwkTkVXX0NFUlRfRklMRQogICAgbXYgXCRORVdfQ0VSVF9GSUxFIFwkQ1VSUkVOVF9DRVJUX0ZJTEUKICBmaQplbHNlCiAgZWNobyBGYWlsZWQgdG8gcmVmcmVzaCBjZXJ0aWZpY2F0ZSBmb3IgXCRDT01QT05FTlQgJiYgZXhpdCAxCmZpIgoKICAgIHdyaXRlX2ZpbGUgZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGVuYW1lIGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlIHRydWUKCiAgICBjaG1vZCB1K3ggL3Vzci9sb2NhbC9iaW4vZG93bmxvYWQtY3JlZGVudGlhbHMuc2gKCiAgICAkZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGVuYW1lIG1kc2QgJgogICAgd2FpdCAiJCEiCgoKICAgICRkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWUgbWRtICYKICAgIHdhaXQgIiQhIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3NlcnZpY2VfZmlsZW5hbWU9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnNlcnZpY2UiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkc19zZXJ2aWNlX2ZpbGU9IltVbml0XQpEZXNjcmlwdGlvbj1XYXRjaCBmb3IgY2hhbmdlcyBpbiBtZG0ucGVtIGFuZCByZXN0YXJ0cyB0aGUgbWRtIHNlcnZpY2UKCltTZXJ2aWNlXQpUeXBlPW9uZXNob3QKRXhlY1N0YXJ0PS91c3IvYmluL3N5c3RlbWN0bCByZXN0YXJ0IG1kbS5zZXJ2aWNlCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQiCgogICAgd3JpdGVfZmlsZSB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlbmFtZSB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGVuYW1lPScvdXNyL2xpYi9zeXN0ZW1kL3N5c3RlbS93YXRjaC1tZG0tY3JlZGVudGlhbHMucGF0aCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZT0nW1BhdGhdClBhdGhNb2RpZmllZD0vZXRjL21kbS5wZW0KCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCcKCiAgICB3cml0ZV9maWxlIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGVuYW1lIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGUgdHJ1ZQoKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkcz0nd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnBhdGgnCiAgICBzeXN0ZW1jdGwgZW5hYmxlIC0tbm93ICIkd2F0Y2hfbWRtX2NyZWRzIiB8fCBhYm9ydCAiZmFpbGVkIHRvIGVuYWJsZSBhbmQgc3RhcnQgJHdhdGNoX21kbV9jcmVkcyIKfQoKIyBjb25maWd1cmVfc2VydmljZV9tZG0KIyBhcmdzOgojIDEpIHJvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgojIDIpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBtZG0gY29udGFpbmVyIGltYWdlIHRvIHJ1bgpjb25maWd1cmVfc2VydmljZV9tZG0oKSB7CiAgICBsb2NhbCAtbiByb2xlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIG1kbSBzZXJ2aWNlIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHN5c2NvbmZpZ19tZG1fZmlsZW5hbWU9Ii9ldGMvc3lzY29uZmlnL21kbSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX21kbV9maWxlPSJNRE1GUk9OVEVORFVSTD0nJE1ETUZST05URU5EVVJMJwpNRE1JTUFHRT0nJGltYWdlJwpNRE1TT1VSQ0VFTlZJUk9OTUVOVD0nJExPQ0FUSU9OJwpNRE1TT1VSQ0VST0xFPSckcm9sZScKTURNU09VUkNFUk9MRUlOU1RBTkNFPVwiJChob3N0bmFtZSlcIiIKCiAgICB3cml0ZV9maWxlIHN5c2NvbmZpZ19tZG1fZmlsZW5hbWUgc3lzY29uZmlnX21kbV9maWxlIHRydWUKCiAgICBta2RpciAtcCAvdmFyL2V0dwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZG1fc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9tZG0uc2VydmljZSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRtX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvbWRtCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWVudHJ5cG9pbnQgL3Vzci9zYmluL01ldHJpY3NFeHRlbnNpb24gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtbSAyZyBcCiAgLXYgL2V0Yy9tZG0ucGVtOi9ldGMvbWRtLnBlbSBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJGltYWdlIFwKICAtQ2VydEZpbGUgL2V0Yy9tZG0ucGVtIFwKICAtRnJvbnRFbmRVcmwgJE1ETUZST05URU5EVVJMIFwKICAtTG9nZ2VyIENvbnNvbGUgXAogIC1Mb2dMZXZlbCBXYXJuaW5nIFwKICAtUHJpdmF0ZUtleUZpbGUgL2V0Yy9tZG0ucGVtIFwKICAtU291cmNlRW52aXJvbm1lbnQgJExPQ0FUSU9OIFwKICAtU291cmNlUm9sZSAkcm9sZSBcCiAgLVNvdXJjZVJvbGVJbnN0YW5jZSAkSE9TVE5BTUUKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgJU4KUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz0xClN0YXJ0TGltaXRJbnRlcnZhbD0wCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQiCgogICAgd3JpdGVfZmlsZSBtZG1fc2VydmljZV9maWxlbmFtZSBtZG1fc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfdm1zc19hcm9fc2VydmljZQojIGFyZ3M6CiMgMSkgciAtIG5hbWVyZWYsIHN0cmluZzsgcm9sZSBvZiBWTVNTCiMgMikgaW1hZ2VzIC0gbmFtZXJlZiwgYXNzb2NpYXRpdmUgYXJyYXk7IEFSTyBjb250YWluZXIgaW1hZ2VzCiMgMykgY29uZmlncyAtIG5hbWVyZWYsIGFzc29jaWF0aXZlIGFycmF5OyBjb25maWd1cmF0aW9uIGZpbGVzIGFuZCB2ZXJzaW9ucy4gVGhlIHZhbHVlcyBzaG91bGQgYmUgYSByZWZlcmVuY2UgdG8gdmFyaWFibGVzLCBub3QgZGVyZWZlcmVuY2VkLgojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBpcyBiZWNhdXNlIHRoZSB2YWx1ZSBpcyB1c2VkIHdoZW4gY3JlYXRpbmcgbmFtZXJlZiB2YXJpYWJsZXMgYnkgaGVscGVyIGZ1bmN0aW9ucy4KY29uZmlndXJlX3Ztc3NfYXJvX3NlcnZpY2VzKCkgewogICAgbG9jYWwgLW4gcj0iJDEiCiAgICBsb2NhbCAtbiBpbWFnZXM9IiQyIgogICAgbG9jYWwgLW4gY29uZmlncz0iJDMiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgdmVyaWZ5X3JvbGUgIiQxIgoKICAgIGlmIFsgIiRyIiA9PSAiJHJvbGVfZ2F0ZXdheSIgXTsgdGhlbgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19nYXRld2F5ICIke2ltYWdlc1sicnAiXX0iICIkMSIgIiR7Y29uZmlnc1siZ2F0ZXdheV9jb25maWciXX0iCiAgICAgICAgY29uZmlndXJlX2NlcnRzX2dhdGV3YXkKICAgIGVsaWYgWyAiJHIiID09ICIkcm9sZV9ycCIgXTsgdGhlbgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19ycCAiJHtpbWFnZXNbInJwIl19IiAiJDEiICIke2NvbmZpZ3NbInJwX2NvbmZpZyJdfSIKICAgICAgICBjb25maWd1cmVfc2VydmljZV9hcm9fbW9uaXRvciAiJHtpbWFnZXNbInJwIl19IgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19wb3J0YWwgIiR7aW1hZ2VzWyJycCJdfSIKICAgICAgICBjb25maWd1cmVfY2VydHNfcnAKICAgIGZpCgogICAgY29uZmlndXJlX3NlcnZpY2VfZmx1ZW50Yml0ICIke2NvbmZpZ3NbImZsdWVudGJpdCJdfSIgIiR7aW1hZ2VzWyJmbHVlbnRiaXQiXX0iCiAgICBjb25maWd1cmVfdGltZXJzX21kbV9tZHNkICIkMSIKICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX21kbSAiJDEiICIke2ltYWdlc1sibWRtIl19IgogICAgY29uZmlndXJlX3NlcnZpY2VfbWRzZCAiJDEiICIke2NvbmZpZ3NbIm1kc2QiXX0iCiAgICBydW5fYXpzZWNkX2NvbmZpZ19zY2FuCn0KCiMgdXRpbC1jb21tb24uc2ggZG9lcyBub3QgZXhpc3Qgd2hlbiBkZXBsb3llZCB0byBWTVNTIHZpYSBWTVNTIGV4dGVuc2lvbnMKIyBQcm92aWRlcyBzaGVsbGNoZWNrIGRlZmluaXRpb25zCnV0aWxfY29tbW9uPSJ1dGlsLWNvbW1vbi5zaCIKaWYgWyAtZiAiJHV0aWxfY29tbW9uIiBdOyB0aGVuCiAgICAjIHNoZWxsY2hlY2sgc291cmNlPXV0aWwtY29tbW9uLnNoCiAgICBzb3VyY2UgIiR1dGlsX2NvbW1vbiIKZmkKCiMgdXRpbC1zeXN0ZW0uc2ggZG9lcyBub3QgZXhpc3Qgd2hlbiBkZXBsb3llZCB0byBWTVNTIHZpYSBWTVNTIGV4dGVuc2lvbnMKIyBQcm92aWRlcyBzaGVsbGNoZWNrIGRlZmluaXRpb25zCnV0aWxfc3lzdGVtPSJ1dGlsLXN5c3RlbS5zaCIKaWYgWyAtZiAiJHV0aWxfc3lzdGVtIiBdOyB0aGVuCiAgICAjIHNoZWxsY2hlY2sgc291cmNlPXV0aWwtc3lzdGVtLnNoCiAgICBzb3VyY2UgIiR1dGlsX3N5c3RlbSIKZmkKIyEvYmluL2Jhc2gKIyBUaGlzIGZpbGUgaXMgaW50ZW5kZWQgdG8gYmUgc291cmNlZCBieSBib290c3RyYXBwaW5nIHNjcmlwdHMgZm9yIGNvbW1vbmx5IHVzZWQgZnVuY3Rpb25zCgojIGdldF9ib290X2Rldl91dWlkCiMgR2V0IHRoZSBib290IGRldmljZXMgdXVpZAojIGFyZ3M6CiMgMSkgYm9vdF9kZXZfdXVpZCAtIG5hbWVyZWYsIHN0cmluZzsgRW1wdHkgdmFyaWFibGUgZm9yIGJvb3QgZGV2aWNlIHV1aWQgYXNzaWdubWVudAojIFRha2VuIGFuZCByZWZhY3RvcmVkIGZyb20gaHR0cHM6Ly9lbmcubXMvZG9jcy9wcm9kdWN0cy9henVyZS1saW51eC9mZWF0dXJlcy9zZWN1cml0eS9maXBzCmdldF9ib290X2Rldl91dWlkKCkgewogICAgbG9jYWwgLW4gYm9vdF9kZXZfdXVpZD0iJDEiCiAgICAjIFNldCBib290X3V1aWQgdmFyaWFibGUgZm9yIHRoZSBib290IHBhcnRpdGlvbiBpZiBkaWZmZXJlbnQgZnJvbSB0aGUgcm9vdAogICAgYm9vdF9kZXY9IiQoZGYgL2Jvb3QvIHwgdGFpbCAtMSB8IGN1dCAtZCcgJyAtZjEpIgogICAgcm9vdF9kZXY9IiQoZGYgLyB8IHRhaWwgLTEgfCBjdXQgLWQnICcgLWYxKSIKCiAgICBib290X2Rldl91dWlkPSIkcm9vdF9kZXYiCiAgICBpZiBbICIkYm9vdF9kZXYiICE9ICIkcm9vdF9kZXYiIF07IHRoZW4KICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBib290X2Rldl91dWlkPSJib290PVVVSUQ9JChibGtpZCAiJGJvb3RfZGV2IiAtcyBVVUlEIC1vIHZhbHVlKSIKICAgIGZpCn0KCiMgZmlwc192ZXJpZnkKIyBWZXJpZnkgdGhhdCBmaXBzIG1vZGUgaXMgZW5hYmxlZAojIFRha2VuIGFuZCByZWZhY3RvcmVkIGZyb20gaHR0cHM6Ly9lbmcubXMvZG9jcy9wcm9kdWN0cy9henVyZS1saW51eC9mZWF0dXJlcy9zZWN1cml0eS9maXBzCmZpcHNfdmVyaWZ5KCkgewogICAgZmlwc19lbmFibGVkX3Byb2M9IiQoY2F0IC9wcm9jL3N5cy9jcnlwdG8vZmlwc19lbmFibGVkKSIKICAgIGZpcHNfZW5hYmxlZF9zeXNjdGw9IiQoc3lzY3RsIC1uIGNyeXB0by5maXBzX2VuYWJsZWQpIgogICAgaWYgWyAiJGZpcHNfZW5hYmxlZF9wcm9jIiAtbmUgMSBdIHx8IFsgIiRmaXBzX2VuYWJsZWRfc3lzY3RsIiAtbmUgMSBdOyB0aGVuCiAgICAgICAgYWJvcnQgIkZJUFMgbW9kZSBpcyBkaXNhYmxlZCIKICAgIGZpCgogICAgbG9nICJGSVBTIG1vZGUgaXMgZW5hYmxlZCIKfQoKIyBmaXBzX2NvbmZpZ3VyZQojIENvbmZpZ3VyZXMgVk0gdG8gcnVuIHdpdGggZmlwcyBtb2RlIGVuYWJsZWQKIyBUYWtlbiBhbmQgcmVmYWN0b3JlZCBmcm9tIGh0dHBzOi8vZW5nLm1zL2RvY3MvcHJvZHVjdHMvYXp1cmUtbGludXgvZmVhdHVyZXMvc2VjdXJpdHkvZmlwcwojIFRPRE8gcmVtb3ZlIHRoaXMgb25jZSBza3UgY2JsLW1hcmluZXItMi1nZW4yLWZpcHMgaXMgc3VwcG9ydGVkIGJ5IGF1dG9tYXRpYyBPUyB1cGRhdGVzCiMgUmVmZXJlbmNlOiBodHRwczovL2xlYXJuLm1pY3Jvc29mdC5jb20vZW4tdXMvYXp1cmUvdmlydHVhbC1tYWNoaW5lLXNjYWxlLXNldHMvdmlydHVhbC1tYWNoaW5lLXNjYWxlLXNldHMtYXV0b21hdGljLXVwZ3JhZGUjc3VwcG9ydGVkLW9zLWltYWdlcwpmaXBzX2NvbmZpZ3VyZSgpIHsKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgYm9vdF91dWlkCiAgICBnZXRfYm9vdF9kZXZfdXVpZCBib290X3V1aWQKCiAgICBsb2NhbCBncnViMl9lbnYKICAgIGlmIGdydWIyX2Vudj0iJChncnViMi1lZGl0ZW52IC0gbGlzdCB8IGdyZXAga2VybmVsb3B0cykiOyB0aGVuCiAgICAgICAgZ3J1YjItZWRpdGVudiAtIHNldCAiJGdydWIyX2VudiBmaXBzPTEgJGJvb3RfdXVpZCIKICAgIGVsc2UKICAgICAgICBncnViYnkgLS11cGRhdGUta2VybmVsPUFMTCAtLWFyZ3M9ImZpcHM9MSAkYm9vdF91dWlkIgogICAgZmkKCiAgICAjIGZpcHMgbW9kZSB2ZXJpZmljYXRpb24gd2lsbCBmYWlsIHVudGlsIGFmdGVyIHRoZSB2bSBoYXMgYmVlbiByZWJvb3RlZAogICAgIyBmaXBzX3ZlcmlmeQp9CgojIGNvbmZpZ3VyZV9zc2hkCiMgV2UgbmVlZCB0byBjb25maWd1cmUgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB0byB5ZXMgaW4gb3JkZXIgZm9yIHRoZSBWTVNTIEFjY2VzcyBKSVQgdG8gd29yawpjb25maWd1cmVfc3NoZCgpIHsKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2NhbCAtciBzc2hkX2NvbmZpZz0iL2V0Yy9zc2gvc3NoZF9jb25maWciCgogICAgbG9nICJFZGl0aW5nICRzc2hkX2NvbmZpZyB0byBhbGxvdyBwYXNzd29yZCBhdXRoZW50aWNhdGlvbiIKICAgIHNlZCAtaSAncy9QYXNzd29yZEF1dGhlbnRpY2F0aW9uIG5vL1Bhc3N3b3JkQXV0aGVudGljYXRpb24geWVzL2cnICIkc3NoZF9jb25maWciCgogICAgc3lzdGVtY3RsIHJlbG9hZCBzc2hkLnNlcnZpY2UgfHwgYWJvcnQgInNzaGQgZmFpbGVkIHRvIHJlbG9hZCIKfQoKIyBjb25maWd1cmVfbG9ncm90YXRlIGNsb2JiZXJzIC9ldGMvbG9ncm90YXRlLmNvbmYKIyBhcmdzOgojIDEpIGRyb3Bpbl9maWxlcyAtIG5hbWVyZWYsIGFzc29jaWF0aXZlIGFycmF5LCBvcHRpb25hbDsgbG9ncm90YXRlIGZpbGVzIHRvIHdyaXRlIHRvIC9ldGMvbG9ncm90YXRlLmQKIyAgICAgICBLZXkgbmFtZSBkaWN0YXRlcyBmaWxlbmFtZXMgd3JpdHRlbiB0byAvZXRjL2xvZ3JvdGF0ZS5kLgojIEV4YW1wbGU6CiMgICBLZXkgZGljdGF0ZXMgdGhlIGZpbGVuYW1lIHdyaXR0ZW4gaW4gL2V0Yy9sb2dyb3RhdGUuZAojICAgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAojICAgbG9jYWwgLXJBIGxvZ3JvdGF0ZV9kcm9waW5zPSgKIyAgICAgIFsiZ2F0ZXdheSJdPSIkZ2F0ZXdheV9sb2dfZmlsZSIKIyAgICkKY29uZmlndXJlX2xvZ3JvdGF0ZSgpIHsKICAgIGxvY2FsIC1uIGRyb3Bpbl9maWxlcz0iJHsxOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGxvZ3JvdGF0ZV9jb25mX2ZpbGVuYW1lPScvZXRjL2xvZ3JvdGF0ZS5jb25mJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBsb2dyb3RhdGVfY29uZl9maWxlPScjIHNlZSAibWFuIGxvZ3JvdGF0ZSIgZm9yIGRldGFpbHMKIyByb3RhdGUgbG9nIGZpbGVzIHdlZWtseQp3ZWVrbHkKCiMga2VlcCAyIHdlZWtzIHdvcnRoIG9mIGJhY2tsb2dzCnJvdGF0ZSAyCgojIGNyZWF0ZSBuZXcgKGVtcHR5KSBsb2cgZmlsZXMgYWZ0ZXIgcm90YXRpbmcgb2xkIG9uZXMKY3JlYXRlCgojIHVzZSBkYXRlIGFzIGEgc3VmZml4IG9mIHRoZSByb3RhdGVkIGZpbGUKZGF0ZWV4dAoKIyB1bmNvbW1lbnQgdGhpcyBpZiB5b3Ugd2FudCB5b3VyIGxvZyBmaWxlcyBjb21wcmVzc2VkCmNvbXByZXNzCgojIFJQTSBwYWNrYWdlcyBkcm9wIGxvZyByb3RhdGlvbiBpbmZvcm1hdGlvbiBpbnRvIHRoaXMgZGlyZWN0b3J5CmluY2x1ZGUgL2V0Yy9sb2dyb3RhdGUuZAoKIyBubyBwYWNrYWdlcyBvd24gd3RtcCBhbmQgYnRtcCAtLSB3ZSB3aWxsIHJvdGF0ZSB0aGVtIGhlcmUKL3Zhci9sb2cvd3RtcCB7CiAgICBtb250aGx5CiAgICBjcmVhdGUgMDY2NCByb290IHV0bXAKICAgICAgICBtaW5zaXplIDFNCiAgICByb3RhdGUgMQp9CgovdmFyL2xvZy9idG1wIHsKICAgIG1pc3NpbmdvawogICAgbW9udGhseQogICAgY3JlYXRlIDA2MDAgcm9vdCB1dG1wCiAgICByb3RhdGUgMQp9JwoKICAgIHdyaXRlX2ZpbGUgbG9ncm90YXRlX2NvbmZfZmlsZW5hbWUgbG9ncm90YXRlX2NvbmZfZmlsZSB0cnVlCgogICAgaWYgWyAtbiAiJHtkcm9waW5fZmlsZXNbKl19IiBdOyB0aGVuCiAgICAgICAgbG9jYWwgLXIgbG9ncm90YXRlX2Q9Ii9ldGMvbG9ncm90YXRlLmQiCiAgICAgICAgbG9nICJXcml0aW5nIGxvZ3JvdGF0ZSBmaWxlcyB0byAkbG9ncm90YXRlX2QiCiAgICAgICAgZm9yIGRyb3Bpbl9uYW1lIGluICIkeyFkcm9waW5fZmlsZXNbQF19IjsgZG8KICAgICAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgICAgIGxvY2FsIC1yIGRyb3Bpbl9maWxlbmFtZT0iJGxvZ3JvdGF0ZV9kLyRkcm9waW5fbmFtZSIKICAgICAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgICAgIGxvY2FsIC1yIGRyb3Bpbl9maWxlPSIke2Ryb3Bpbl9maWxlc1siJGRyb3Bpbl9uYW1lIl19IgogICAgICAgICAgICB3cml0ZV9maWxlIGRyb3Bpbl9maWxlbmFtZSBkcm9waW5fZmlsZSB0cnVlCiAgICAgICAgZG9uZQogICAgZmkKfQoKIyBwdWxsX2NvbnRhaW5lcl9pbWFnZXMKIyBhcmdzOgojIDEpIHB1bGxfaW1hZ2VzIC0gbmFtZXJlZiwgc3RyaW5nIGFycmF5CiMgMikgcmVnaXN0cnlfY29uZiAtIG5hbWVyZWYsIHN0cmluZywgb3B0aW9uYWw7IHBhdGggdG8gZG9ja2VyL3BvZG1hbiBjb25maWd1cmF0aW9uIGZpbGUKcHVsbF9jb250YWluZXJfaW1hZ2VzKCkgewogICAgbG9jYWwgLW4gcHVsbF9pbWFnZXM9IiQxIgogICAgbG9jYWwgLW4gcmVnaXN0cnlfY29uZj0iJHsyOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yaSByZXRyeV90aW1lPTMwCiAgICBjbWQ9KAogICAgICAgIGF6CiAgICAgICAgbG9naW4KICAgICAgICAtaQogICAgICAgIC0tYWxsb3ctbm8tc3Vic2NyaXB0aW9ucwogICAgKQoKICAgIGxvZyAiUnVubmluZyBheiBsb2dpbiB3aXRoIHJldHJpZXMiCiAgICByZXRyeSBjbWQgcmV0cnlfdGltZQoKICAgICMgU3VwcHJlc3MgZW11bGF0aW9uIG91dHB1dCBmb3IgcG9kbWFuIGluc3RlYWQgb2YgZG9ja2VyIGZvciBheiBhY3IgY29tcGF0YWJpbGl0eQogICAgbWtkaXIgLXAgL2V0Yy9jb250YWluZXJzLwogICAgbWtkaXIgLXAgL3Jvb3QvLmRvY2tlcgogICAgdG91Y2ggL2V0Yy9jb250YWluZXJzL25vZG9ja2VyCgogICAgIyBUaGlzIG5hbWUgaXMgdXNlZCBpbiB0aGUgY2FzZSB0aGF0IGF6IGFjciBsb2dpbiBzZWFyY2hlcyBmb3IgdGhpcyBpbiBpdCdzIGVudmlyb25tZW50CiAgICBleHBvcnQgUkVHSVNUUllfQVVUSF9GSUxFPSIvcm9vdC8uZG9ja2VyL2NvbmZpZy5qc29uIgoKICAgIGlmIFsgLW4gIiR7cmVnaXN0cnlfY29uZn0iIF07IHRoZW4KICAgICAgICB3cml0ZV9maWxlIFJFR0lTVFJZX0FVVEhfRklMRSByZWdpc3RyeV9jb25mIHRydWUKICAgIGZpCgogICAgbG9nICJsb2dnaW5nIGludG8gcHJvZCBhY3IiCiAgICBjbWQ9KAogICAgICAgIGF6CiAgICAgICAgYWNyCiAgICAgICAgbG9naW4KICAgICAgICAtLW5hbWUKICAgICAgICAjIFRPRE8gcmVwbGFjZSB0aGlzIHdpdGggdmFyaWFibGUgZXhwYW5zaW9uCiAgICAgICAgIyBSZWZlcmVuY2U6IGh0dHBzOi8vd3d3LnNoZWxsY2hlY2submV0L3dpa2kvU0MyMDAxCiAgICAgICAgIiQoc2VkIC1lICdzfC4qL3x8JyA8PDwiJEFDUlJFU09VUkNFSUQiKSIKICAgICkKCiAgICByZXRyeSBjbWQgcmV0cnlfdGltZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgZm9yIGkgaW4gJHtwdWxsX2ltYWdlc1tAXX07IGRvCiAgICAgICAgbG9jYWwgLW4gaW1hZ2U9IiRpIgogICAgICAgIGNtZD0oCiAgICAgICAgICAgIHBvZG1hbgogICAgICAgICAgICBwdWxsCiAgICAgICAgICAgICIkaW1hZ2UiCiAgICAgICAgKQoKICAgICAgICBsb2cgIlB1bGxpbmcgaW1hZ2UgJGltYWdlIHdpdGggcmV0cmllcyBub3ciCiAgICAgICAgcmV0cnkgY21kIHJldHJ5X3RpbWUKICAgIGRvbmUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGNtZD0oCiAgICAgICAgYXoKICAgICAgICBsb2dvdXQKICAgICkKCiAgICBsb2cgIlJ1bm5pbmcgYXogbG9nb3V0IHdpdGggcmV0cmllcyIKICAgIHJldHJ5IGNtZCByZXRyeV90aW1lCn0KCiMgY29uZmlndXJlX2NlcnRzX2dlbmVyYWwgQ29uZmlndXJlIHN5c3RlbSBjZXJ0aWZpY2F0ZXMgY29tbW9uIHRvIGFsbCBWTVNTIGluc3RhbmNlcwpjb25maWd1cmVfY2VydHNfZ2VuZXJhbCgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgIyBzZXR0aW5nIE1PTklUT1JJTkdfR0NTX0FVVEhfSURfVFlQRT1BdXRoS2V5VmF1bHQgc2VlbXMgdG8gaGF2ZSBjYXVzZWQgbWRzZCBub3QKICAgICMgdG8gaG9ub3VyIFNTTF9DRVJUX0ZJTEUgYW55IG1vcmUsIGhlYXZlbiBvbmx5IGtub3dzIHdoeS4KICAgIGxvY2FsIC1yIHNzbF9jZXJ0c19iYXNlZGlyPSIvdXNyL2xpYi9zc2wvY2VydHMiCiAgICBta2RpciAtcCAiJHNzbF9jZXJ0c19iYXNlZGlyIgogICAgY3NwbGl0IC1mICIkc3NsX2NlcnRzX2Jhc2VkaXIvY2VydC0iIC1iICUwM2QucGVtIC9ldGMvcGtpL3Rscy9jZXJ0cy9jYS1idW5kbGUuY3J0IC9eJC8xICJ7Kn0iIDE+L2Rldi9udWxsCiAgICBjX3JlaGFzaCAiJHNzbF9jZXJ0c19iYXNlZGlyIgp9CgojIGNvbmZpZ3VyZV9jZXJ0c19ycCBDb25maWd1cmUgc3lzdGVtIGNlcnRpZmljYXRlcyBmb3IgUlAgVk1TUwojIGFyZ3M6CmNvbmZpZ3VyZV9jZXJ0c19ycCgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgdmVyaWZ5X3JvbGUgcm9sZV9ycAoKICAgIGxvY2FsIC1yIHJwX2NlcnRzX2Jhc2VkaXI9Ii9ldGMvYXJvLXJwIgogICAgbWtkaXIgLXAgIiRycF9jZXJ0c19iYXNlZGlyIgogICAgYmFzZTY0IC1kIDw8PCIkQURNSU5BUElDQUJVTkRMRSIgPiAiJHJwX2NlcnRzX2Jhc2VkaXIvYWRtaW4tY2EtYnVuZGxlLnBlbSIKICAgIGlmIFtbIC1uICIkQVJNQVBJQ0FCVU5ETEUiIF1dOyB0aGVuCiAgICBiYXNlNjQgLWQgPDw8IiRBUk1BUElDQUJVTkRMRSIgPiAiJHJwX2NlcnRzX2Jhc2VkaXIvYXJtLWNhLWJ1bmRsZS5wZW0iCiAgICBmaQogICAgY2hvd24gLVIgMTAwMDoxMDAwICIkcnBfY2VydHNfYmFzZWRpciIKCiAgICBjb25maWd1cmVfY2VydHNfZ2VuZXJhbAp9CgojIGNvbmZpZ3VyZV9jZXJ0c19nYXRld2F5IENvbmZpZ3VyZSBzeXN0ZW0gY2VydGlmaWNhdGVzIGZvciBHYXRld2F5IFZNU1MgaW5zdGFuY2VzCmNvbmZpZ3VyZV9jZXJ0c19nYXRld2F5KCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICB2ZXJpZnlfcm9sZSByb2xlX2dhdGV3YXkKICAgIGNvbmZpZ3VyZV9jZXJ0c19nZW5lcmFsCn0KCiMgY29uZmlndXJlX2NlcnRzX2RldnByb3h5IENvbmZpZ3VyZSBzeXN0ZW0gY2VydGlmaWNhdGVzIGZvciBkZXZwcm94eSBWTVNTIGluc3RhbmNlcwpjb25maWd1cmVfY2VydHNfZGV2cHJveHkoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHZlcmlmeV9yb2xlIHJvbGVfZGV2cHJveHkKCiAgICBsb2NhbCAtciBwcm94eV9jZXJ0c19iYXNlZGlyPSIvZXRjL3Byb3h5IgogICAgbWtkaXIgLXAgIiRwcm94eV9jZXJ0c19iYXNlZGlyIgogICAgYmFzZTY0IC1kIDw8PCIkUFJPWFlDRVJUIiA+ICIkcHJveHlfY2VydHNfYmFzZWRpci9wcm94eS5jcnQiCiAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUtFWSIgPiAiJHByb3h5X2NlcnRzX2Jhc2VkaXIvcHJveHkua2V5IgogICAgYmFzZTY0IC1kIDw8PCIkUFJPWFlDTElFTlRDRVJUIiA+ICIkcHJveHlfY2VydHNfYmFzZWRpci9wcm94eS1jbGllbnQuY3J0IgogICAgY2hvd24gLVIgMTAwMDoxMDAwIC9ldGMvcHJveHkKICAgIGNobW9kIDA2MDAgIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LmtleSIKfQoKY29uZmlndXJlX2F6c2VjZF9zY2FuKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHdlIGxlYXZlIGNsaWVudElkIGJsYW5rIGFzIGxvbmcgYXMgb25seSAxIG1hbmFnZWQgaWRlbnRpdHkgYXNzaWduZWQgdG8gdm1zcwogICAgIyBpZiB3ZSBoYXZlIG1vcmUgdGhhbiAxLCB3ZSB3aWxsIG5lZWQgdG8gcG9wdWxhdGUgd2l0aCBjbGllbnRJZCB1c2VkIGZvciBvZmYtbm9kZSBzY2FubmluZwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBub2Rlc2Nhbl9hZ2VudF9maWxlbmFtZT0iL2V0Yy9kZWZhdWx0L3ZzYS1ub2Rlc2Nhbi1hZ2VudC5jb25maWciCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG5vZGVzY2FuX2FnZW50X2ZpbGU9InsKICAgIFwiTmljZVwiOiAxOSwKICAgIFwiVGltZW91dFwiOiAxMDgwMCwKICAgIFwiQ2xpZW50SWRcIjogXCJcIiwKICAgIFwiVGVuYW50SWRcIjogJEFaVVJFU0VDUEFDS1ZTQVRFTkFOVElELAogICAgXCJRdWFseXNTdG9yZUJhc2VVcmxcIjogJEFaVVJFU0VDUEFDS1FVQUxZU1VSTCwKICAgIFwiUHJvY2Vzc1RpbWVvdXRcIjogMzAwLAogICAgXCJDb21tYW5kRGVsYXlcIjogMAogIH0iCgogICAgd3JpdGVfZmlsZSBub2Rlc2Nhbl9hZ2VudF9maWxlbmFtZSBub2Rlc2Nhbl9hZ2VudF9maWxlIHRydWUKfQoKIyBydW5fYXpzZWNkX2NvbmZpZ19zY2FuCnJ1bl9henNlY2RfY29uZmlnX3NjYW4oKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGNvbmZpZ3VyZV9henNlY2Rfc2NhbgoKICAgIGxvY2FsIC1hciBjb25maWdzPSgKICAgICAgICAiYmFzZWxpbmUiCiAgICAgICAgImNsYW1hdiIKICAgICAgICAic29mdHdhcmUiCiAgICApCgogICAgbG9nICJTY2FubmluZyBjb25maWd1cmF0aW9uIGZpbGVzIHdpdGggYXpzZWNkICR7Y29uZmlnc1sqXX0iCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBzY2FuIGluICR7Y29uZmlnc1tAXX07IGRvCiAgICAgICAgbG9nICJTY2FubmluZyBjb25maWcgZmlsZSAkc2NhbiBub3ciCiAgICAgICAgL3Vzci9sb2NhbC9iaW4vYXpzZWNkIGNvbmZpZyAtcyAiJHNjYW4iIC1kIFAxRAogICAgZG9uZQp9CgojIGNyZWF0ZV9yZXF1aXJlZF9kaXJzCmNyZWF0ZV9yZXF1aXJlZF9kaXJzKCkgewogICAgY3JlYXRlX2RpcnM9KAogICAgICAgIC92YXIvbG9nL2pvdXJuYWwKICAgICAgICAvdmFyL2xpYi93YWFnZW50L01pY3Jvc29mdC5BenVyZS5LZXlWYXVsdC5TdG9yZQogICAgICAgICMgRG9lcyBub3QgZXhpc3Qgb24gZGV2UHJveHlWTVNTCiAgICAgICAgL3Zhci9vcHQvbWljcm9zb2Z0L2xpbnV4bW9uYWdlbnQKICAgICkKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBkIGluICR7Y3JlYXRlX2RpcnNbQF19OyBkbwogICAgICAgIGxvZyAiQ3JlYXRpbmcgZGlyZWN0b3J5ICRkIgogICAgICAgIG1rZGlyIC1wICIkZCIgfHwgYWJvcnQgImZhaWxlZCB0byBjcmVhdGUgZGlyZWN0b3J5ICRkIgogICAgZG9uZQp9CgojIGZpcmV3YWxsZF9jb25maWd1cmVfYmFja2VuZApmaXJld2FsbGRfY29uZmlndXJlX2JhY2tlbmQoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGxvZyAiQ2hhbmdpbmcgZmlyZXdhbGxkIGJhY2tlbmQgdG8gaXB0YWJsZXMiCiAgICBjb25mX2ZpbGU9Ii9ldGMvZmlyZXdhbGxkL2ZpcmV3YWxsZC5jb25mIgogICAgc2VkIC1pICdzL0ZpcmV3YWxsQmFja2VuZD1uZnRhYmxlcy9GaXJld2FsbEJhY2tlbmQ9aXB0YWJsZXMvZycgIiRjb25mX2ZpbGUiCn0KCiMgZmlyZXdhbGxkX2NvbmZpZ3VyZQojIGFyZ3M6CiMgMSkgcG9ydHMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IHBvcnRzIHRvIGJlIGVuYWJsZWQuCiMgICAgICAgUG9ydHMgbXVzdCBiZSBwb3N0Zml4ZWQgd2l0aCAvdGNwIG9yIC91ZHAKZmlyZXdhbGxkX2NvbmZpZ3VyZSgpIHsKICAgIGxvY2FsIC1uIHBvcnRzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgZmlyZXdhbGxkX2NvbmZpZ3VyZV9iYWNrZW5kCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgc2VydmljZT0oCiAgICAgICAgImZpcmV3YWxsZCIKICAgICkKICAgIGVuYWJsZV9zZXJ2aWNlcyBzZXJ2aWNlCgogICAgbG9nICJFbmFibGluZyBwb3J0cyAke3BvcnRzWypdfSBvbiBkZWZhdWx0IGZpcmV3YWxsZCB6b25lIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgcG9ydCBpbiAke3BvcnRzW0BdfTsgZG8KICAgICAgICBsb2cgIkVuYWJsaW5nIHBvcnQgJHBvcnQgbm93IgogICAgICAgIGZpcmV3YWxsLWNtZCAiLS1hZGQtcG9ydD0kcG9ydCIgXAogICAgICAgICAgICAgICAgICAgICAtLXBlcm1hbmVudAogICAgZG9uZQoKICAgIGxvZyAiV3JpdGluZyBydW50aW1lIGNvbmZpZyB0byBwZXJtYW5lbnQgY29uZmlnIgogICAgZmlyZXdhbGwtY21kIC0tcnVudGltZS10by1wZXJtYW5lbnQKfQoKIyB1dGlsLWNvbW1vbi5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQojIS9iaW4vYmFzaAoKc2V0IC1vIGVycmV4aXQgXAogICAgLW8gcGlwZWZhaWwgXAogICAgLW8gbm91bnNldAoKbWFpbigpIHsKICAgICMgdHJhbnNhY3Rpb24gYXR0ZW1wdCByZXRyeSB0aW1lIGluIHNlY29uZHMKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJpIHJldHJ5X3dhaXRfdGltZT0zMAogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBsb2NhbCAtcmkgcGtnX3JldHJ5X2NvdW50PTYwCgogICAgY3JlYXRlX3JlcXVpcmVkX2RpcnMKICAgIGNvbmZpZ3VyZV9zc2hkCiAgICBjb25maWd1cmVfcnBtX3JlcG9zIHJldHJ5X3dhaXRfdGltZSBcCiAgICAgICAgICAgICAgICAgICAgIiRwa2dfcmV0cnlfY291bnQiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtYXIgZXhjbHVkZV9wa2dzPSgKICAgICAgICAiLXggV0FMaW51eEFnZW50IgogICAgICAgICIteCBXQUxpbnV4QWdlbnQtdWRldiIKICAgICkKCiAgICBkbmZfdXBkYXRlX3BrZ3MgZXhjbHVkZV9wa2dzIFwKICAgICAgICAgICAgICAgICAgICByZXRyeV93YWl0X3RpbWUgXAogICAgICAgICAgICAgICAgICAgICIkcGtnX3JldHJ5X2NvdW50IgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJhIGluc3RhbGxfcGtncz0oCiAgICAgICAgY2xhbWF2CiAgICAgICAgYXpzZWMtY2xhbWF2CiAgICAgICAgYXp1cmUtY2xpCiAgICAgICAgYXp1cmUtbWRzZAogICAgICAgIGF6dXJlLXNlY3VyaXR5CiAgICAgICAgcG9kbWFuCiAgICAgICAgcG9kbWFuLWRvY2tlcgogICAgICAgIG9wZW5zc2wtcGVybAogICAgICAgICMgaGFjayAtIHdlIGFyZSBpbnN0YWxsaW5nIHB5dGhvbjMgb24gaG9zdHMgZHVlIHRvIGFuIGlzc3VlIHdpdGggQXp1cmUgTGludXggRXh0ZW5zaW9ucyBodHRwczovL2dpdGh1Yi5jb20vQXp1cmUvYXp1cmUtbGludXgtZXh0ZW5zaW9ucy9wdWxsLzE1MDUKICAgICAgICBweXRob24zCiAgICAgICAgIyByZXF1aXJlZCBmb3IgcG9kbWFuIG5ldHdvcmtpbmcKICAgICAgICBmaXJld2FsbGQKICAgICAgICAjIFJlcXVpcmVkIHRvIGVuYWJsZSBmaXBzCiAgICAgICAgZ3J1YmJ5CiAgICAgICAgZHJhY3V0LWZpcHMKICAgICkKCiAgICBkbmZfaW5zdGFsbF9wa2dzIGluc3RhbGxfcGtncyBcCiAgICAgICAgICAgICAgICAgICAgIHJldHJ5X3dhaXRfdGltZSBcCiAgICAgICAgICAgICAgICAgICAgICIkcGtnX3JldHJ5X2NvdW50IgoKICAgIGZpcHNfY29uZmlndXJlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTE5CiAgICBjb25maWd1cmVfbG9ncm90YXRlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0IGRpc2FibGU9U0MyMTUzCiAgICBsb2NhbCAtciBtZG1pbWFnZT0iJHtSUElNQUdFJSUvKn0vJHtNRE1JTUFHRSMqL30iCiAgICBsb2NhbCAtciBycGltYWdlPSIkUlBJTUFHRSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgZmx1ZW50Yml0X2ltYWdlPSIkRkxVRU5UQklUSU1BR0UiCiAgICAjIHZhbHVlcyBhcmUgcmVmZXJlbmNlcyB0byB2YXJpYWJsZXMsIHRoZXkgc2hvdWxkIG5vdCBiZSBkZXJlZmVyZW5jZWQgaGVyZQogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtckEgYXJvX2ltYWdlcz0oCiAgICAgICAgWyJtZG0iXT0ibWRtaW1hZ2UiCiAgICAgICAgWyJycCJdPSJycGltYWdlIgogICAgICAgIFsiZmx1ZW50Yml0Il09ImZsdWVudGJpdF9pbWFnZSIKICAgICkKCiAgICBwdWxsX2NvbnRhaW5lcl9pbWFnZXMgYXJvX2ltYWdlcwoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJhIGVuYWJsZV9wb3J0cz0oCiAgICAgICAgIyBSUCBnYXRld2F5CiAgICAgICAgIjgwL3RjcCIKICAgICAgICAiODA4MS90Y3AiCiAgICAgICAgIjQ0My90Y3AiCiAgICAgICAgIyBKSVQgc3NoCiAgICAgICAgIjIyL3RjcCIKICAgICkKCiAgICBmaXJld2FsbGRfY29uZmlndXJlIGVuYWJsZV9wb3J0cwoKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGZsdWVudGJpdF9jb25mX2ZpbGU9IltJTlBVVF0KCU5hbWUgc3lzdGVtZAoJVGFnIGpvdXJuYWxkCglTeXN0ZW1kX0ZpbHRlciBfQ09NTT1hcm8KCURCIC92YXIvbGliL2ZsdWVudC9qb3VybmFsZGIKCltGSUxURVJdCglOYW1lIG1vZGlmeQoJTWF0Y2ggam91cm5hbGQKCVJlbW92ZV93aWxkY2FyZCBfCglSZW1vdmUgVElNRVNUQU1QCgpbT1VUUFVUXQoJTmFtZSBmb3J3YXJkCglNYXRjaCAqCglQb3J0IDI5MjMwIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX2dhdGV3YXlfY29uZl9maWxlPSJBQ1JfUkVTT1VSQ0VfSUQ9JyRBQ1JSRVNPVVJDRUlEJwpEQVRBQkFTRV9BQ0NPVU5UX05BTUU9JyREQVRBQkFTRUFDQ09VTlROQU1FJwpNRE1fQUNDT1VOVD0nJFJQTURNQUNDT1VOVCcKTURNX05BTUVTUEFDRT0nJHtyb2xlX2dhdGV3YXlefScKR0FURVdBWV9ET01BSU5TPSckR0FURVdBWURPTUFJTlMnCkdBVEVXQVlfRkVBVFVSRVM9JyRHQVRFV0FZRkVBVFVSRVMnClJQSU1BR0U9JyRycGltYWdlJyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kc2RfY29uZmlnX3ZlcnNpb249IiRHQVRFV0FZTURTRENPTkZJR1ZFUlNJT04iCgogICAgIyB2YWx1ZXMgYXJlIHJlZmVyZW5jZXMgdG8gdmFyaWFibGVzLCB0aGV5IHNob3VsZCBub3QgYmUgZGVyZWZlcmVuY2VkIGhlcmUKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJBIGFyb19jb25maWdzPSgKICAgICAgICBbImdhdGV3YXlfY29uZmlnIl09ImFyb19nYXRld2F5X2NvbmZfZmlsZSIKICAgICAgICBbImZsdWVudGJpdCJdPSJmbHVlbnRiaXRfY29uZl9maWxlIgogICAgICAgIFsibWRzZCJdPSJtZHNkX2NvbmZpZ192ZXJzaW9uIgogICAgKQoKICAgIGNvbmZpZ3VyZV92bXNzX2Fyb19zZXJ2aWNlcyByb2xlX2dhdGV3YXkgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyb19pbWFnZXMgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyb19jb25maWdzCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgZ2F0ZXdheV9zZXJ2aWNlcz0oCiAgICAgICAgImFyby1nYXRld2F5IgogICAgICAgICJhenNlY2QiCiAgICAgICAgIm1kc2QiCiAgICAgICAgIm1kbSIKICAgICAgICAiY2hyb255ZCIKICAgICAgICAiZmx1ZW50Yml0IgogICAgICAgICJkb3dubG9hZC1tZHNkLWNyZWRlbnRpYWxzLnRpbWVyIgogICAgICAgICJkb3dubG9hZC1tZG0tY3JlZGVudGlhbHMudGltZXIiCiAgICAgICAgImZpcmV3YWxsZCIKICAgICkKCiAgICBlbmFibGVfc2VydmljZXMgZ2F0ZXdheV9zZXJ2aWNlcwoKICAgIHJlYm9vdF92bQp9CgpleHBvcnQgQVpVUkVfQ0xPVURfTkFNRT0iJHtBWlVSRUNMT1VETkFNRTo/IkZhaWxlZCB0byBjYXJyeSBvdmVyIHZhcmlhYmxlcyJ9IgoKIyB1dGlsLnNoIGRvZXMgbm90IGV4aXN0IHdoZW4gZGVwbG95ZWQgdG8gVk1TUyB2aWEgVk1TUyBleHRlbnNpb25zCiMgUHJvdmlkZXMgc2hlbGxjaGVjayBkZWZpbml0aW9ucwp1dGlsPSJ1dGlsLnNoIgppZiBbIC1mICIkdXRpbCIgXTsgdGhlbgogICAgIyBzaGVsbGNoZWNrIHNvdXJjZT11dGlsLnNoCiAgICBzb3VyY2UgIiR1dGlsIgpmaQoKbWFpbiAiJEAiCg==')))]" + "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'ACRRESOURCEID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('acrResourceId')),''')\n','AZURECLOUDNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureCloudName')),''')\n','AZURESECPACKQUALYSURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackQualysUrl')),''')\n','AZURESECPACKVSATENANTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackVSATenantId')),''')\n','DATABASEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('databaseAccountName')),''')\n','MDMFRONTENDURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdmFrontendUrl')),''')\n','MDSDENVIRONMENT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdsdEnvironment')),''')\n','FLUENTBITIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fluentbitImage')),''')\n','GATEWAYMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayMdsdConfigVersion')),''')\n','GATEWAYDOMAINS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayDomains')),''')\n','GATEWAYFEATURES=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayFeatures')),''')\n','KEYVAULTDNSSUFFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultDNSSuffix')),''')\n','KEYVAULTPREFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultPrefix')),''')\n','RPIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpImage')),''')\n','RPMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdmAccount')),''')\n','RPMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdAccount')),''')\n','RPMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdNamespace')),''')\n','MDMIMAGE=''/distroless/genevamdm:2.2024.626.1539-d1a6e7-20240715t0935@sha256:372fbc981bbfdf2b9a9d0ffdca2c51ed389b291a3bcff0401e9afb0c01605823''\n','LOCATION=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().location),''')\n','SUBSCRIPTIONID=$(base64 -d \u003c\u003c\u003c''',base64(subscription().subscriptionId),''')\n','RESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().name),''')\n','\n',base64ToString('IyEvYmluL2Jhc2gKIyBJbnRlcm5hbCBGdW5jdGlvbnMgYW5kIENvbnN0YW50cwoKIyBlbXB0eV9zdHIgLSBjb25zdGFudDsgdXNlZCBieSBmdW5jdGlvbnMgZm9yIG9wdGlvbmFsIG5hbWVyZWYgc3RyaW5nIGFyZ3VlbWVudHMKIyBlbXB0eV9zdHI9IiIKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CmRlY2xhcmUgLXIgZW1wdHlfc3RyPSIiCgojIHJvbGVfZ2F0ZXdheSAtIGNvbnN0YW50OyBJcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHRoaXMgc2hvdWxkIGJlIHJlZmVyZW5jZWQgYnkgc2NyaXB0cyBzb3VyY2luZyB0aGlzIGZpbGUKIyByb2xlX2dhdGV3YXk9ImdhdGV3YXkiCmRlY2xhcmUgLXIgcm9sZV9nYXRld2F5PSJnYXRld2F5IgojIHJvbGVfcnAgLSBjb25zdGFudDsgSXMgdXNlZCB0byBkZXRlcm1pbmUgd2hpY2ggVk1TUyBpcyBiZWluZyBib290c3RyYXBwZWQKIyB0aGlzIHNob3VsZCBiZSByZWZlcmVuY2VkIGJ5IHNjcmlwdHMgc291cmNpbmcgdGhpcyBmaWxlCiMgcm9sZV9ycD0icnAiCmRlY2xhcmUgLXIgcm9sZV9ycD0icnAiCiMgcm9sZV9kZXZwcm94eSAtIGNvbnN0YW50OyBJcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHJvbGVfZGV2cHJveHk9ImRldnByb3h5IgpkZWNsYXJlIC1yIHJvbGVfZGV2cHJveHk9ImRldnByb3h5IgoKIyBsb2cgaXMgYSB3cmFwcGVyIGZvciBlY2hvIHRoYXQgaW5jbHVkZXMgdGhlIGZ1bmN0aW9uIG5hbWUKIyBBcmdzCiMgMSkgbXNnIC0gc3RyaW5nCiMgMikgc3RhY2tfbGV2ZWwgLSBpbnQ7IG9wdGlvbmFsLCBkZWZhdWx0cyB0byB0aGUgZnVuY3Rpb24gYXQgdGhlIGJvdHRvbSBvZiB0aGUgY2FsbCBzdGFjawpsb2coKSB7CiAgICBsb2NhbCAtciBtc2c9IiR7MTotImxvZyBtZXNzYWdlIGlzIGVtcHR5In0iCiAgICBsb2NhbCAtciBzdGFja19sZXZlbD0iJHsyOi0xfSIKICAgIGVjaG8gIiR7RlVOQ05BTUVbJHtzdGFja19sZXZlbH1dfTogJHttc2d9Igp9CgojIGFib3J0IGlzIGEgd3JhcHBlciBmb3IgbG9nIHRoYXQgZXhpdHMgd2l0aCBhbiBlcnJvciBjb2RlCmFib3J0KCkgewogICAgbG9jYWwgLXJpIG9yaWdpbl9zdGFja2xldmVsPTIKICAgIGxvZyAiJHsxfSIgIiRvcmlnaW5fc3RhY2tsZXZlbCIKICAgIGxvZyAiRXhpdGluZyIKICAgIGV4aXQgMQp9CgojIHdyaXRlX2ZpbGUKIyBBcmdzCiMgMSkgZmlsZW5hbWUgLSBzdHJpbmcKIyAyKSBmaWxlX2NvbnRlbnRzIC0gc3RyaW5nCiMgMykgY2xvYmJlciAtIGJvb2xlYW47IG9wdGlvbmFsIC0gZGVmYXVsdHMgdG8gZmFsc2UKd3JpdGVfZmlsZSgpIHsKICAgIGxvY2FsIC1uIGZpbGVuYW1lPSIkMSIKICAgIGxvY2FsIC1uIGZpbGVfY29udGVudHM9IiQyIgogICAgbG9jYWwgLXIgY2xvYmJlcj0iJHszOi1mYWxzZX0iCgogICAgaWYgJGNsb2JiZXI7IHRoZW4KICAgICAgICBsb2cgIk92ZXJ3cml0aW5nIGZpbGUgJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+ICIkZmlsZW5hbWUiCiAgICBlbHNlCiAgICAgICAgbG9nICJBcHBlbmRpbmcgdG8gJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+PiAiJGZpbGVuYW1lIgogICAgZmkKfQoKIyByZXRyeSBBZGRpbmcgcmV0cnkgbG9naWMgdG8geXVtIGNvbW1hbmRzIGluIG9yZGVyIHRvIGF2b2lkIHN0YWxsaW5nIG91dCBvbiByZXNvdXJjZSBsb2NrcwojIGFyZ3M6CiMgMSkgY21kX3JldHJ5IC0gbmFtZXJlZiwgYXJyYXk7IENvbW1hbmQgYW5kIGFyZ3VlbWVudChzKSB0byByZXRyeQojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CnJldHJ5KCkgewogICAgbG9jYWwgLW4gY21kX3JldHJ5PSIkMSIKICAgIGxvY2FsIC1uIHdhaXRfdGltZT0iJDIiCiAgICBsb2NhbCAtcmkgcmV0cmllcz0iJHszOi01fSIKCiAgICAKICAgIGZvciBhdHRlbXB0IGluICQoc2VxIDEgJHJldHJpZXMpOyBkbwogICAgICAgIGxvZyAiYXR0ZW1wdCAjJHthdHRlbXB0fSAtICR7RlVOQ05BTUVbMl19IgogICAgICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgICAgICR7Y21kX3JldHJ5W0BdfSAmCgogICAgICAgIHdhaXQgLWYgJCEgJiYgcmV0dXJuIDAKICAgICAgICBzbGVlcCAiJHdhaXRfdGltZSIKICAgIGRvbmUKCiAgICBhYm9ydCAiJHtjbWRfcmV0cnlbKl19IGZhaWxlZCBhZnRlciAjJHJldHJpZXMgYXR0ZW1wdHMiCn0KCiMgdmVyaWZ5X3JvbGUKIyBhcmdzOgojIDEpIHRlc3Rfcm9sZSAtIG5hbWVyZWY7IHJvbGUgYmVpbmcgdmVyaWZpZWQKdmVyaWZ5X3JvbGUoKSB7CiAgICBsb2NhbCAtbiB0ZXN0X3JvbGU9IiQxIgoKICAgIGFsbG93ZWRfcm9sZXNfZ2xvYj0iKCRyb2xlX3JwfCRyb2xlX2dhdGV3YXl8JHJvbGVfZGV2cHJveHkpIgogICAgaWYgW1sgIiR0ZXN0X3JvbGUiID1+ICRhbGxvd2VkX3JvbGVzX2dsb2IgXV07IHRoZW4KICAgICAgICBsb2cgIlZlcmlmaWVkIHJvbGUgXCIkdGVzdF9yb2xlXCIiCiAgICBlbHNlCiAgICAgICAgYWJvcnQgImZhaWxlZCB0byB2ZXJpZnkgcm9sZSwgcm9sZSBcIiR7dGVzdF9yb2xlfVwiIG5vdCBpbiBcIiR7YWxsb3dlZF9yb2xlc19nbG9ifVwiIgogICAgZmkKfQoKIyBnZXRfa2V5dmF1bHRfc3VmZml4CiMgYXJnczoKIyAxKSBybCAtIG5hbWVyZWYsIHN0cmluZzsgcm9sZSB0byBnZXQgc2hvcnQgcm9sZSBmb3IKIyAyKSBrdl9zdWZmaXggLSBuYW1lcmVmLCBzdHJpbmc7IHNob3J0IHJvbGUgd2lsbCBiZSBhc3NpZ25lZCB0byB0aGlzIG5hbWVyZWYKIyAzKSBzZWNfcHJlZml4IC0gbmFtZXJlZiwgc3RyaW5nOyBrZXl2YXVsdCBjZXJ0aWZpY2F0ZSBwcmVmaXggd2lsbCBiZSBhc3NpZ25lZCB0byB0aGlzIG5hbWVyZWYKZ2V0X2tleXZhdWx0X3N1ZmZpeCgpIHsKICAgIGxvY2FsIC1uIHJsPSIkMSIKICAgIGxvY2FsIC1uIGt2X3N1ZmZpeD0iJDIiCiAgICBsb2NhbCAtbiBzZWNfcHJlZml4PSIkMyIKCiAgICBsb2NhbCAtciBrZXl2YXVsdF9zdWZmaXhfcnA9InN2YyIKICAgIGxvY2FsIC1yIGtleXZhdWx0X3ByZWZpeF9nYXRld2F5PSJnd3kiCgogICAgY2FzZSAiJHJsIiBpbgogICAgICAgICIkcm9sZV9nYXRld2F5IikKICAgICAgICAgICAga3Zfc3VmZml4PSIka2V5dmF1bHRfcHJlZml4X2dhdGV3YXkiCiAgICAgICAgICAgIHNlY19wcmVmaXg9IiRrZXl2YXVsdF9wcmVmaXhfZ2F0ZXdheSIKICAgICAgICAgICAgOzsKICAgICAgICAiJHJvbGVfcnAiKQogICAgICAgICAgICBrdl9zdWZmaXg9IiRrZXl2YXVsdF9zdWZmaXhfcnAiCiAgICAgICAgICAgIHNlY19wcmVmaXg9IiRyb2xlX3JwIgogICAgICAgICAgICA7OwogICAgICAgICopCiAgICAgICAgICAgIGFib3J0ICJ1bmtvd24gcm9sZSAkcmwiCiAgICAgICAgICAgIDs7CiAgICBlc2FjCn0KCiMgcmVib290X3ZtIHJlc3RvcmVzIGNhbGxzIHNodXRkb3duIC1yIGluIGEgc3Vic2hlbGwKIyBSZWJvb3RzIHNob3VsZCBzY2hlZHVsZWQgYWZ0ZXIgYWxsIFZNIGV4dGVuc2lvbnMgaGF2ZSBoYWQgdGltZSB0byBjb21wbGV0ZQojIFJlZmVyZW5jZTogaHR0cHM6Ly9sZWFybi5taWNyb3NvZnQuY29tL2VuLXVzL2F6dXJlL3ZpcnR1YWwtbWFjaGluZXMvZXh0ZW5zaW9ucy9jdXN0b20tc2NyaXB0LWxpbnV4I3RpcHMKcmVib290X3ZtKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICAoc2h1dGRvd24gLXIgbm93ICYpCn0KIyEvYmluL2Jhc2gKIyBSZXBvc2l0b3J5IGFuZCBwYWNrYWdlIG1hbmFnZW1lbnQgcmVsYXRlZCBmdW5jdGlvbnMKCmNvbmZpZ3VyZV9yZXBvX21hcmluZXJfZXh0ZW5kZWQoKSB7CiAgICBsb2NhbCAtciBleHRlbmRlZF9yZXBvX2NvbmZpZz0iaHR0cHM6Ly9wYWNrYWdlcy5taWNyb3NvZnQuY29tL2NibC1tYXJpbmVyLzIuMC9wcm9kL2V4dGVuZGVkL3g4Nl82NC9jb25maWcucmVwbyIKICAgIGN1cmwgLXNTTCAiJGV4dGVuZGVkX3JlcG9fY29uZmlnIiAtbyAvZXRjL3l1bS5yZXBvcy5kL21hcmluZXItZXh0ZW5kZWQucmVwbwoKICAgIGxvY2FsIC1yIHJlcG9fbmFtZT0iY2JsLW1hcmluZXIyLjBwcm9kZXh0ZW5kZWR4ODZfNjQiCgogICAgbG9jYWwgLXJhIGNtZD0oCiAgICAgICAgZG5mCiAgICAgICAgdXBkYXRlCiAgICAgICAgLXkKICAgICAgICAtLWVuYWJsZXJlcG89IiRyZXBvX25hbWUiCiAgICApCgogICAgbG9nICJFbmFibGluZyByZXBvICRyZXBvX25hbWUiCiAgICByZXRyeSBjbWQgIiQxIiAiJHsyOi19Igp9CgojIGNvbmZpZ3VyZV9ycG1fcmVwb3MKIyBOZXcgcmVwb3NpdG9yaWVzIHNob3VsZCBiZSBhZGRlZCBpbiB0aGVpciBvd24gZnVuY3Rpb25zLCBhbmQgY2FsbGVkIGhlcmUKIyBhcmdzOgojIDEpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDIpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1vdW50IG9mIHRpbWVzIHRvIHJldHJ5IGNvbW1hbmQsIGRlZmF1bHRzIHRvIDUKY29uZmlndXJlX3JwbV9yZXBvcygpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgY29uZmlndXJlX3JlcG9fbWFyaW5lcl9leHRlbmRlZCAiJDEiICIkezI6LTF9Igp9CgojIGRuZl9pbnN0YWxsX3BrZ3MKIyBhcmdzOgojIDEpIHBrZ3MgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IFBhY2thZ2VzIHRvIGJlIGluc3RhbGxlZAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1vdW50IG9mIHRpbWVzIHRvIHJldHJ5IGNvbW1hbmQsIGRlZmF1bHRzIHRvIDUKZG5mX2luc3RhbGxfcGtncygpIHsKICAgIGxvY2FsIC1uIHBrZ3M9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgIGRuZgogICAgICAgIC15CiAgICAgICAgaW5zdGFsbAogICAgKQogICAgCiAgICAjIFJlZmVyZW5jZTogaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIyMDYKICAgICMgYXBwZW5kIHBrZ3MgYXJyYXkgdG8gY21kCiAgICBtYXBmaWxlIC1PICQoKCAkeyNjbWRbQF19ICsgMSApKSAtZCAnICcgY21kIDw8PCAiJHtwa2dzW0BdfSIKICAgIGxvY2FsIC1yIGNtZAoKICAgIGxvZyAiQXR0ZW1wdGluZyB0byBpbnN0YWxsIHBhY2thZ2VzOiAke3BrZ3NbKl19IgogICAgcmV0cnkgY21kICIkMiIgIiR7MzotfSIKfQoKCiMgZG5mX3VwZGF0ZV9wa2dzCiMgYXJnczoKIyAxKSBleGNsdWRlcyAtIG5hbWVyZWYsIHN0cmluZyBhcnJheSwgb3B0aW9uYWw7IFBhY2thZ2VzIHRvIGV4Y2x1ZGUgZnJvbSB1cGRhdGluZwojICAgICAgIEVhY2ggaW5kZXggbXVzdCBiZSBwcmVmaXhlZCB3aXRoIC14IAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CmRuZl91cGRhdGVfcGtncygpIHsKICAgIGxvY2FsIC1uIGV4Y2x1ZGVzPSIkezE6LWVtcHR5X3N0cn0iCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGxvY2FsIC1hIGNtZD0oCiAgICAgICAgZG5mCiAgICAgICAgLXkKICAgICAgICAjIFJlcGxhY2VkIHdpdGggZXhjbHVkZXMKICAgICAgICAiIgogICAgICAgIHVwZGF0ZQogICAgICAgIC0tYWxsb3dlcmFzaW5nCiAgICApCgogICAgaWYgWyAtbiAiJHtleGNsdWRlc30iIF07IHRoZW4KICAgICAgICAjIFJlZmVyZW5jZSBodHRwczovL3d3dy5zaGVsbGNoZWNrLm5ldC93aWtpL1NDMjIwNgogICAgICAgIG1hcGZpbGUgLU8gMiBjbWQgPDw8ICIke2V4Y2x1ZGVzW0BdfSIKICAgIGVsc2UKICAgICAgICAjIFJlbW92ZSBlbXB0eSBzdHJpbmcgaWYgd2UgYXJlbid0IHJlcGxhY2luZyB0aGVtLCBwcm9iYWJseSBkb2Vzbid0IG1hdHRlciwgYnV0IHdoeSBub3QgYmUgc2FmZQogICAgICAgIHVuc2V0ICJjbWRbMl0iCiAgICBmaQogICAgbG9jYWwgLXIgY21kCgogICAgbG9nICJVcGRhdGluZyBhbGwgcGFja2FnZXMgZXhjbHVkaW5nIFwiJHtleGNsdWRlc1sqXTotfVwiIgogICAgcmV0cnkgY21kICIkMiIgIiR7MzotfSIKfQoKIyBycG1faW1wb3J0X2tleXMKIyBhcmdzOgojIDEpIGtleXMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IHJwbSBrZXlzIHRvIGJlIGltcG9ydGVkCiMgMikgd2FpdF90aW1lIC0gbmFtZXJlZiwgaW50ZWdlcjsgVGltZSB0byB3YWl0IGJlZm9yZSByZXRyeWluZyBjb21tYW5kCnJwbV9pbXBvcnRfa2V5cygpIHsKICAgIGxvY2FsIC1uIGtleXM9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBrZXkgaW4gJHtrZXlzW0BdfTsgZG8KICAgICAgICBpZiBbICR7I2tleXNbQF19IC1lcSAwIF07IHRoZW4KICAgICAgICAgICAgYnJlYWsKICAgICAgICBmaQoKICAgICAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgICAgICBycG0KICAgICAgICAgICAgLS1pbXBvcnQKICAgICAgICAgICAgLXYKICAgICAgICAgICAgIiRrZXkiCiAgICAgICAgKQoKICAgICAgICBsb2cgIkltcG9ydGluZyBycG0gcmVwb3NpdG9yeSBrZXkgJGtleSIKICAgICAgICByZXRyeSBjbWQgIiQyIiAiJHszOi19IiAmJiB1bnNldCBrZXkKICAgIGRvbmUKfQoKIyB1dGlsLWNvbW1vbi5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQojIS9iaW4vYmFzaAojIEFSTyBzZXJ2aWNlIHNldHVwIGZ1bmN0aW9ucwoKIyBlbmFibGVfc2VydmljZXMgZW5hYmxlcyB0aGUgc3lzdGVtZCBzZXJ2aWNlcyB0aGF0IGFyZSBwYXNzZWQgaW4KIyBhcmdzOgojIDEpIHNlcnZpY2VzIC0gYXJyYXk7IHNlcnZpY2VzIHRvIGJlIGVuYWJsZWQKZW5hYmxlX3NlcnZpY2VzKCkgewogICAgbG9jYWwgLW4gc3Zjcz0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHN5c3RlbWN0bCBkYWVtb24tcmVsb2FkCgogICAgbG9nICJlbmFibGluZyBzZXJ2aWNlcyAke3N2Y3NbKl19IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3Igc3ZjIGluICR7c3Zjc1tAXX07IGRvCiAgICAgICAgbG9nICJFbmFibGluZyBhbmQgc3RhcnRpbmcgJHN2YyBub3ciCiAgICAgICAgc3lzdGVtY3RsIGVuYWJsZSBcCiAgICAgICAgICAgICAgICAgIC0tbm93IFwKICAgICAgICAgICAgICAgICAgIiRzdmMiCiAgICBkb25lCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBjb250YWluZXIgaW1hZ2UKIyAyKSByb2xlIC0gbmFtZXJlZiwgc3RyaW5nOyBWTVNTIHJvbGUKIyAzKSBjb25mX2ZpbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGFybyBnYXRld2F5IGVudmlyb25tZW50IGZpbGUKIyA0KSBpcGFkZHJlc3MgLSBuYW1lcmVmLCBzdHJpbmc7IHN0YXRpYyBpcCBvZiBwb2RtYW4gbmV0d29yayB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9hcm9fZ2F0ZXdheSgpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIHJvbGU9IiQyIgogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMyIKICAgIGxvY2FsIC1uIGlwYWRkcmVzcz0iJDQiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tZ2F0ZXdheSBzZXJ2aWNlIgoKICAgIGxvY2FsIC1yIGFyb19nYXRld2F5X2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1nYXRld2F5JwogICAgbG9jYWwgLXIgYWRkX2NvbmZfZmlsZT0icG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJwpST0xFPScke3JvbGUsLH0nIgoKICAgIHdyaXRlX2ZpbGUgYXJvX2dhdGV3YXlfY29uZl9maWxlbmFtZSBjb25mX2ZpbGUgdHJ1ZQogICAgd3JpdGVfZmlsZSBhcm9fZ2F0ZXdheV9jb25mX2ZpbGVuYW1lIGFkZF9jb25mX2ZpbGUgZmFsc2UKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19nYXRld2F5X3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLWdhdGV3YXkuc2VydmljZScKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19nYXRld2F5X3NlcnZpY2VfZmlsZT0nW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLWdhdGV3YXkKRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtZSBBQ1JfUkVTT1VSQ0VfSUQgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX0ZFQVRVUkVTIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLW0gMmcgXAogIC0tbmV0d29yaz0ke1BPRE1BTl9ORVRXT1JLfSBcCiAgLS1pcCAke0lQQUREUkVTU30gXAogIC1wIDgwOjgwODAgXAogIC1wIDgwODE6ODA4MSBcCiAgLXAgNDQzOjg0NDMgXAogIC12IC9ydW4vc3lzdGVtZC9qb3VybmFsOi9ydW4vc3lzdGVtZC9qb3VybmFsIFwKICAtdiAvdmFyL2V0dzovdmFyL2V0dzp6IFwKICAkUlBJTUFHRSBcCiAgJFJPTEUKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgLXQgMzYwMCAlTgpUaW1lb3V0U3RvcFNlYz0zNjAwClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAnCgogICAgd3JpdGVfZmlsZSBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19nYXRld2F5X3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX3JwCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCiMgMikgcm9sZSAtIG5hbWVyZWYsIHN0cmluZzsgVk1TUyByb2xlCiMgMykgY29uZl9maWxlIC0gbmFtZXJlZiwgc3RyaW5nOyBhcm8gcnAgZW52aXJvbm1lbnQgZmlsZQojIDQpIGlwYWRkcmVzcyAtIG5hbWVyZWYsIHN0cmluZzsgc3RhdGljIGlwIG9mIHBvZG1hbiBuZXR3b3JrIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19ycCgpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIHJvbGU9IiQyIgogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMyIKICAgIGxvY2FsIC1uIGlwYWRkcmVzcz0iJDQiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tcnAgc2VydmljZSIKCiAgICBsb2NhbCAtciBhcm9fcnBfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLXJwJwogICAgbG9jYWwgLXIgYWRkX2NvbmZfZmlsZT0icG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJwpST0xFPScke3JvbGUsLH0nIgoKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX2NvbmZfZmlsZW5hbWUgY29uZl9maWxlIHRydWUKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX2NvbmZfZmlsZW5hbWUgYWRkX2NvbmZfZmlsZSBmYWxzZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3JwX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLXJwLnNlcnZpY2UnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19ycF9zZXJ2aWNlX2ZpbGU9J1tVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2Fyby1ycApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC1lIEFDUl9SRVNPVVJDRV9JRCBcCiAgLWUgQURNSU5fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FIFwKICAtZSBBUk1fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FIFwKICAtZSBBWlVSRV9BUk1fQ0xJRU5UX0lEIFwKICAtZSBBWlVSRV9GUF9DTElFTlRfSUQgXAogIC1lIENMVVNURVJfTURNX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURNX05BTUVTUEFDRSBcCiAgLWUgQ0xVU1RFUl9NRFNEX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTiBcCiAgLWUgQ0xVU1RFUl9NRFNEX05BTUVTUEFDRSBcCiAgLWUgREFUQUJBU0VfQUNDT1VOVF9OQU1FIFwKICAtZSBET01BSU5fTkFNRSBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX1JFU09VUkNFR1JPVVAgXAogIC1lIEtFWVZBVUxUX1BSRUZJWCBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1lIE1EU0RfRU5WSVJPTk1FTlQgXAogIC1lIFJQX0ZFQVRVUkVTIFwKICAtZSBBUk9fSU5TVEFMTF9WSUFfSElWRSBcCiAgLWUgQVJPX0hJVkVfREVGQVVMVF9JTlNUQUxMRVJfUFVMTFNQRUMgXAogIC1lIEFST19BRE9QVF9CWV9ISVZFIFwKICAtZSBPSURDX0FGRF9FTkRQT0lOVCBcCiAgLWUgT0lEQ19TVE9SQUdFX0FDQ09VTlRfTkFNRSBcCiAgLWUgTVNJX1JQX0VORFBPSU5UIFwKICAtZSBNSVNFX0FERFJFU1MgXAogIC1tIDJnIFwKICAtLW5ldHdvcms9JHtQT0RNQU5fTkVUV09SS30gXAogIC0taXAgJHtJUEFERFJFU1N9IFwKICAtcCA0NDM6ODQ0MyBcCiAgLXYgL2V0Yy9hcm8tcnA6L2V0Yy9hcm8tcnAgXAogIC12IC9ydW4vc3lzdGVtZC9qb3VybmFsOi9ydW4vc3lzdGVtZC9qb3VybmFsIFwKICAtdiAvdmFyL2V0dzovdmFyL2V0dzp6IFwKICAkUlBJTUFHRSBcCiAgJFJPTEUKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgLXQgMzYwMCAlTgpUaW1lb3V0U3RvcFNlYz0zNjAwClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0JwoKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX3NlcnZpY2VfZmlsZW5hbWUgYXJvX3JwX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX21vbml0b3IKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBSUCBjb250YWluZXIgaW1hZ2UKIyAyKSBpcGFkZHJlc3MgLSBuYW1lcmVmLCBzdHJpbmc7IHN0YXRpYyBpcCBvZiBwb2RtYW4gbmV0d29yayB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9hcm9fbW9uaXRvcigpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIGlwYWRkcmVzcz0iJDIiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tbW9uaXRvciBzZXJ2aWNlIgoKICAgICMgRE9NQUlOX05BTUUsIENMVVNURVJfTURTRF9BQ0NPVU5ULCBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04sIEdBVEVXQVlfRE9NQUlOUywgR0FURVdBWV9SRVNPVVJDRUdST1VQLCBNRFNEX0VOVklST05NRU5UIENMVVNURVJfTURTRF9OQU1FU1BBQ0UKICAgICMgYXJlIG5vdCB1c2VkLCBidXQgY2FuJ3QgZWFzaWx5IGJlIHJlZmFjdG9yZWQgb3V0LiBTaG91bGQgYmUgcmV2aXNpdGVkIGluIHRoZSBmdXR1cmUuCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLW1vbml0b3InCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlPSJBWlVSRV9GUF9DTElFTlRfSUQ9JyRGUENMSUVOVElEJwpET01BSU5fTkFNRT0nJExPQ0FUSU9OLiRDTFVTVEVSUEFSRU5URE9NQUlOTkFNRScKQ0xVU1RFUl9NRFNEX0FDQ09VTlQ9JyRDTFVTVEVSTURTREFDQ09VTlQnCkNMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTj0nJENMVVNURVJNRFNEQ09ORklHVkVSU0lPTicKR0FURVdBWV9ET01BSU5TPSckR0FURVdBWURPTUFJTlMnCkdBVEVXQVlfUkVTT1VSQ0VHUk9VUD0nJEdBVEVXQVlSRVNPVVJDRUdST1VQTkFNRScKTURTRF9FTlZJUk9OTUVOVD0nJE1EU0RFTlZJUk9OTUVOVCcKQ0xVU1RFUl9NRFNEX05BTUVTUEFDRT0nJENMVVNURVJNRFNETkFNRVNQQUNFJwpDTFVTVEVSX01ETV9BQ0NPVU5UPSckQ0xVU1RFUk1ETUFDQ09VTlQnCkNMVVNURVJfTURNX05BTUVTUEFDRT1CQk0KREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPUJCTQpSUElNQUdFPSckaW1hZ2UnCnBvZG1hbl9uZXR3b3JrPSdwb2RtYW4nCklQQUREUkVTUz0nJGlwYWRkcmVzcyciCgogICAgd3JpdGVfZmlsZSBhcm9fbW9uaXRvcl9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX21vbml0b3Jfc2VydmljZV9jb25mX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21vbml0b3Jfc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9hcm8tbW9uaXRvci5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbW9uaXRvcl9zZXJ2aWNlX2ZpbGU9J1tVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2Fyby1tb25pdG9yCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLS1uZXR3b3JrPSR7UE9ETUFOX05FVFdPUkt9IFwKICAtLWlwICR7SVBBRERSRVNTfSBcCiAgLWUgQVpVUkVfRlBfQ0xJRU5UX0lEIFwKICAtZSBET01BSU5fTkFNRSBcCiAgLWUgQ0xVU1RFUl9NRFNEX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTiBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX1JFU09VUkNFR1JPVVAgXAogIC1lIE1EU0RfRU5WSVJPTk1FTlQgXAogIC1lIENMVVNURVJfTURTRF9OQU1FU1BBQ0UgXAogIC1lIENMVVNURVJfTURNX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURNX05BTUVTUEFDRSBcCiAgLWUgREFUQUJBU0VfQUNDT1VOVF9OQU1FIFwKICAtZSBLRVlWQVVMVF9QUkVGSVggXAogIC1lIE1ETV9BQ0NPVU5UIFwKICAtZSBNRE1fTkFNRVNQQUNFIFwKICAtbSAyLjVnIFwKICAtdiAvcnVuL3N5c3RlbWQvam91cm5hbDovcnVuL3N5c3RlbWQvam91cm5hbCBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJFJQSU1BR0UgXAogIG1vbml0b3IKUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz0xClN0YXJ0TGltaXRJbnRlcnZhbD0wCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQnCgogICAgd3JpdGVfZmlsZSBhcm9fbW9uaXRvcl9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX3BvcnRhbAojIGFyZ3M6CiMgMSkgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IFJQIGNvbnRhaW5lciBpbWFnZQojIDIpIGlwYWRkcmVzcyAtIG5hbWVyZWYsIHN0cmluZzsgc3RhdGljIGlwIG9mIHBvZG1hbiBuZXR3b3JrIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19wb3J0YWwoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiBpcGFkZHJlc3M9IiQyIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgYXJvIHBvcnRhbCBzZXJ2aWNlIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1wb3J0YWwnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19wb3J0YWxfc2VydmljZV9jb25mX2ZpbGU9IkFaVVJFX1BPUlRBTF9BQ0NFU1NfR1JPVVBfSURTPSckUE9SVEFMQUNDRVNTR1JPVVBJRFMnCkFaVVJFX1BPUlRBTF9DTElFTlRfSUQ9JyRQT1JUQUxDTElFTlRJRCcKQVpVUkVfUE9SVEFMX0VMRVZBVEVEX0dST1VQX0lEUz0nJFBPUlRBTEVMRVZBVEVER1JPVVBJRFMnCkRBVEFCQVNFX0FDQ09VTlRfTkFNRT0nJERBVEFCQVNFQUNDT1VOVE5BTUUnCktFWVZBVUxUX1BSRUZJWD0nJEtFWVZBVUxUUFJFRklYJwpNRE1fQUNDT1VOVD0nJFJQTURNQUNDT1VOVCcKTURNX05BTUVTUEFDRT1Qb3J0YWwKUE9SVEFMX0hPU1ROQU1FPSckTE9DQVRJT04uYWRtaW4uJFJQUEFSRU5URE9NQUlOTkFNRScKUlBJTUFHRT0nJGltYWdlJwpwb2RtYW5fbmV0d29yaz0ncG9kbWFuJwpJUEFERFJFU1M9JyRpcGFkZHJlc3MnIgoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLXBvcnRhbC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZT0nW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKU3RhcnRMaW1pdEludGVydmFsPTAKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC0tbmV0d29yaz0ke1BPRE1BTl9ORVRXT1JLfSBcCiAgLS1pcCAke0lQQUREUkVTU30gXAogIC1lIEFaVVJFX1BPUlRBTF9BQ0NFU1NfR1JPVVBfSURTIFwKICAtZSBBWlVSRV9QT1JUQUxfQ0xJRU5UX0lEIFwKICAtZSBBWlVSRV9QT1JUQUxfRUxFVkFURURfR1JPVVBfSURTIFwKICAtZSBEQVRBQkFTRV9BQ0NPVU5UX05BTUUgXAogIC1lIEtFWVZBVUxUX1BSRUZJWCBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1lIFBPUlRBTF9IT1NUTkFNRSBcCiAgLW0gMmcgXAogIC1wIDQ0NDo4NDQ0IFwKICAtcCAyMjIyOjIyMjIgXAogIC12IC9ydW4vc3lzdGVtZC9qb3VybmFsOi9ydW4vc3lzdGVtZC9qb3VybmFsIFwKICAtdiAvdmFyL2V0dzovdmFyL2V0dzp6IFwKICAkUlBJTUFHRSBcCiAgcG9ydGFsClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0JwoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19wb3J0YWxfc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9hcm9fbWlzZQojIGFyZ3M6CiMgMSkgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IE1JU0UgY29udGFpbmVyIGltYWdlCiMgMikgaXBhZGRyZXNzIC0gbmFtZXJlZiwgc3RyaW5nOyBzdGF0aWMgaXAgb2YgcG9kbWFuIG5ldHdvcmsgdG8gYmUgYXR0YWNoZWQKY29uZmlndXJlX3NlcnZpY2VfYXJvX21pc2UoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiBpcGFkZHJlc3M9IiQyIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgYXJvLW1pc2Ugc2VydmljZSIKCiAgICBMT0dJTklOU1RBTkNFPSJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20iCiAgICBpZiBbWyAkQVpVUkVDTE9VRE5BTUUgPT0gIkF6dXJlVVNHb3Zlcm5tZW50IiBdXTsgdGhlbgogICAgICAgIExPR0lOSU5TVEFOQ0U9Imh0dHBzOi8vbG9naW4ubWljcm9zb2Z0b25saW5lLnVzIgogICAgZmkKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21pc2Vfc2VydmljZV9jb25mX2ZpbGVuYW1lPScvZXRjL3N5c2NvbmZpZy9hcm8tbWlzZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21pc2Vfc2VydmljZV9jb25mX2ZpbGU9IkZQQ0xJRU5USUQ9JyRGUENMSUVOVElEJwpGUFRFTkFOVElEPSckRlBURU5BTlRJRCcKTUlTRUlNQUdFPSckaW1hZ2UnCk1JU0VWQUxJREFVRElFTkNFUz0nJE1JU0VWQUxJREFVRElFTkNFUycKTUlTRVZBTElEQVBQSURTPSckTUlTRVZBTElEQVBQSURTJwpMT0dJTklOU1RBTkNFPSckTE9HSU5JTlNUQU5DRScKcG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJyIKCiAgICB3cml0ZV9maWxlIGFyb19taXNlX3NlcnZpY2VfY29uZl9maWxlbmFtZSBhcm9fbWlzZV9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgbWtkaXIgLXAgL2FwcC9taXNlCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19taXNlX2FwcHNldHRpbmdzX2ZpbGVuYW1lPScvYXBwL21pc2UvYXBwc2V0dGluZ3MuanNvbicKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21pc2VfYXBwc2V0dGluZ3NfZmlsZT0iewogICAgXCJWZXJzaW9uXCI6IFwiMVwiLAogICAgXCJIZWFydGJlYXRJbnRlcnZhbE1zXCI6IDUwMDAsCiAgICBcIkF6dXJlQWRcIjogewogICAgICAgIFwiSW5zdGFuY2VcIjogXCIkTE9HSU5JTlNUQU5DRVwiLAogICAgICAgIFwiQ2xpZW50SWRcIjogXCIkRlBDTElFTlRJRFwiLAogICAgICAgIFwiVGVuYW50SWRcIjogXCIkRlBURU5BTlRJRFwiLAogICAgICAgIFwiQXVkaWVuY2VcIjogXCJhcGk6Ly8kRlBDTElFTlRJRFwiLAogICAgICAgIFwiU2hvd1BJSVwiOiBmYWxzZSwKICAgICAgICBcIkluYm91bmRQb2xpY2llc1wiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFwiTGFiZWxcIjogXCJhcm9ycC1hcm0taW5ib3VuZC1wb2xpY3lcIiwKICAgICAgICAgICAgICAgIFwiQXV0aG9yaXR5XCI6IFwiJExPR0lOSU5TVEFOQ0UvJEZQVEVOQU5USUQvXCIKLAogICAgICAgICAgICAgICAgXCJBdXRoZW50aWNhdGlvblNjaGVtZXNcIjogWwogICAgICAgICAgICAgICAgICAgIFwiUG9QXCIKICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICBcIlZhbGlkQXVkaWVuY2VzXCI6ICRNSVNFVkFMSURBVURJRU5DRVMsCiAgICAgICAgICAgICAgICBcIlNpZ25lZEh0dHBSZXF1ZXN0VmFsaWRhdGlvblBvbGljeVwiOiB7CiAgICAgICAgICAgICAgICAgICAgXCJWYWxpZGF0ZVRzXCI6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgXCJWYWxpZGF0ZU1cIjogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBcIlZhbGlkYXRlVVwiOiB0cnVlLAogICAgICAgICAgICAgICAgICAgIFwiVmFsaWRhdGVQXCI6IHRydWUKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBcIlZhbGlkQXBwbGljYXRpb25JZHNcIjogJE1JU0VWQUxJREFQUElEUwogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICBcIkxvZ2dpbmdcIjogewogICAgICAgICAgICBcIkxvZ0xldmVsXCI6IFwiSW5mb3JtYXRpb25cIgogICAgICAgIH0sCiAgICAgICAgXCJNb2R1bGVzXCI6IHsKICAgICAgICAgICAgXCJUclYyXCI6IHsKICAgICAgICAgICAgICAgIFwiTW9kdWxlVHlwZVwiOiBcIlRyVjJNb2R1bGVcIiwKICAgICAgICAgICAgICAgIFwiRW5hYmxlZFwiOiB0cnVlCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgXCJBbGxvd2VkSG9zdHNcIjogXCIqXCIsCiAgICBcIktlc3RyZWxcIjogewogICAgICAgIFwiRW5kcG9pbnRzXCI6IHsKICAgICAgICAgICAgXCJIdHRwXCI6IHsKICAgICAgICAgICAgICAgIFwiVXJsXCI6IFwiaHR0cDovLyRpcGFkZHJlc3M6NTAwMFwiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgXCJMb2dnaW5nXCI6IHsKICAgICAgICBcIkxvZ0xldmVsXCI6IHsKICAgICAgICAgICAgXCJEZWZhdWx0XCI6IFwiSW5mb3JtYXRpb25cIiwKICAgICAgICAgICAgXCJNaWNyb3NvZnRcIjogXCJJbmZvcm1hdGlvblwiLAogICAgICAgICAgICBcIk1pY3Jvc29mdC5Ib3N0aW5nLkxpZmV0aW1lXCI6IFwiSW5mb3JtYXRpb25cIgogICAgICAgIH0KICAgIH0KfSIKCiAgICB3cml0ZV9maWxlIGFyb19taXNlX2FwcHNldHRpbmdzX2ZpbGVuYW1lIGFyb19taXNlX2FwcHNldHRpbmdzX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21pc2Vfc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9hcm8tbWlzZS5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbWlzZV9zZXJ2aWNlX2ZpbGU9J1tVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0ClN0YXJ0TGltaXRJbnRlcnZhbFNlYz0wCltTZXJ2aWNlXQpSZXN0YXJ0U2VjPTFzCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9hcm8tbWlzZQpFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLXAgNTAwMDo1MDAwIFwKICAtdiAvYXBwL21pc2UvYXBwc2V0dGluZ3MuanNvbjovYXBwL2FwcHNldHRpbmdzLmpzb246eiBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLW5ldHdvcms9JHtQT0RNQU5fTkVUV09SS30gXAogIC0taXAgJHtJUEFERFJFU1N9IFwKICAtLXJtIFwKICAkTUlTRUlNQUdFCkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MwpTdGFydExpbWl0SW50ZXJ2YWw9MApbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQnCgogICAgd3JpdGVfZmlsZSBhcm9fbWlzZV9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19taXNlX3NlcnZpY2VfZmlsZSB0cnVlCn0KIyBjb25maWd1cmVfc2VydmljZV9hcm9fb3RlbF9jb2xsZWN0b3IKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBPVEVMIGNvbnRhaW5lciBpbWFnZQojIDIpIHN0YXRpY19pcF9hZGRyZXNzIC0gbmFtZXJlZiwgYXJyYXk7IHN0YXRpYyBpcHMgb2YgYWxsIHNlcnZpY2VzCiMgMykgaXBhZGRyZXNzIC0gbmFtZXJlZiwgc3RyaW5nOyBzdGF0aWMgaXAgb2YgcG9kbWFuIG5ldHdvcmsgdG8gYmUgYXR0YWNoZWQKY29uZmlndXJlX3NlcnZpY2VfYXJvX290ZWxfY29sbGVjdG9yKCkgewogICAgbG9jYWwgLW4gaW1hZ2U9IiQxIgogICAgbG9jYWwgLW4gc3RhdGljX2lwX2FkZHJlc3M9IiQyIgogICAgbG9jYWwgLW4gaXBhZGRyZXNzPSIkMyIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIGFyby1vdGVsLWNvbGxlY3RvciBzZXJ2aWNlIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX290ZWxfY29sbGVjdG9yX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLW90ZWwtY29sbGVjdG9yJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fb3RlbF9jb2xsZWN0b3Jfc2VydmljZV9jb25mX2ZpbGU9IkdPTUVNTElNSVQ9MTAwME1pQgpPVEVMSU1BR0U9JyRpbWFnZScKcG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJyIKCiAgICB3cml0ZV9maWxlIGFyb19vdGVsX2NvbGxlY3Rvcl9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX290ZWxfY29sbGVjdG9yX3NlcnZpY2VfY29uZl9maWxlIHRydWUKCiAgICBta2RpciAtcCAvYXBwL290ZWwKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX290ZWxfY29sbGVjdG9yX2FwcGNvbmZpZ19maWxlbmFtZT0nL2FwcC9vdGVsL2NvbmZpZy55YW1sJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fb3RlbF9jb2xsZWN0b3JfYXBwY29uZmlnX2ZpbGU9InJlY2VpdmVyczoKICBodHRwY2hlY2s6CiAgICB0YXJnZXRzOgogICAgIyBNSVNFIEVuZHBvaW50cwogICAgICAtIGVuZHBvaW50OiBodHRwOi8vJHtzdGF0aWNfaXBfYWRkcmVzc1sibWlzZSJdfTo1MDAwL2hlYWx0aHoKICAgICAgICBtZXRob2Q6IEdFVAogICAgICAtIGVuZHBvaW50OiBodHRwOi8vJHtzdGF0aWNfaXBfYWRkcmVzc1sibWlzZSJdfTo1MDAwL3JlYWR5egogICAgICAgIG1ldGhvZDogR0VUCiAgICAjIE9URUxzIG93biBFbmRwb2ludHMKICAgICAgLSBlbmRwb2ludDogaHR0cDovLyRpcGFkZHJlc3M6MTMxMzMvaGVhbHRoegogICAgICAgIG1ldGhvZDogR0VUCiAgICAgIC0gZW5kcG9pbnQ6IGh0dHA6Ly8kaXBhZGRyZXNzOjEzMTMzL3JlYWR5egogICAgICAgIG1ldGhvZDogR0VUCiAgICBjb2xsZWN0aW9uX2ludGVydmFsOiAyMHMKcHJvY2Vzc29yczoKICBiYXRjaDoKZXh0ZW5zaW9uczoKICBoZWFsdGhfY2hlY2s6CiAgICBlbmRwb2ludDogJGlwYWRkcmVzczoxMzEzMwpleHBvcnRlcnM6CiAgb3RscDoKICAgIGVuZHBvaW50OiAke3N0YXRpY19pcF9hZGRyZXNzWyJtZG0iXX06NDMxNwogICAgdGxzOgogICAgICBpbnNlY3VyZTogdHJ1ZQpzZXJ2aWNlOgogIGV4dGVuc2lvbnM6IFtoZWFsdGhfY2hlY2tdCiAgcGlwZWxpbmVzOgogICAgbWV0cmljczoKICAgICAgcmVjZWl2ZXJzOiBbaHR0cGNoZWNrXQogICAgICBwcm9jZXNzb3JzOiBbYmF0Y2hdCiAgICAgIGV4cG9ydGVyczogW290bHBdIgoKICAgIHdyaXRlX2ZpbGUgYXJvX290ZWxfY29sbGVjdG9yX2FwcGNvbmZpZ19maWxlbmFtZSBhcm9fb3RlbF9jb2xsZWN0b3JfYXBwY29uZmlnX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX290ZWxfY29sbGVjdG9yX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLW90ZWwtY29sbGVjdG9yLnNlcnZpY2UnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19vdGVsX2NvbGxlY3Rvcl9zZXJ2aWNlX2ZpbGU9J1tVbml0XQpBZnRlcj1tZG0uc2VydmljZQpXYW50cz1tZG0uc2VydmljZQpTdGFydExpbWl0SW50ZXJ2YWxTZWM9MApbU2VydmljZV0KUmVzdGFydFNlYz0xcwpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLW90ZWwtY29sbGVjdG9yCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tbmV0d29yaz0ke1BPRE1BTl9ORVRXT1JLfSBcCiAgLS1pcCAkSVBBRERSRVNTIFwKICAtbSAyZyBcCiAgLXYgL2FwcC9vdGVsL2NvbmZpZy55YW1sOi9ldGMvb3RlbGNvbC1jb250cmliL2NvbmZpZy55YW1sOnogXAogICRPVEVMSU1BR0UKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgJU4KUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz0zClN0YXJ0TGltaXRJbnRlcnZhbD0wCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCcKCiAgICB3cml0ZV9maWxlIGFyb19vdGVsX2NvbGxlY3Rvcl9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19vdGVsX2NvbGxlY3Rvcl9zZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX21kc2QKIyBhcmdzOgojIDEpIG1vbml0b3Jpbmdfcm9sZSAtIG5hbWVyZWYsIHN0cmluZzsgY2FuIGJlICJnYXRld2F5IiBvciAicnAiCiMgMikgbW9uaXRvcl9jb25maWdfdmVyc2lvbiAtIG5hbWVyZWYsIHN0cmluZzsgbWRzZCBjb25maWcgdmVyc2lvbgpjb25maWd1cmVfc2VydmljZV9tZHNkKCkgewogICAgbG9jYWwgLW4gcm9sZT0iJDEiCiAgICBsb2NhbCAtbiBtb25pdG9yX2NvbmZpZ192ZXJzaW9uPSIkMiIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgImNvbmZpZ3VyaW5nIG1kc2Qgc2VydmljZSIKCiAgICB2ZXJpZnlfcm9sZSByb2xlCgogICAgbG9jYWwgLXIgbWRzZF9zZXJ2aWNlX2Rpcj0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9tZHNkLnNlcnZpY2UuZCIKICAgIG1rZGlyIC1wICIkbWRzZF9zZXJ2aWNlX2RpciIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kc2Rfb3ZlcnJpZGVfY29uZl9maWxlbmFtZT0iJG1kc2Rfc2VydmljZV9kaXIvb3ZlcnJpZGUuY29uZiIKICAgIGxvY2FsIC1yIG1kc2RfY2VydGlmaWNhdGVfc2FuPSIkKG9wZW5zc2wgeDUwOSAtaW4gL3Zhci9saWIvd2FhZ2VudC9NaWNyb3NvZnQuQXp1cmUuS2V5VmF1bHQuU3RvcmUvbWRzZC5wZW0gLW5vb3V0IC1zdWJqZWN0IHwgc2VkIC1lICdzLy4qQ04gPSAvLycpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZHNkX292ZXJyaWRlX2NvbmZfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIG1kc2Rfb3ZlcnJpZGVfY29uZl9maWxlbmFtZSBtZHNkX292ZXJyaWRlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBkZWZhdWx0X21kc2RfZmlsZW5hbWU9Ii9ldGMvZGVmYXVsdC9tZHNkIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBkZWZhdWx0X21kc2RfZmlsZT0iTURTRF9ST0xFX1BSRUZJWD0vdmFyL3J1bi9tZHNkL2RlZmF1bHQKTURTRF9PUFRJT05TPVwiLUEgLWQgLXIgXCRNRFNEX1JPTEVfUFJFRklYXCIKCmV4cG9ydCBNT05JVE9SSU5HX0dDU19FTlZJUk9OTUVOVD0nJE1EU0RFTlZJUk9OTUVOVCcKZXhwb3J0IE1PTklUT1JJTkdfR0NTX0FDQ09VTlQ9JyRSUE1EU0RBQ0NPVU5UJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfUkVHSU9OPSckTE9DQVRJT04nCmV4cG9ydCBNT05JVE9SSU5HX0dDU19BVVRIX0lEX1RZUEU9QXV0aEtleVZhdWx0CmV4cG9ydCBNT05JVE9SSU5HX0dDU19BVVRIX0lEPSckbWRzZF9jZXJ0aWZpY2F0ZV9zYW4nCmV4cG9ydCBNT05JVE9SSU5HX0dDU19OQU1FU1BBQ0U9JyRSUE1EU0ROQU1FU1BBQ0UnCmV4cG9ydCBNT05JVE9SSU5HX0NPTkZJR19WRVJTSU9OPSckbW9uaXRvcl9jb25maWdfdmVyc2lvbicKZXhwb3J0IE1PTklUT1JJTkdfVVNFX0dFTkVWQV9DT05GSUdfU0VSVklDRT10cnVlCgpleHBvcnQgTU9OSVRPUklOR19URU5BTlQ9JyRMT0NBVElPTicKZXhwb3J0IE1PTklUT1JJTkdfUk9MRT0nJHJvbGUnCmV4cG9ydCBNT05JVE9SSU5HX1JPTEVfSU5TVEFOQ0U9XCIkKGhvc3RuYW1lKVwiCgpleHBvcnQgTURTRF9NU0dQQUNLX1NPUlRfQ09MVU1OUz1cIjFcIiIKCiAgICB3cml0ZV9maWxlIGRlZmF1bHRfbWRzZF9maWxlbmFtZSBkZWZhdWx0X21kc2RfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfZmx1ZW50Yml0CiMgYXJnczoKIyAxKSBjb25mX2ZpbGUgLSBzdHJpbmc7IGZsdWVuYml0IGNvbmZpZ3VyYXRpb24gZmlsZQojIDIpIGltYWdlIC0gc3RyaW5nOyBmbHVlbnRiaXQgY29udGFpbmVyIGltYWdlIHRvIHJ1bgojIDMpIGlwYWRkcmVzcyAtIG5hbWVyZWYsIHN0cmluZzsgc3RhdGljIGlwIG9mIHBvZG1hbiBuZXR3b3JrIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdCgpIHsKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvY2FsIC1uIGlwYWRkcmVzcz0iJDMiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBmbHVlbnRiaXQgc2VydmljZSIKCiAgICBta2RpciAtcCAvZXRjL2ZsdWVudGJpdC8KICAgIG1rZGlyIC1wIC92YXIvbGliL2ZsdWVudAoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgY29uZl9maWxlbmFtZT0nL2V0Yy9mbHVlbnRiaXQvZmx1ZW50Yml0LmNvbmYnCiAgICB3cml0ZV9maWxlIGNvbmZfZmlsZW5hbWUgY29uZl9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHN5c2NvbmZpZ19maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvZmx1ZW50Yml0JwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzeXNjb25maWdfZmlsZT0iRkxVRU5UQklUSU1BR0U9JGltYWdlCnBvZG1hbl9uZXR3b3JrPSdwb2RtYW4nCklQQUREUkVTUz0nJGlwYWRkcmVzcyciCgogICAgd3JpdGVfZmlsZSBzeXNjb25maWdfZmlsZW5hbWUgc3lzY29uZmlnX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9mbHVlbnRiaXQuc2VydmljZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc2VydmljZV9maWxlPSdbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldApTdGFydExpbWl0SW50ZXJ2YWxTZWM9MAoKW1NlcnZpY2VdClJlc3RhcnRTZWM9MXMKRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2ZsdWVudGJpdApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1zZWN1cml0eS1vcHQgbGFiZWw9ZGlzYWJsZSBcCiAgLS1lbnRyeXBvaW50IC9vcHQvdGQtYWdlbnQtYml0L2Jpbi90ZC1hZ2VudC1iaXQgXAogIC0tbmV0d29yaz0ke1BPRE1BTl9ORVRXT1JLfSBcCiAgLS1pcCAke0lQQUREUkVTU30gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtdiAvZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZjovZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZiBcCiAgLXYgL3Zhci9saWIvZmx1ZW50Oi92YXIvbGliL2ZsdWVudDp6IFwKICAtdiAvdmFyL2xvZy9qb3VybmFsOi92YXIvbG9nL2pvdXJuYWw6cm8gXAogIC12IC9ldGMvbWFjaGluZS1pZDovZXRjL21hY2hpbmUtaWQ6cm8gXAogICRGTFVFTlRCSVRJTUFHRSBcCiAgLWMgL2V0Yy9mbHVlbnRiaXQvZmx1ZW50Yml0LmNvbmYKCkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9NQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0JwoKICAgIHdyaXRlX2ZpbGUgc2VydmljZV9maWxlbmFtZSBzZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV90aW1lcnNfbWRtX21kc2QKIyBhcmdzOgojIDEpIHJvbGUgLSBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgpjb25maWd1cmVfdGltZXJzX21kbV9tZHNkKCkgewogICAgbG9jYWwgLW4gcm9sZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICBsb2NhbCBrZXl2YXVsdF9zdWZmaXggc2VjcmV0X3ByZWZpeAogICAgZ2V0X2tleXZhdWx0X3N1ZmZpeCByb2xlIGtleXZhdWx0X3N1ZmZpeCBzZWNyZXRfcHJlZml4CgogICAgZm9yIHZhciBpbiAibWRzZCIgIm1kbSI7IGRvCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9kb3dubG9hZC0kdmFyLWNyZWRlbnRpYWxzLnNlcnZpY2UiCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlPSJbVW5pdF0KRGVzY3JpcHRpb249UGVyaW9kaWMgJHZhciBjcmVkZW50aWFscyByZWZyZXNoCgpbU2VydmljZV0KVHlwZT1vbmVzaG90CkV4ZWNTdGFydD0vdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaCAkdmFyIgoKICAgICAgICB3cml0ZV9maWxlIGRvd25sb2FkX2NyZWRzX3NlcnZpY2VfZmlsZW5hbWUgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlIHRydWUKCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfdGltZXJfZmlsZW5hbWU9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vZG93bmxvYWQtJHZhci1jcmVkZW50aWFscy50aW1lciIKICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlPSJbVW5pdF0KRGVzY3JpcHRpb249UGVyaW9kaWMgJHZhciBjcmVkZW50aWFscyByZWZyZXNoCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltUaW1lcl0KT25Cb290U2VjPTBtaW4KT25DYWxlbmRhcj0wLzEyOjAwOjAwCkFjY3VyYWN5U2VjPTVzCgpbSW5zdGFsbF0KV2FudGVkQnk9dGltZXJzLnRhcmdldCIKCiAgICAgICAgd3JpdGVfZmlsZSBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlbmFtZSBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlIHRydWUKICAgIGRvbmUKCiAgICBsb2NhbCAtciBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWU9Ii91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZT0iIyEvYmluL2Jhc2gKc2V0IC1ldQoKQ09NUE9ORU5UPVwkMQplY2hvIFwiRG93bmxvYWQgXCRDT01QT05FTlQgY3JlZGVudGlhbHNcIgoKVEVNUF9ESVI9XCJcJChta3RlbXAgLWQpXCIKZXhwb3J0IEFaVVJFX0NPTkZJR19ESVI9XCJcJChta3RlbXAgLWQpXCIKCmVjaG8gXCJMb2dnaW5nIGludG8gQXp1cmUuLi5cIgpSRVRSSUVTPTMKd2hpbGUgW1sgXCRSRVRSSUVTIC1ndCAwIF1dOyBkbwogICAgaWYgYXogbG9naW4gLWkgLS1hbGxvdy1uby1zdWJzY3JpcHRpb25zCiAgICB0aGVuCiAgICAgICAgZWNobyBcImF6IGxvZ2luIHN1Y2Nlc3NmdWxcIgogICAgICAgIGJyZWFrCiAgICBlbHNlCiAgICAgICAgZWNobyBcImF6IGxvZ2luIGZhaWxlZC4gUmV0cnlpbmcuLi5cIgogICAgICAgIGxldCBSRVRSSUVTLT0xCiAgICAgICAgc2xlZXAgNQogICAgZmkKZG9uZQoKdHJhcCBcImNsZWFudXBcIiBFWElUCgpjbGVhbnVwKCkgewogIGF6IGxvZ291dAogIFtbIFwkVEVNUF9ESVIgPX4gL3RtcC8uKyBdXSAmJiBybSAtcmYgXCRURU1QX0RJUgogIFtbIFwkQVpVUkVfQ09ORklHX0RJUiA9fiAvdG1wLy4rIF1dICYmIHJtIC1yZiBcJEFaVVJFX0NPTkZJR19ESVIKfQoKaWYgW1sgXCRDT01QT05FTlQgPSBcIm1kbVwiIF1dOyB0aGVuCiAgQ1VSUkVOVF9DRVJUX0ZJTEU9XCIvZXRjL21kbS5wZW1cIgplbGlmIFtbIFwkQ09NUE9ORU5UID0gXCJtZHNkXCIgXV07IHRoZW4KICBDVVJSRU5UX0NFUlRfRklMRT1cIi92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlL21kc2QucGVtXCIKZWxzZQogIGVjaG8gSW52YWxpZCB1c2FnZSAmJiBleGl0IDEKZmkKClNFQ1JFVF9OQU1FPVwiJHNlY3JldF9wcmVmaXgtXCR7Q09NUE9ORU5UfVwiCk5FV19DRVJUX0ZJTEU9XCJcJFRFTVBfRElSL1wkQ09NUE9ORU5ULnBlbVwiCmZvciBhdHRlbXB0IGluIHsxLi41fTsgZG8KICBheiBrZXl2YXVsdCBcCiAgICBzZWNyZXQgXAogICAgZG93bmxvYWQgXAogICAgLS1maWxlIFwiXCRORVdfQ0VSVF9GSUxFXCIgXAogICAgLS1pZCBcImh0dHBzOi8vJEtFWVZBVUxUUFJFRklYLSRrZXl2YXVsdF9zdWZmaXguJEtFWVZBVUxURE5TU1VGRklYL3NlY3JldHMvXCRTRUNSRVRfTkFNRVwiIFwKICAgICYmIGJyZWFrCiAgaWYgW1sgXCRhdHRlbXB0IC1sdCA1IF1dOyB0aGVuIHNsZWVwIDEwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKaWYgWyAtZiBcJE5FV19DRVJUX0ZJTEUgXTsgdGhlbgogIGlmIFtbIFwkQ09NUE9ORU5UID0gXCJtZHNkXCIgXV07IHRoZW4KICAgIGNob3duIHN5c2xvZzpzeXNsb2cgXCRORVdfQ0VSVF9GSUxFCiAgZWxzZQogICAgc2VkIC1pIC1uZSAnMSwvRU5EIENFUlRJRklDQVRFLyBwJyBcJE5FV19DRVJUX0ZJTEUKICBmaQoKICBuZXdfY2VydF9zbj1cIlwkKG9wZW5zc2wgeDUwOSAtaW4gXCJcJE5FV19DRVJUX0ZJTEVcIiAtbm9vdXQgLXNlcmlhbCB8IGF3ayAtRj0gJ3twcmludCBcJDJ9JylcIgogIGN1cnJlbnRfY2VydF9zbj1cIlwkKG9wZW5zc2wgeDUwOSAtaW4gXCJcJENVUlJFTlRfQ0VSVF9GSUxFXCIgLW5vb3V0IC1zZXJpYWwgfCBhd2sgLUY9ICd7cHJpbnQgXCQyfScpXCIKICBpZiBbWyAhIC16IFwkbmV3X2NlcnRfc24gXV0gJiYgW1sgXCRuZXdfY2VydF9zbiAhPSBcIlwkY3VycmVudF9jZXJ0X3NuXCIgXV07IHRoZW4KICAgIGVjaG8gdXBkYXRpbmcgY2VydGlmaWNhdGUgZm9yIFwkQ09NUE9ORU5UCiAgICBjaG1vZCAwNjAwIFwkTkVXX0NFUlRfRklMRQogICAgbXYgXCRORVdfQ0VSVF9GSUxFIFwkQ1VSUkVOVF9DRVJUX0ZJTEUKICBmaQplbHNlCiAgZWNobyBGYWlsZWQgdG8gcmVmcmVzaCBjZXJ0aWZpY2F0ZSBmb3IgXCRDT01QT05FTlQgJiYgZXhpdCAxCmZpIgoKICAgIHdyaXRlX2ZpbGUgZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGVuYW1lIGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlIHRydWUKCiAgICBjaG1vZCB1K3ggL3Vzci9sb2NhbC9iaW4vZG93bmxvYWQtY3JlZGVudGlhbHMuc2gKCiAgICAkZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGVuYW1lIG1kc2QgJgogICAgd2FpdCAiJCEiCgoKICAgICRkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWUgbWRtICYKICAgIHdhaXQgIiQhIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3NlcnZpY2VfZmlsZW5hbWU9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnNlcnZpY2UiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkc19zZXJ2aWNlX2ZpbGU9IltVbml0XQpEZXNjcmlwdGlvbj1XYXRjaCBmb3IgY2hhbmdlcyBpbiBtZG0ucGVtIGFuZCByZXN0YXJ0cyB0aGUgbWRtIHNlcnZpY2UKCltTZXJ2aWNlXQpUeXBlPW9uZXNob3QKRXhlY1N0YXJ0PS91c3IvYmluL3N5c3RlbWN0bCByZXN0YXJ0IG1kbS5zZXJ2aWNlCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQiCgogICAgd3JpdGVfZmlsZSB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlbmFtZSB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGVuYW1lPScvdXNyL2xpYi9zeXN0ZW1kL3N5c3RlbS93YXRjaC1tZG0tY3JlZGVudGlhbHMucGF0aCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZT0nW1BhdGhdClBhdGhNb2RpZmllZD0vZXRjL21kbS5wZW0KCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCcKCiAgICB3cml0ZV9maWxlIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGVuYW1lIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGUgdHJ1ZQoKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkcz0nd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnBhdGgnCiAgICBzeXN0ZW1jdGwgZW5hYmxlIC0tbm93ICIkd2F0Y2hfbWRtX2NyZWRzIiB8fCBhYm9ydCAiZmFpbGVkIHRvIGVuYWJsZSBhbmQgc3RhcnQgJHdhdGNoX21kbV9jcmVkcyIKfQoKIyBjb25maWd1cmVfc2VydmljZV9tZG0KIyBhcmdzOgojIDEpIHJvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgojIDIpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBtZG0gY29udGFpbmVyIGltYWdlIHRvIHJ1bgojIDMpIGlwYWRkcmVzcyAtIG5hbWVyZWYsIHN0cmluZzsgc3RhdGljIGlwIG9mIHBvZG1hbiBuZXR3b3JrIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX21kbSgpIHsKICAgIGxvY2FsIC1uIHJvbGU9IiQxIgogICAgbG9jYWwgLW4gaW1hZ2U9IiQyIgogICAgbG9jYWwgLW4gaXBhZGRyZXNzPSIkMyIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIG1kbSBzZXJ2aWNlIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHN5c2NvbmZpZ19tZG1fZmlsZW5hbWU9Ii9ldGMvc3lzY29uZmlnL21kbSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX21kbV9maWxlPSJNRE1GUk9OVEVORFVSTD0nJE1ETUZST05URU5EVVJMJwpNRE1JTUFHRT0nJGltYWdlJwpNRE1TT1VSQ0VFTlZJUk9OTUVOVD0nJExPQ0FUSU9OJwpNRE1TT1VSQ0VST0xFPSckcm9sZScKTURNU09VUkNFUk9MRUlOU1RBTkNFPVwiJChob3N0bmFtZSlcIgpNRE1fSU5QVVQ9c3RhdHNkX2xvY2FsLG90bHBfZ3JwYwpNRE1fTkFNRVNQQUNFPSdPVEVMJwpNRE1fQUNDT1VOVD0nQXp1cmVSZWRIYXRPcGVuU2hpZnRSUCcKcG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJyIKCiAgICB3cml0ZV9maWxlIHN5c2NvbmZpZ19tZG1fZmlsZW5hbWUgc3lzY29uZmlnX21kbV9maWxlIHRydWUKCiAgICBta2RpciAtcCAvdmFyL2V0dwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZG1fc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9tZG0uc2VydmljZSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRtX3NlcnZpY2VfZmlsZT0nW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvbWRtCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWVudHJ5cG9pbnQgL3Vzci9zYmluL01ldHJpY3NFeHRlbnNpb24gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtLW5ldHdvcms9JHtQT0RNQU5fTkVUV09SS30gXAogIC0taXAgJHtJUEFERFJFU1N9IFwKICAtbSAyZyBcCiAgLXYgL2V0Yy9tZG0ucGVtOi9ldGMvbWRtLnBlbSBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJE1ETUlNQUdFIFwKICAtSW5wdXQgJE1ETV9JTlBVVCBcCiAgLU1ldHJpY05hbWVzcGFjZSAkTURNX05BTUVTUEFDRSBcCiAgLU1vbml0b3JpbmdBY2NvdW50ICRNRE1fQUNDT1VOVCBcCiAgLUNlcnRGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLUZyb250RW5kVXJsICRNRE1GUk9OVEVORFVSTCBcCiAgLUxvZ2dlciBDb25zb2xlIFwKICAtTG9nTGV2ZWwgV2FybmluZyBcCiAgLVByaXZhdGVLZXlGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLVNvdXJjZUVudmlyb25tZW50ICRNRE1TT1VSQ0VFTlZJUk9OTUVOVCBcCiAgLVNvdXJjZVJvbGUgJE1ETVNPVVJDRVJPTEUgXAogIC1Tb3VyY2VSb2xlSW5zdGFuY2UgJE1ETVNPVVJDRVJPTEVJTlNUQU5DRQpFeGVjU3RvcD0vdXNyL2Jpbi9wb2RtYW4gc3RvcCAlTgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCcKCiAgICB3cml0ZV9maWxlIG1kbV9zZXJ2aWNlX2ZpbGVuYW1lIG1kbV9zZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV92bXNzX2Fyb19zZXJ2aWNlCiMgYXJnczoKIyAxKSByIC0gbmFtZXJlZiwgc3RyaW5nOyByb2xlIG9mIFZNU1MKIyAyKSBpbWFnZXMgLSBuYW1lcmVmLCBhc3NvY2lhdGl2ZSBhcnJheTsgQVJPIGNvbnRhaW5lciBpbWFnZXMKIyAzKSBjb25maWdzIC0gbmFtZXJlZiwgYXNzb2NpYXRpdmUgYXJyYXk7IGNvbmZpZ3VyYXRpb24gZmlsZXMgYW5kIHZlcnNpb25zLiBUaGUgdmFsdWVzIHNob3VsZCBiZSBhIHJlZmVyZW5jZSB0byB2YXJpYWJsZXMsIG5vdCBkZXJlZmVyZW5jZWQuCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGlzIGJlY2F1c2UgdGhlIHZhbHVlIGlzIHVzZWQgd2hlbiBjcmVhdGluZyBuYW1lcmVmIHZhcmlhYmxlcyBieSBoZWxwZXIgZnVuY3Rpb25zLgpjb25maWd1cmVfdm1zc19hcm9fc2VydmljZXMoKSB7CiAgICBsb2NhbCAtbiByPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlcz0iJDIiCiAgICBsb2NhbCAtbiBjb25maWdzPSIkMyIKICAgIGxvZyAic3RhcnRpbmciCiAgICB2ZXJpZnlfcm9sZSAiJDEiCgogICAgaWYgWyAiJHIiID09ICIkcm9sZV9nYXRld2F5IiBdOyB0aGVuCiAgICAgICAgY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkgIiR7aW1hZ2VzWyJycCJdfSIgIiQxIiAiJHtjb25maWdzWyJnYXRld2F5X2NvbmZpZyJdfSIgIiR7Y29uZmlnc1sic3RhdGljX2lwX2FkZHJlc3MiXX1bImdhdGV3YXkiXSIKICAgICAgICBjb25maWd1cmVfY2VydHNfZ2F0ZXdheQogICAgZWxpZiBbICIkciIgPT0gIiRyb2xlX3JwIiBdOyB0aGVuCiAgICAgICAgY29uZmlndXJlX3NlcnZpY2VfYXJvX3JwICIke2ltYWdlc1sicnAiXX0iICIkMSIgIiR7Y29uZmlnc1sicnBfY29uZmlnIl19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfVsicnAiXSIKICAgICAgICBjb25maWd1cmVfc2VydmljZV9hcm9fbW9uaXRvciAiJHtpbWFnZXNbInJwIl19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfVsibW9uaXRvciJdIgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19wb3J0YWwgIiR7aW1hZ2VzWyJycCJdfSIgIiR7Y29uZmlnc1sic3RhdGljX2lwX2FkZHJlc3MiXX1bInBvcnRhbCJdIgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19taXNlICIke2ltYWdlc1sibWlzZSJdfSIgIiR7Y29uZmlnc1sic3RhdGljX2lwX2FkZHJlc3MiXX1bIm1pc2UiXSIKICAgICAgICBjb25maWd1cmVfc2VydmljZV9hcm9fb3RlbF9jb2xsZWN0b3IgIiR7aW1hZ2VzWyJvdGVsIl19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfSIgIiR7Y29uZmlnc1sic3RhdGljX2lwX2FkZHJlc3MiXX1bIm90ZWxfY29sbGVjdG9yIl0iCiAgICAgICAgY29uZmlndXJlX2NlcnRzX3JwCiAgICBmaQoKICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdCAiJHtjb25maWdzWyJmbHVlbnRiaXQiXX0iICIke2ltYWdlc1siZmx1ZW50Yml0Il19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfVsiZmx1ZW50Yml0Il0iCiAgICBjb25maWd1cmVfdGltZXJzX21kbV9tZHNkICIkMSIKICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX21kbSAiJDEiICIke2ltYWdlc1sibWRtIl19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfVsibWRtIl0iCiAgICBjb25maWd1cmVfc2VydmljZV9tZHNkICIkMSIgIiR7Y29uZmlnc1sibWRzZCJdfSIKICAgIHJ1bl9henNlY2RfY29uZmlnX3NjYW4KfQoKIyB1dGlsLWNvbW1vbi5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQoKIyB1dGlsLXN5c3RlbS5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9zeXN0ZW09InV0aWwtc3lzdGVtLnNoIgppZiBbIC1mICIkdXRpbF9zeXN0ZW0iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1zeXN0ZW0uc2gKICAgIHNvdXJjZSAiJHV0aWxfc3lzdGVtIgpmaQojIS9iaW4vYmFzaAojIFRoaXMgZmlsZSBpcyBpbnRlbmRlZCB0byBiZSBzb3VyY2VkIGJ5IGJvb3RzdHJhcHBpbmcgc2NyaXB0cyBmb3IgY29tbW9ubHkgdXNlZCBmdW5jdGlvbnMKCiMgZ2V0X2Jvb3RfZGV2X3V1aWQKIyBHZXQgdGhlIGJvb3QgZGV2aWNlcyB1dWlkCiMgYXJnczoKIyAxKSBib290X2Rldl91dWlkIC0gbmFtZXJlZiwgc3RyaW5nOyBFbXB0eSB2YXJpYWJsZSBmb3IgYm9vdCBkZXZpY2UgdXVpZCBhc3NpZ25tZW50CiMgVGFrZW4gYW5kIHJlZmFjdG9yZWQgZnJvbSBodHRwczovL2VuZy5tcy9kb2NzL3Byb2R1Y3RzL2F6dXJlLWxpbnV4L2ZlYXR1cmVzL3NlY3VyaXR5L2ZpcHMKZ2V0X2Jvb3RfZGV2X3V1aWQoKSB7CiAgICBsb2NhbCAtbiBib290X2Rldl91dWlkPSIkMSIKICAgICMgU2V0IGJvb3RfdXVpZCB2YXJpYWJsZSBmb3IgdGhlIGJvb3QgcGFydGl0aW9uIGlmIGRpZmZlcmVudCBmcm9tIHRoZSByb290CiAgICBib290X2Rldj0iJChkZiAvYm9vdC8gfCB0YWlsIC0xIHwgY3V0IC1kJyAnIC1mMSkiCiAgICByb290X2Rldj0iJChkZiAvIHwgdGFpbCAtMSB8IGN1dCAtZCcgJyAtZjEpIgoKICAgIGJvb3RfZGV2X3V1aWQ9IiRyb290X2RldiIKICAgIGlmIFsgIiRib290X2RldiIgIT0gIiRyb290X2RldiIgXTsgdGhlbgogICAgICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgICAgIGJvb3RfZGV2X3V1aWQ9ImJvb3Q9VVVJRD0kKGJsa2lkICIkYm9vdF9kZXYiIC1zIFVVSUQgLW8gdmFsdWUpIgogICAgZmkKfQoKIyBmaXBzX3ZlcmlmeQojIFZlcmlmeSB0aGF0IGZpcHMgbW9kZSBpcyBlbmFibGVkCiMgVGFrZW4gYW5kIHJlZmFjdG9yZWQgZnJvbSBodHRwczovL2VuZy5tcy9kb2NzL3Byb2R1Y3RzL2F6dXJlLWxpbnV4L2ZlYXR1cmVzL3NlY3VyaXR5L2ZpcHMKZmlwc192ZXJpZnkoKSB7CiAgICBmaXBzX2VuYWJsZWRfcHJvYz0iJChjYXQgL3Byb2Mvc3lzL2NyeXB0by9maXBzX2VuYWJsZWQpIgogICAgZmlwc19lbmFibGVkX3N5c2N0bD0iJChzeXNjdGwgLW4gY3J5cHRvLmZpcHNfZW5hYmxlZCkiCiAgICBpZiBbICIkZmlwc19lbmFibGVkX3Byb2MiIC1uZSAxIF0gfHwgWyAiJGZpcHNfZW5hYmxlZF9zeXNjdGwiIC1uZSAxIF07IHRoZW4KICAgICAgICBhYm9ydCAiRklQUyBtb2RlIGlzIGRpc2FibGVkIgogICAgZmkKCiAgICBsb2cgIkZJUFMgbW9kZSBpcyBlbmFibGVkIgp9CgojIGZpcHNfY29uZmlndXJlCiMgQ29uZmlndXJlcyBWTSB0byBydW4gd2l0aCBmaXBzIG1vZGUgZW5hYmxlZAojIFRha2VuIGFuZCByZWZhY3RvcmVkIGZyb20gaHR0cHM6Ly9lbmcubXMvZG9jcy9wcm9kdWN0cy9henVyZS1saW51eC9mZWF0dXJlcy9zZWN1cml0eS9maXBzCiMgVE9ETyByZW1vdmUgdGhpcyBvbmNlIHNrdSBjYmwtbWFyaW5lci0yLWdlbjItZmlwcyBpcyBzdXBwb3J0ZWQgYnkgYXV0b21hdGljIE9TIHVwZGF0ZXMKIyBSZWZlcmVuY2U6IGh0dHBzOi8vbGVhcm4ubWljcm9zb2Z0LmNvbS9lbi11cy9henVyZS92aXJ0dWFsLW1hY2hpbmUtc2NhbGUtc2V0cy92aXJ0dWFsLW1hY2hpbmUtc2NhbGUtc2V0cy1hdXRvbWF0aWMtdXBncmFkZSNzdXBwb3J0ZWQtb3MtaW1hZ2VzCmZpcHNfY29uZmlndXJlKCkgewogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCBib290X3V1aWQKICAgIGdldF9ib290X2Rldl91dWlkIGJvb3RfdXVpZAoKICAgIGxvY2FsIGdydWIyX2VudgogICAgaWYgZ3J1YjJfZW52PSIkKGdydWIyLWVkaXRlbnYgLSBsaXN0IHwgZ3JlcCBrZXJuZWxvcHRzKSI7IHRoZW4KICAgICAgICBncnViMi1lZGl0ZW52IC0gc2V0ICIkZ3J1YjJfZW52IGZpcHM9MSAkYm9vdF91dWlkIgogICAgZWxzZQogICAgICAgIGdydWJieSAtLXVwZGF0ZS1rZXJuZWw9QUxMIC0tYXJncz0iZmlwcz0xICRib290X3V1aWQiCiAgICBmaQoKICAgICMgZmlwcyBtb2RlIHZlcmlmaWNhdGlvbiB3aWxsIGZhaWwgdW50aWwgYWZ0ZXIgdGhlIHZtIGhhcyBiZWVuIHJlYm9vdGVkCiAgICAjIGZpcHNfdmVyaWZ5Cn0KCiMgY29uZmlndXJlX3NzaGQKIyBXZSBuZWVkIHRvIGNvbmZpZ3VyZSBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIHRvIHllcyBpbiBvcmRlciBmb3IgdGhlIFZNU1MgQWNjZXNzIEpJVCB0byB3b3JrCmNvbmZpZ3VyZV9zc2hkKCkgewogICAgbG9nICJzdGFydGluZyIKICAgIGxvY2FsIC1yIHNzaGRfY29uZmlnPSIvZXRjL3NzaC9zc2hkX2NvbmZpZyIKCiAgICBsb2cgIkVkaXRpbmcgJHNzaGRfY29uZmlnIHRvIGFsbG93IHBhc3N3b3JkIGF1dGhlbnRpY2F0aW9uIgogICAgc2VkIC1pICdzL1Bhc3N3b3JkQXV0aGVudGljYXRpb24gbm8vUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB5ZXMvZycgIiRzc2hkX2NvbmZpZyIKCiAgICBzeXN0ZW1jdGwgcmVsb2FkIHNzaGQuc2VydmljZSB8fCBhYm9ydCAic3NoZCBmYWlsZWQgdG8gcmVsb2FkIgp9CgojIGNvbmZpZ3VyZV9sb2dyb3RhdGUgY2xvYmJlcnMgL2V0Yy9sb2dyb3RhdGUuY29uZgojIGFyZ3M6CiMgMSkgZHJvcGluX2ZpbGVzIC0gbmFtZXJlZiwgYXNzb2NpYXRpdmUgYXJyYXksIG9wdGlvbmFsOyBsb2dyb3RhdGUgZmlsZXMgdG8gd3JpdGUgdG8gL2V0Yy9sb2dyb3RhdGUuZAojICAgICAgIEtleSBuYW1lIGRpY3RhdGVzIGZpbGVuYW1lcyB3cml0dGVuIHRvIC9ldGMvbG9ncm90YXRlLmQuCiMgRXhhbXBsZToKIyAgIEtleSBkaWN0YXRlcyB0aGUgZmlsZW5hbWUgd3JpdHRlbiBpbiAvZXRjL2xvZ3JvdGF0ZS5kCiMgICBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiMgICBsb2NhbCAtckEgbG9ncm90YXRlX2Ryb3BpbnM9KAojICAgICAgWyJnYXRld2F5Il09IiRnYXRld2F5X2xvZ19maWxlIgojICAgKQpjb25maWd1cmVfbG9ncm90YXRlKCkgewogICAgbG9jYWwgLW4gZHJvcGluX2ZpbGVzPSIkezE6LWVtcHR5X3N0cn0iCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbG9ncm90YXRlX2NvbmZfZmlsZW5hbWU9Jy9ldGMvbG9ncm90YXRlLmNvbmYnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGxvZ3JvdGF0ZV9jb25mX2ZpbGU9JyMgc2VlICJtYW4gbG9ncm90YXRlIiBmb3IgZGV0YWlscwojIHJvdGF0ZSBsb2cgZmlsZXMgd2Vla2x5CndlZWtseQoKIyBrZWVwIDIgd2Vla3Mgd29ydGggb2YgYmFja2xvZ3MKcm90YXRlIDIKCiMgY3JlYXRlIG5ldyAoZW1wdHkpIGxvZyBmaWxlcyBhZnRlciByb3RhdGluZyBvbGQgb25lcwpjcmVhdGUKCiMgdXNlIGRhdGUgYXMgYSBzdWZmaXggb2YgdGhlIHJvdGF0ZWQgZmlsZQpkYXRlZXh0CgojIHVuY29tbWVudCB0aGlzIGlmIHlvdSB3YW50IHlvdXIgbG9nIGZpbGVzIGNvbXByZXNzZWQKY29tcHJlc3MKCiMgUlBNIHBhY2thZ2VzIGRyb3AgbG9nIHJvdGF0aW9uIGluZm9ybWF0aW9uIGludG8gdGhpcyBkaXJlY3RvcnkKaW5jbHVkZSAvZXRjL2xvZ3JvdGF0ZS5kCgojIG5vIHBhY2thZ2VzIG93biB3dG1wIGFuZCBidG1wIC0tIHdlIHdpbGwgcm90YXRlIHRoZW0gaGVyZQovdmFyL2xvZy93dG1wIHsKICAgIG1vbnRobHkKICAgIGNyZWF0ZSAwNjY0IHJvb3QgdXRtcAogICAgICAgIG1pbnNpemUgMU0KICAgIHJvdGF0ZSAxCn0KCi92YXIvbG9nL2J0bXAgewogICAgbWlzc2luZ29rCiAgICBtb250aGx5CiAgICBjcmVhdGUgMDYwMCByb290IHV0bXAKICAgIHJvdGF0ZSAxCn0nCgogICAgd3JpdGVfZmlsZSBsb2dyb3RhdGVfY29uZl9maWxlbmFtZSBsb2dyb3RhdGVfY29uZl9maWxlIHRydWUKCiAgICBpZiBbIC1uICIke2Ryb3Bpbl9maWxlc1sqXX0iIF07IHRoZW4KICAgICAgICBsb2NhbCAtciBsb2dyb3RhdGVfZD0iL2V0Yy9sb2dyb3RhdGUuZCIKICAgICAgICBsb2cgIldyaXRpbmcgbG9ncm90YXRlIGZpbGVzIHRvICRsb2dyb3RhdGVfZCIKICAgICAgICBmb3IgZHJvcGluX25hbWUgaW4gIiR7IWRyb3Bpbl9maWxlc1tAXX0iOyBkbwogICAgICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICAgICAgbG9jYWwgLXIgZHJvcGluX2ZpbGVuYW1lPSIkbG9ncm90YXRlX2QvJGRyb3Bpbl9uYW1lIgogICAgICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICAgICAgbG9jYWwgLXIgZHJvcGluX2ZpbGU9IiR7ZHJvcGluX2ZpbGVzWyIkZHJvcGluX25hbWUiXX0iCiAgICAgICAgICAgIHdyaXRlX2ZpbGUgZHJvcGluX2ZpbGVuYW1lIGRyb3Bpbl9maWxlIHRydWUKICAgICAgICBkb25lCiAgICBmaQp9CgojIHB1bGxfY29udGFpbmVyX2ltYWdlcwojIGFyZ3M6CiMgMSkgcHVsbF9pbWFnZXMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXkKIyAyKSByZWdpc3RyeV9jb25mIC0gbmFtZXJlZiwgc3RyaW5nLCBvcHRpb25hbDsgcGF0aCB0byBkb2NrZXIvcG9kbWFuIGNvbmZpZ3VyYXRpb24gZmlsZQpwdWxsX2NvbnRhaW5lcl9pbWFnZXMoKSB7CiAgICBsb2NhbCAtbiBwdWxsX2ltYWdlcz0iJDEiCiAgICBsb2NhbCAtbiByZWdpc3RyeV9jb25mPSIkezI6LWVtcHR5X3N0cn0iCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJpIHJldHJ5X3RpbWU9MzAKICAgIGNtZD0oCiAgICAgICAgYXoKICAgICAgICBsb2dpbgogICAgICAgIC1pCiAgICAgICAgLS1hbGxvdy1uby1zdWJzY3JpcHRpb25zCiAgICApCgogICAgbG9nICJSdW5uaW5nIGF6IGxvZ2luIHdpdGggcmV0cmllcyIKICAgIHJldHJ5IGNtZCByZXRyeV90aW1lCgogICAgIyBTdXBwcmVzcyBlbXVsYXRpb24gb3V0cHV0IGZvciBwb2RtYW4gaW5zdGVhZCBvZiBkb2NrZXIgZm9yIGF6IGFjciBjb21wYXRhYmlsaXR5CiAgICBta2RpciAtcCAvZXRjL2NvbnRhaW5lcnMvCiAgICBta2RpciAtcCAvcm9vdC8uZG9ja2VyCiAgICB0b3VjaCAvZXRjL2NvbnRhaW5lcnMvbm9kb2NrZXIKCiAgICAjIFRoaXMgbmFtZSBpcyB1c2VkIGluIHRoZSBjYXNlIHRoYXQgYXogYWNyIGxvZ2luIHNlYXJjaGVzIGZvciB0aGlzIGluIGl0J3MgZW52aXJvbm1lbnQKICAgIGV4cG9ydCBSRUdJU1RSWV9BVVRIX0ZJTEU9Ii9yb290Ly5kb2NrZXIvY29uZmlnLmpzb24iCgogICAgaWYgWyAtbiAiJHtyZWdpc3RyeV9jb25mfSIgXTsgdGhlbgogICAgICAgIHdyaXRlX2ZpbGUgUkVHSVNUUllfQVVUSF9GSUxFIHJlZ2lzdHJ5X2NvbmYgdHJ1ZQogICAgZmkKCiAgICBsb2cgImxvZ2dpbmcgaW50byBwcm9kIGFjciIKICAgIGNtZD0oCiAgICAgICAgYXoKICAgICAgICBhY3IKICAgICAgICBsb2dpbgogICAgICAgIC0tbmFtZQogICAgICAgICMgVE9ETyByZXBsYWNlIHRoaXMgd2l0aCB2YXJpYWJsZSBleHBhbnNpb24KICAgICAgICAjIFJlZmVyZW5jZTogaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIwMDEKICAgICAgICAiJChzZWQgLWUgJ3N8LiovfHwnIDw8PCIkQUNSUkVTT1VSQ0VJRCIpIgogICAgKQoKICAgIHJldHJ5IGNtZCByZXRyeV90aW1lCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgaSBpbiAke3B1bGxfaW1hZ2VzW0BdfTsgZG8KICAgICAgICBsb2NhbCAtbiBpbWFnZT0iJGkiCiAgICAgICAgY21kPSgKICAgICAgICAgICAgcG9kbWFuCiAgICAgICAgICAgIHB1bGwKICAgICAgICAgICAgIiRpbWFnZSIKICAgICAgICApCgogICAgICAgIGxvZyAiUHVsbGluZyBpbWFnZSAkaW1hZ2Ugd2l0aCByZXRyaWVzIG5vdyIKICAgICAgICByZXRyeSBjbWQgcmV0cnlfdGltZQogICAgZG9uZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgY21kPSgKICAgICAgICBhegogICAgICAgIGxvZ291dAogICAgKQoKICAgIGxvZyAiUnVubmluZyBheiBsb2dvdXQgd2l0aCByZXRyaWVzIgogICAgcmV0cnkgY21kIHJldHJ5X3RpbWUKfQoKIyBjb25maWd1cmVfY2VydHNfZ2VuZXJhbCBDb25maWd1cmUgc3lzdGVtIGNlcnRpZmljYXRlcyBjb21tb24gdG8gYWxsIFZNU1MgaW5zdGFuY2VzCmNvbmZpZ3VyZV9jZXJ0c19nZW5lcmFsKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNldHRpbmcgTU9OSVRPUklOR19HQ1NfQVVUSF9JRF9UWVBFPUF1dGhLZXlWYXVsdCBzZWVtcyB0byBoYXZlIGNhdXNlZCBtZHNkIG5vdAogICAgIyB0byBob25vdXIgU1NMX0NFUlRfRklMRSBhbnkgbW9yZSwgaGVhdmVuIG9ubHkga25vd3Mgd2h5LgogICAgbG9jYWwgLXIgc3NsX2NlcnRzX2Jhc2VkaXI9Ii91c3IvbGliL3NzbC9jZXJ0cyIKICAgIG1rZGlyIC1wICIkc3NsX2NlcnRzX2Jhc2VkaXIiCiAgICBjc3BsaXQgLWYgIiRzc2xfY2VydHNfYmFzZWRpci9jZXJ0LSIgLWIgJTAzZC5wZW0gL2V0Yy9wa2kvdGxzL2NlcnRzL2NhLWJ1bmRsZS5jcnQgL14kLzEgInsqfSIgMT4vZGV2L251bGwKICAgIGNfcmVoYXNoICIkc3NsX2NlcnRzX2Jhc2VkaXIiCn0KCiMgY29uZmlndXJlX2NlcnRzX3JwIENvbmZpZ3VyZSBzeXN0ZW0gY2VydGlmaWNhdGVzIGZvciBSUCBWTVNTCiMgYXJnczoKY29uZmlndXJlX2NlcnRzX3JwKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICB2ZXJpZnlfcm9sZSByb2xlX3JwCgogICAgbG9jYWwgLXIgcnBfY2VydHNfYmFzZWRpcj0iL2V0Yy9hcm8tcnAiCiAgICBta2RpciAtcCAiJHJwX2NlcnRzX2Jhc2VkaXIiCiAgICBiYXNlNjQgLWQgPDw8IiRBRE1JTkFQSUNBQlVORExFIiA+ICIkcnBfY2VydHNfYmFzZWRpci9hZG1pbi1jYS1idW5kbGUucGVtIgogICAgaWYgW1sgLW4gIiRBUk1BUElDQUJVTkRMRSIgXV07IHRoZW4KICAgIGJhc2U2NCAtZCA8PDwiJEFSTUFQSUNBQlVORExFIiA+ICIkcnBfY2VydHNfYmFzZWRpci9hcm0tY2EtYnVuZGxlLnBlbSIKICAgIGZpCiAgICBjaG93biAtUiAxMDAwOjEwMDAgIiRycF9jZXJ0c19iYXNlZGlyIgoKICAgIGNvbmZpZ3VyZV9jZXJ0c19nZW5lcmFsCn0KCiMgY29uZmlndXJlX2NlcnRzX2dhdGV3YXkgQ29uZmlndXJlIHN5c3RlbSBjZXJ0aWZpY2F0ZXMgZm9yIEdhdGV3YXkgVk1TUyBpbnN0YW5jZXMKY29uZmlndXJlX2NlcnRzX2dhdGV3YXkoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHZlcmlmeV9yb2xlIHJvbGVfZ2F0ZXdheQogICAgY29uZmlndXJlX2NlcnRzX2dlbmVyYWwKfQoKIyBjb25maWd1cmVfY2VydHNfZGV2cHJveHkgQ29uZmlndXJlIHN5c3RlbSBjZXJ0aWZpY2F0ZXMgZm9yIGRldnByb3h5IFZNU1MgaW5zdGFuY2VzCmNvbmZpZ3VyZV9jZXJ0c19kZXZwcm94eSgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgdmVyaWZ5X3JvbGUgcm9sZV9kZXZwcm94eQoKICAgIGxvY2FsIC1yIHByb3h5X2NlcnRzX2Jhc2VkaXI9Ii9ldGMvcHJveHkiCiAgICBta2RpciAtcCAiJHByb3h5X2NlcnRzX2Jhc2VkaXIiCiAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUNFUlQiID4gIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LmNydCIKICAgIGJhc2U2NCAtZCA8PDwiJFBST1hZS0VZIiA+ICIkcHJveHlfY2VydHNfYmFzZWRpci9wcm94eS5rZXkiCiAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUNMSUVOVENFUlQiID4gIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LWNsaWVudC5jcnQiCiAgICBjaG93biAtUiAxMDAwOjEwMDAgL2V0Yy9wcm94eQogICAgY2htb2QgMDYwMCAiJHByb3h5X2NlcnRzX2Jhc2VkaXIvcHJveHkua2V5Igp9Cgpjb25maWd1cmVfYXpzZWNkX3NjYW4oKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgICMgd2UgbGVhdmUgY2xpZW50SWQgYmxhbmsgYXMgbG9uZyBhcyBvbmx5IDEgbWFuYWdlZCBpZGVudGl0eSBhc3NpZ25lZCB0byB2bXNzCiAgICAjIGlmIHdlIGhhdmUgbW9yZSB0aGFuIDEsIHdlIHdpbGwgbmVlZCB0byBwb3B1bGF0ZSB3aXRoIGNsaWVudElkIHVzZWQgZm9yIG9mZi1ub2RlIHNjYW5uaW5nCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG5vZGVzY2FuX2FnZW50X2ZpbGVuYW1lPSIvZXRjL2RlZmF1bHQvdnNhLW5vZGVzY2FuLWFnZW50LmNvbmZpZyIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbm9kZXNjYW5fYWdlbnRfZmlsZT0iewogICAgXCJOaWNlXCI6IDE5LAogICAgXCJUaW1lb3V0XCI6IDEwODAwLAogICAgXCJDbGllbnRJZFwiOiBcIlwiLAogICAgXCJUZW5hbnRJZFwiOiAkQVpVUkVTRUNQQUNLVlNBVEVOQU5USUQsCiAgICBcIlF1YWx5c1N0b3JlQmFzZVVybFwiOiAkQVpVUkVTRUNQQUNLUVVBTFlTVVJMLAogICAgXCJQcm9jZXNzVGltZW91dFwiOiAzMDAsCiAgICBcIkNvbW1hbmREZWxheVwiOiAwCiAgfSIKCiAgICB3cml0ZV9maWxlIG5vZGVzY2FuX2FnZW50X2ZpbGVuYW1lIG5vZGVzY2FuX2FnZW50X2ZpbGUgdHJ1ZQp9CgojIHJ1bl9henNlY2RfY29uZmlnX3NjYW4KcnVuX2F6c2VjZF9jb25maWdfc2NhbigpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgY29uZmlndXJlX2F6c2VjZF9zY2FuCgogICAgbG9jYWwgLWFyIGNvbmZpZ3M9KAogICAgICAgICJiYXNlbGluZSIKICAgICAgICAiY2xhbWF2IgogICAgICAgICJzb2Z0d2FyZSIKICAgICkKCiAgICBsb2cgIlNjYW5uaW5nIGNvbmZpZ3VyYXRpb24gZmlsZXMgd2l0aCBhenNlY2QgJHtjb25maWdzWypdfSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgZm9yIHNjYW4gaW4gJHtjb25maWdzW0BdfTsgZG8KICAgICAgICBsb2cgIlNjYW5uaW5nIGNvbmZpZyBmaWxlICRzY2FuIG5vdyIKICAgICAgICAvdXNyL2xvY2FsL2Jpbi9henNlY2QgY29uZmlnIC1zICIkc2NhbiIgLWQgUDFECiAgICBkb25lCn0KCiMgY3JlYXRlX3JlcXVpcmVkX2RpcnMKY3JlYXRlX3JlcXVpcmVkX2RpcnMoKSB7CiAgICBjcmVhdGVfZGlycz0oCiAgICAgICAgL3Zhci9sb2cvam91cm5hbAogICAgICAgIC92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlCiAgICAgICAgIyBEb2VzIG5vdCBleGlzdCBvbiBkZXZQcm94eVZNU1MKICAgICAgICAvdmFyL29wdC9taWNyb3NvZnQvbGludXhtb25hZ2VudAogICAgKQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgZm9yIGQgaW4gJHtjcmVhdGVfZGlyc1tAXX07IGRvCiAgICAgICAgbG9nICJDcmVhdGluZyBkaXJlY3RvcnkgJGQiCiAgICAgICAgbWtkaXIgLXAgIiRkIiB8fCBhYm9ydCAiZmFpbGVkIHRvIGNyZWF0ZSBkaXJlY3RvcnkgJGQiCiAgICBkb25lCn0KCiMgZmlyZXdhbGxkX2NvbmZpZ3VyZV9iYWNrZW5kCmZpcmV3YWxsZF9jb25maWd1cmVfYmFja2VuZCgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgbG9nICJDaGFuZ2luZyBmaXJld2FsbGQgYmFja2VuZCB0byBpcHRhYmxlcyIKICAgIGNvbmZfZmlsZT0iL2V0Yy9maXJld2FsbGQvZmlyZXdhbGxkLmNvbmYiCiAgICBzZWQgLWkgJ3MvRmlyZXdhbGxCYWNrZW5kPW5mdGFibGVzL0ZpcmV3YWxsQmFja2VuZD1pcHRhYmxlcy9nJyAiJGNvbmZfZmlsZSIKfQoKIyBmaXJld2FsbGRfY29uZmlndXJlCiMgYXJnczoKIyAxKSBwb3J0cyAtIG5hbWVyZWYsIHN0cmluZyBhcnJheTsgcG9ydHMgdG8gYmUgZW5hYmxlZC4KIyAgICAgICBQb3J0cyBtdXN0IGJlIHBvc3RmaXhlZCB3aXRoIC90Y3Agb3IgL3VkcApmaXJld2FsbGRfY29uZmlndXJlKCkgewogICAgbG9jYWwgLW4gcG9ydHM9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICBmaXJld2FsbGRfY29uZmlndXJlX2JhY2tlbmQKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yYSBzZXJ2aWNlPSgKICAgICAgICAiZmlyZXdhbGxkIgogICAgKQogICAgZW5hYmxlX3NlcnZpY2VzIHNlcnZpY2UKCiAgICBsb2cgIkVuYWJsaW5nIHBvcnRzICR7cG9ydHNbKl19IG9uIGRlZmF1bHQgZmlyZXdhbGxkIHpvbmUiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBwb3J0IGluICR7cG9ydHNbQF19OyBkbwogICAgICAgIGxvZyAiRW5hYmxpbmcgcG9ydCAkcG9ydCBub3ciCiAgICAgICAgZmlyZXdhbGwtY21kICItLWFkZC1wb3J0PSRwb3J0IiBcCiAgICAgICAgICAgICAgICAgICAgIC0tcGVybWFuZW50CiAgICBkb25lCgogICAgbG9nICJXcml0aW5nIHJ1bnRpbWUgY29uZmlnIHRvIHBlcm1hbmVudCBjb25maWciCiAgICBmaXJld2FsbC1jbWQgLS1ydW50aW1lLXRvLXBlcm1hbmVudAp9CgojIHV0aWwtY29tbW9uLnNoIGRvZXMgbm90IGV4aXN0IHdoZW4gZGVwbG95ZWQgdG8gVk1TUyB2aWEgVk1TUyBleHRlbnNpb25zCiMgUHJvdmlkZXMgc2hlbGxjaGVjayBkZWZpbml0aW9ucwp1dGlsX2NvbW1vbj0idXRpbC1jb21tb24uc2giCmlmIFsgLWYgIiR1dGlsX2NvbW1vbiIgXTsgdGhlbgogICAgIyBzaGVsbGNoZWNrIHNvdXJjZT11dGlsLWNvbW1vbi5zaAogICAgc291cmNlICIkdXRpbF9jb21tb24iCmZpCiMhL2Jpbi9iYXNoCgpzZXQgLW8gZXJyZXhpdCBcCiAgICAtbyBwaXBlZmFpbCBcCiAgICAtbyBub3Vuc2V0CgptYWluKCkgewogICAgIyB0cmFuc2FjdGlvbiBhdHRlbXB0IHJldHJ5IHRpbWUgaW4gc2Vjb25kcwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmkgcmV0cnlfd2FpdF90aW1lPTMwCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGxvY2FsIC1yaSBwa2dfcmV0cnlfY291bnQ9NjAKCiAgICBjcmVhdGVfcmVxdWlyZWRfZGlycwogICAgY29uZmlndXJlX3NzaGQKICAgIGNvbmZpZ3VyZV9ycG1fcmVwb3MgcmV0cnlfd2FpdF90aW1lIFwKICAgICAgICAgICAgICAgICAgICAiJHBrZ19yZXRyeV9jb3VudCIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1hciBleGNsdWRlX3BrZ3M9KAogICAgICAgICIteCBXQUxpbnV4QWdlbnQiCiAgICAgICAgIi14IFdBTGludXhBZ2VudC11ZGV2IgogICAgKQoKICAgIGRuZl91cGRhdGVfcGtncyBleGNsdWRlX3BrZ3MgXAogICAgICAgICAgICAgICAgICAgIHJldHJ5X3dhaXRfdGltZSBcCiAgICAgICAgICAgICAgICAgICAgIiRwa2dfcmV0cnlfY291bnQiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgaW5zdGFsbF9wa2dzPSgKICAgICAgICBjbGFtYXYKICAgICAgICBhenNlYy1jbGFtYXYKICAgICAgICBhenVyZS1jbGkKICAgICAgICBhenVyZS1tZHNkCiAgICAgICAgYXp1cmUtc2VjdXJpdHkKICAgICAgICBwb2RtYW4KICAgICAgICBwb2RtYW4tZG9ja2VyCiAgICAgICAgb3BlbnNzbC1wZXJsCiAgICAgICAgIyBoYWNrIC0gd2UgYXJlIGluc3RhbGxpbmcgcHl0aG9uMyBvbiBob3N0cyBkdWUgdG8gYW4gaXNzdWUgd2l0aCBBenVyZSBMaW51eCBFeHRlbnNpb25zIGh0dHBzOi8vZ2l0aHViLmNvbS9BenVyZS9henVyZS1saW51eC1leHRlbnNpb25zL3B1bGwvMTUwNQogICAgICAgIHB5dGhvbjMKICAgICAgICAjIHJlcXVpcmVkIGZvciBwb2RtYW4gbmV0d29ya2luZwogICAgICAgIGZpcmV3YWxsZAogICAgICAgICMgUmVxdWlyZWQgdG8gZW5hYmxlIGZpcHMKICAgICAgICBncnViYnkKICAgICAgICBkcmFjdXQtZmlwcwogICAgKQoKICAgIGRuZl9pbnN0YWxsX3BrZ3MgaW5zdGFsbF9wa2dzIFwKICAgICAgICAgICAgICAgICAgICAgcmV0cnlfd2FpdF90aW1lIFwKICAgICAgICAgICAgICAgICAgICAgIiRwa2dfcmV0cnlfY291bnQiCgogICAgZmlwc19jb25maWd1cmUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxMTkKICAgIGNvbmZpZ3VyZV9sb2dyb3RhdGUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQgZGlzYWJsZT1TQzIxNTMKICAgIGxvY2FsIC1yIG1kbWltYWdlPSIke1JQSU1BR0UlJS8qfS8ke01ETUlNQUdFIyovfSIKICAgIGxvY2FsIC1yIHJwaW1hZ2U9IiRSUElNQUdFIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBmbHVlbnRiaXRfaW1hZ2U9IiRGTFVFTlRCSVRJTUFHRSIKICAgICMgdmFsdWVzIGFyZSByZWZlcmVuY2VzIHRvIHZhcmlhYmxlcywgdGhleSBzaG91bGQgbm90IGJlIGRlcmVmZXJlbmNlZCBoZXJlCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yQSBhcm9faW1hZ2VzPSgKICAgICAgICBbIm1kbSJdPSJtZG1pbWFnZSIKICAgICAgICBbInJwIl09InJwaW1hZ2UiCiAgICAgICAgWyJmbHVlbnRiaXQiXT0iZmx1ZW50Yml0X2ltYWdlIgogICAgKQoKICAgIHB1bGxfY29udGFpbmVyX2ltYWdlcyBhcm9faW1hZ2VzCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgZW5hYmxlX3BvcnRzPSgKICAgICAgICAjIFJQIGdhdGV3YXkKICAgICAgICAiODAvdGNwIgogICAgICAgICI4MDgxL3RjcCIKICAgICAgICAiNDQzL3RjcCIKICAgICAgICAjIEpJVCBzc2gKICAgICAgICAiMjIvdGNwIgogICAgKQoKICAgIGZpcmV3YWxsZF9jb25maWd1cmUgZW5hYmxlX3BvcnRzCgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgZmx1ZW50Yml0X2NvbmZfZmlsZT0iW0lOUFVUXQoJTmFtZSBzeXN0ZW1kCglUYWcgam91cm5hbGQKCVN5c3RlbWRfRmlsdGVyIF9DT01NPWFybwoJREIgL3Zhci9saWIvZmx1ZW50L2pvdXJuYWxkYgoKW0ZJTFRFUl0KCU5hbWUgbW9kaWZ5CglNYXRjaCBqb3VybmFsZAoJUmVtb3ZlX3dpbGRjYXJkIF8KCVJlbW92ZSBUSU1FU1RBTVAKCltPVVRQVVRdCglOYW1lIGZvcndhcmQKCU1hdGNoICoKCVBvcnQgMjkyMzAiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fZ2F0ZXdheV9jb25mX2ZpbGU9IkFDUl9SRVNPVVJDRV9JRD0nJEFDUlJFU09VUkNFSUQnCkRBVEFCQVNFX0FDQ09VTlRfTkFNRT0nJERBVEFCQVNFQUNDT1VOVE5BTUUnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPScke3JvbGVfZ2F0ZXdheV59JwpHQVRFV0FZX0RPTUFJTlM9JyRHQVRFV0FZRE9NQUlOUycKR0FURVdBWV9GRUFUVVJFUz0nJEdBVEVXQVlGRUFUVVJFUycKUlBJTUFHRT0nJHJwaW1hZ2UnIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRzZF9jb25maWdfdmVyc2lvbj0iJEdBVEVXQVlNRFNEQ09ORklHVkVSU0lPTiIKCiAgICAjIHZhbHVlcyBhcmUgcmVmZXJlbmNlcyB0byB2YXJpYWJsZXMsIHRoZXkgc2hvdWxkIG5vdCBiZSBkZXJlZmVyZW5jZWQgaGVyZQogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtckEgYXJvX2NvbmZpZ3M9KAogICAgICAgIFsiZ2F0ZXdheV9jb25maWciXT0iYXJvX2dhdGV3YXlfY29uZl9maWxlIgogICAgICAgIFsiZmx1ZW50Yml0Il09ImZsdWVudGJpdF9jb25mX2ZpbGUiCiAgICAgICAgWyJtZHNkIl09Im1kc2RfY29uZmlnX3ZlcnNpb24iCiAgICAgICAgWyJzdGF0aWNfaXBfYWRkcmVzcyJdPSJzdGF0aWNfaXBfYWRkcmVzc2VzIgogICAgKQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgIyB1c2UgZGVmYXVsdCBwb2RtYW4gbmV0d29yayB3aXRoIHJhbmdlIDEwLjg4LjAuMC8xNgogICAgbG9jYWwgLXJBIHN0YXRpY19pcF9hZGRyZXNzZXM9KAogICAgICAgIFsiZ2F0ZXdheSJdPSIxMC44OC4wLjIiCiAgICAgICAgWyJmbHVlbnRiaXQiXT0iMTAuODguMC43IgogICAgICAgIFsibWRtIl09IjEwLjg4LjAuOCIKICAgICkKCiAgICBjb25maWd1cmVfdm1zc19hcm9fc2VydmljZXMgcm9sZV9nYXRld2F5IFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcm9faW1hZ2VzIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcm9fY29uZmlncwoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJhIGdhdGV3YXlfc2VydmljZXM9KAogICAgICAgICJhcm8tZ2F0ZXdheSIKICAgICAgICAiYXpzZWNkIgogICAgICAgICJtZHNkIgogICAgICAgICJtZG0iCiAgICAgICAgImNocm9ueWQiCiAgICAgICAgImZsdWVudGJpdCIKICAgICAgICAiZG93bmxvYWQtbWRzZC1jcmVkZW50aWFscy50aW1lciIKICAgICAgICAiZG93bmxvYWQtbWRtLWNyZWRlbnRpYWxzLnRpbWVyIgogICAgICAgICJmaXJld2FsbGQiCiAgICApCgogICAgZW5hYmxlX3NlcnZpY2VzIGdhdGV3YXlfc2VydmljZXMKCiAgICByZWJvb3Rfdm0KfQoKZXhwb3J0IEFaVVJFX0NMT1VEX05BTUU9IiR7QVpVUkVDTE9VRE5BTUU6PyJGYWlsZWQgdG8gY2Fycnkgb3ZlciB2YXJpYWJsZXMifSIKCiMgdXRpbC5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbD0idXRpbC5zaCIKaWYgWyAtZiAiJHV0aWwiIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC5zaAogICAgc291cmNlICIkdXRpbCIKZmkKCm1haW4gIiRAIgo=')))]" } } }, diff --git a/pkg/deploy/assets/rp-production-parameters.json b/pkg/deploy/assets/rp-production-parameters.json index 80b4db20490..f1f21894ca2 100644 --- a/pkg/deploy/assets/rp-production-parameters.json +++ b/pkg/deploy/assets/rp-production-parameters.json @@ -75,6 +75,9 @@ "fpServicePrincipalId": { "value": "" }, + "fpTenantId": { + "value": "" + }, "gatewayDomains": { "value": "" }, @@ -99,6 +102,12 @@ "mdsdEnvironment": { "value": "" }, + "miseValidAppIDs": { + "value": "" + }, + "miseValidAudiences": { + "value": "" + }, "msiRpEndpoint": { "value": "" }, diff --git a/pkg/deploy/assets/rp-production.json b/pkg/deploy/assets/rp-production.json index 424ae091079..63fd90b981c 100644 --- a/pkg/deploy/assets/rp-production.json +++ b/pkg/deploy/assets/rp-production.json @@ -96,6 +96,9 @@ "fpServicePrincipalId": { "type": "string" }, + "fpTenantId": { + "type": "string" + }, "gatewayDomains": { "type": "string", "defaultValue": "" @@ -121,6 +124,12 @@ "mdsdEnvironment": { "type": "string" }, + "miseValidAppIDs": { + "type": "array" + }, + "miseValidAudiences": { + "type": "array" + }, "msiRpEndpoint": { "type": "string" }, @@ -451,7 +460,7 @@ "autoUpgradeMinorVersion": true, "settings": {}, "protectedSettings": { - "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'ACRRESOURCEID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('acrResourceId')),''')\n','ADMINAPICLIENTCERTCOMMONNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('adminApiClientCertCommonName')),''')\n','ARMAPICLIENTCERTCOMMONNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('armApiClientCertCommonName')),''')\n','ARMCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('armClientId')),''')\n','AZURECLOUDNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureCloudName')),''')\n','AZURESECPACKQUALYSURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackQualysUrl')),''')\n','AZURESECPACKVSATENANTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackVSATenantId')),''')\n','CLUSTERMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdmAccount')),''')\n','CLUSTERMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdAccount')),''')\n','CLUSTERMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdConfigVersion')),''')\n','CLUSTERMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdNamespace')),''')\n','CLUSTERPARENTDOMAINNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterParentDomainName')),''')\n','DATABASEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('databaseAccountName')),''')\n','FLUENTBITIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fluentbitImage')),''')\n','FPCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fpClientId')),''')\n','FPSERVICEPRINCIPALID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fpServicePrincipalId')),''')\n','GATEWAYDOMAINS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayDomains')),''')\n','GATEWAYRESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayResourceGroupName')),''')\n','GATEWAYSERVICEPRINCIPALID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayServicePrincipalId')),''')\n','KEYVAULTDNSSUFFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultDNSSuffix')),''')\n','KEYVAULTPREFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultPrefix')),''')\n','MDMFRONTENDURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdmFrontendUrl')),''')\n','MDSDENVIRONMENT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdsdEnvironment')),''')\n','MSIRPENDPOINT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('msiRpEndpoint')),''')\n','PORTALACCESSGROUPIDS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalAccessGroupIds')),''')\n','PORTALCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalClientId')),''')\n','PORTALELEVATEDGROUPIDS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalElevatedGroupIds')),''')\n','RPFEATURES=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpFeatures')),''')\n','RPIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpImage')),''')\n','RPMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdmAccount')),''')\n','RPMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdAccount')),''')\n','RPMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdConfigVersion')),''')\n','RPMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdNamespace')),''')\n','RPPARENTDOMAINNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpParentDomainName')),''')\n','OIDCSTORAGEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('oidcStorageAccountName')),''')\n','CLUSTERSINSTALLVIAHIVE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clustersInstallViaHive')),''')\n','CLUSTERSADOPTBYHIVE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clustersAdoptByHive')),''')\n','CLUSTERDEFAULTINSTALLERPULLSPEC=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterDefaultInstallerPullspec')),''')\n','ADMINAPICABUNDLE=''',parameters('adminApiCaBundle'),'''\n','ARMAPICABUNDLE=''',parameters('armApiCaBundle'),'''\n','MDMIMAGE=''/distroless/genevamdm:2.2024.626.1539-d1a6e7-20240715t0935@sha256:372fbc981bbfdf2b9a9d0ffdca2c51ed389b291a3bcff0401e9afb0c01605823''\n','LOCATION=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().location),''')\n','SUBSCRIPTIONID=$(base64 -d \u003c\u003c\u003c''',base64(subscription().subscriptionId),''')\n','RESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().name),''')\n','\n',base64ToString('IyEvYmluL2Jhc2gKIyBJbnRlcm5hbCBGdW5jdGlvbnMgYW5kIENvbnN0YW50cwoKIyBlbXB0eV9zdHIgLSBjb25zdGFudDsgdXNlZCBieSBmdW5jdGlvbnMgZm9yIG9wdGlvbmFsIG5hbWVyZWYgc3RyaW5nIGFyZ3VlbWVudHMKIyBlbXB0eV9zdHI9IiIKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CmRlY2xhcmUgLXIgZW1wdHlfc3RyPSIiCgojIHJvbGVfZ2F0ZXdheSAtIGNvbnN0YW50OyBJcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHRoaXMgc2hvdWxkIGJlIHJlZmVyZW5jZWQgYnkgc2NyaXB0cyBzb3VyY2luZyB0aGlzIGZpbGUKIyByb2xlX2dhdGV3YXk9ImdhdGV3YXkiCmRlY2xhcmUgLXIgcm9sZV9nYXRld2F5PSJnYXRld2F5IgojIHJvbGVfcnAgLSBjb25zdGFudDsgSXMgdXNlZCB0byBkZXRlcm1pbmUgd2hpY2ggVk1TUyBpcyBiZWluZyBib290c3RyYXBwZWQKIyB0aGlzIHNob3VsZCBiZSByZWZlcmVuY2VkIGJ5IHNjcmlwdHMgc291cmNpbmcgdGhpcyBmaWxlCiMgcm9sZV9ycD0icnAiCmRlY2xhcmUgLXIgcm9sZV9ycD0icnAiCiMgcm9sZV9kZXZwcm94eSAtIGNvbnN0YW50OyBJcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHJvbGVfZGV2cHJveHk9ImRldnByb3h5IgpkZWNsYXJlIC1yIHJvbGVfZGV2cHJveHk9ImRldnByb3h5IgoKIyBsb2cgaXMgYSB3cmFwcGVyIGZvciBlY2hvIHRoYXQgaW5jbHVkZXMgdGhlIGZ1bmN0aW9uIG5hbWUKIyBBcmdzCiMgMSkgbXNnIC0gc3RyaW5nCiMgMikgc3RhY2tfbGV2ZWwgLSBpbnQ7IG9wdGlvbmFsLCBkZWZhdWx0cyB0byB0aGUgZnVuY3Rpb24gYXQgdGhlIGJvdHRvbSBvZiB0aGUgY2FsbCBzdGFjawpsb2coKSB7CiAgICBsb2NhbCAtciBtc2c9IiR7MTotImxvZyBtZXNzYWdlIGlzIGVtcHR5In0iCiAgICBsb2NhbCAtciBzdGFja19sZXZlbD0iJHsyOi0xfSIKICAgIGVjaG8gIiR7RlVOQ05BTUVbJHtzdGFja19sZXZlbH1dfTogJHttc2d9Igp9CgojIGFib3J0IGlzIGEgd3JhcHBlciBmb3IgbG9nIHRoYXQgZXhpdHMgd2l0aCBhbiBlcnJvciBjb2RlCmFib3J0KCkgewogICAgbG9jYWwgLXJpIG9yaWdpbl9zdGFja2xldmVsPTIKICAgIGxvZyAiJHsxfSIgIiRvcmlnaW5fc3RhY2tsZXZlbCIKICAgIGxvZyAiRXhpdGluZyIKICAgIGV4aXQgMQp9CgojIHdyaXRlX2ZpbGUKIyBBcmdzCiMgMSkgZmlsZW5hbWUgLSBzdHJpbmcKIyAyKSBmaWxlX2NvbnRlbnRzIC0gc3RyaW5nCiMgMykgY2xvYmJlciAtIGJvb2xlYW47IG9wdGlvbmFsIC0gZGVmYXVsdHMgdG8gZmFsc2UKd3JpdGVfZmlsZSgpIHsKICAgIGxvY2FsIC1uIGZpbGVuYW1lPSIkMSIKICAgIGxvY2FsIC1uIGZpbGVfY29udGVudHM9IiQyIgogICAgbG9jYWwgLXIgY2xvYmJlcj0iJHszOi1mYWxzZX0iCgogICAgaWYgJGNsb2JiZXI7IHRoZW4KICAgICAgICBsb2cgIk92ZXJ3cml0aW5nIGZpbGUgJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+ICIkZmlsZW5hbWUiCiAgICBlbHNlCiAgICAgICAgbG9nICJBcHBlbmRpbmcgdG8gJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+PiAiJGZpbGVuYW1lIgogICAgZmkKfQoKIyByZXRyeSBBZGRpbmcgcmV0cnkgbG9naWMgdG8geXVtIGNvbW1hbmRzIGluIG9yZGVyIHRvIGF2b2lkIHN0YWxsaW5nIG91dCBvbiByZXNvdXJjZSBsb2NrcwojIGFyZ3M6CiMgMSkgY21kX3JldHJ5IC0gbmFtZXJlZiwgYXJyYXk7IENvbW1hbmQgYW5kIGFyZ3VlbWVudChzKSB0byByZXRyeQojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CnJldHJ5KCkgewogICAgbG9jYWwgLW4gY21kX3JldHJ5PSIkMSIKICAgIGxvY2FsIC1uIHdhaXRfdGltZT0iJDIiCiAgICBsb2NhbCAtcmkgcmV0cmllcz0iJHszOi01fSIKCiAgICAKICAgIGZvciBhdHRlbXB0IGluICQoc2VxIDEgJHJldHJpZXMpOyBkbwogICAgICAgIGxvZyAiYXR0ZW1wdCAjJHthdHRlbXB0fSAtICR7RlVOQ05BTUVbMl19IgogICAgICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgICAgICR7Y21kX3JldHJ5W0BdfSAmCgogICAgICAgIHdhaXQgLWYgJCEgJiYgcmV0dXJuIDAKICAgICAgICBzbGVlcCAiJHdhaXRfdGltZSIKICAgIGRvbmUKCiAgICBhYm9ydCAiJHtjbWRfcmV0cnlbKl19IGZhaWxlZCBhZnRlciAjJHJldHJpZXMgYXR0ZW1wdHMiCn0KCiMgdmVyaWZ5X3JvbGUKIyBhcmdzOgojIDEpIHRlc3Rfcm9sZSAtIG5hbWVyZWY7IHJvbGUgYmVpbmcgdmVyaWZpZWQKdmVyaWZ5X3JvbGUoKSB7CiAgICBsb2NhbCAtbiB0ZXN0X3JvbGU9IiQxIgoKICAgIGFsbG93ZWRfcm9sZXNfZ2xvYj0iKCRyb2xlX3JwfCRyb2xlX2dhdGV3YXl8JHJvbGVfZGV2cHJveHkpIgogICAgaWYgW1sgIiR0ZXN0X3JvbGUiID1+ICRhbGxvd2VkX3JvbGVzX2dsb2IgXV07IHRoZW4KICAgICAgICBsb2cgIlZlcmlmaWVkIHJvbGUgXCIkdGVzdF9yb2xlXCIiCiAgICBlbHNlCiAgICAgICAgYWJvcnQgImZhaWxlZCB0byB2ZXJpZnkgcm9sZSwgcm9sZSBcIiR7dGVzdF9yb2xlfVwiIG5vdCBpbiBcIiR7YWxsb3dlZF9yb2xlc19nbG9ifVwiIgogICAgZmkKfQoKIyBnZXRfa2V5dmF1bHRfc3VmZml4CiMgYXJnczoKIyAxKSBybCAtIG5hbWVyZWYsIHN0cmluZzsgcm9sZSB0byBnZXQgc2hvcnQgcm9sZSBmb3IKIyAyKSBrdl9zdWZmaXggLSBuYW1lcmVmLCBzdHJpbmc7IHNob3J0IHJvbGUgd2lsbCBiZSBhc3NpZ25lZCB0byB0aGlzIG5hbWVyZWYKIyAzKSBzZWNfcHJlZml4IC0gbmFtZXJlZiwgc3RyaW5nOyBrZXl2YXVsdCBjZXJ0aWZpY2F0ZSBwcmVmaXggd2lsbCBiZSBhc3NpZ25lZCB0byB0aGlzIG5hbWVyZWYKZ2V0X2tleXZhdWx0X3N1ZmZpeCgpIHsKICAgIGxvY2FsIC1uIHJsPSIkMSIKICAgIGxvY2FsIC1uIGt2X3N1ZmZpeD0iJDIiCiAgICBsb2NhbCAtbiBzZWNfcHJlZml4PSIkMyIKCiAgICBsb2NhbCAtciBrZXl2YXVsdF9zdWZmaXhfcnA9InN2YyIKICAgIGxvY2FsIC1yIGtleXZhdWx0X3ByZWZpeF9nYXRld2F5PSJnd3kiCgogICAgY2FzZSAiJHJsIiBpbgogICAgICAgICIkcm9sZV9nYXRld2F5IikKICAgICAgICAgICAga3Zfc3VmZml4PSIka2V5dmF1bHRfcHJlZml4X2dhdGV3YXkiCiAgICAgICAgICAgIHNlY19wcmVmaXg9IiRrZXl2YXVsdF9wcmVmaXhfZ2F0ZXdheSIKICAgICAgICAgICAgOzsKICAgICAgICAiJHJvbGVfcnAiKQogICAgICAgICAgICBrdl9zdWZmaXg9IiRrZXl2YXVsdF9zdWZmaXhfcnAiCiAgICAgICAgICAgIHNlY19wcmVmaXg9IiRyb2xlX3JwIgogICAgICAgICAgICA7OwogICAgICAgICopCiAgICAgICAgICAgIGFib3J0ICJ1bmtvd24gcm9sZSAkcmwiCiAgICAgICAgICAgIDs7CiAgICBlc2FjCn0KCiMgcmVib290X3ZtIHJlc3RvcmVzIGNhbGxzIHNodXRkb3duIC1yIGluIGEgc3Vic2hlbGwKIyBSZWJvb3RzIHNob3VsZCBzY2hlZHVsZWQgYWZ0ZXIgYWxsIFZNIGV4dGVuc2lvbnMgaGF2ZSBoYWQgdGltZSB0byBjb21wbGV0ZQojIFJlZmVyZW5jZTogaHR0cHM6Ly9sZWFybi5taWNyb3NvZnQuY29tL2VuLXVzL2F6dXJlL3ZpcnR1YWwtbWFjaGluZXMvZXh0ZW5zaW9ucy9jdXN0b20tc2NyaXB0LWxpbnV4I3RpcHMKcmVib290X3ZtKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICAoc2h1dGRvd24gLXIgbm93ICYpCn0KIyEvYmluL2Jhc2gKIyBSZXBvc2l0b3J5IGFuZCBwYWNrYWdlIG1hbmFnZW1lbnQgcmVsYXRlZCBmdW5jdGlvbnMKCmNvbmZpZ3VyZV9yZXBvX21hcmluZXJfZXh0ZW5kZWQoKSB7CiAgICBsb2NhbCAtciBleHRlbmRlZF9yZXBvX2NvbmZpZz0iaHR0cHM6Ly9wYWNrYWdlcy5taWNyb3NvZnQuY29tL2NibC1tYXJpbmVyLzIuMC9wcm9kL2V4dGVuZGVkL3g4Nl82NC9jb25maWcucmVwbyIKICAgIGN1cmwgLXNTTCAiJGV4dGVuZGVkX3JlcG9fY29uZmlnIiAtbyAvZXRjL3l1bS5yZXBvcy5kL21hcmluZXItZXh0ZW5kZWQucmVwbwoKICAgIGxvY2FsIC1yIHJlcG9fbmFtZT0iY2JsLW1hcmluZXIyLjBwcm9kZXh0ZW5kZWR4ODZfNjQiCgogICAgbG9jYWwgLXJhIGNtZD0oCiAgICAgICAgZG5mCiAgICAgICAgdXBkYXRlCiAgICAgICAgLXkKICAgICAgICAtLWVuYWJsZXJlcG89IiRyZXBvX25hbWUiCiAgICApCgogICAgbG9nICJFbmFibGluZyByZXBvICRyZXBvX25hbWUiCiAgICByZXRyeSBjbWQgIiQxIiAiJHsyOi19Igp9CgojIGNvbmZpZ3VyZV9ycG1fcmVwb3MKIyBOZXcgcmVwb3NpdG9yaWVzIHNob3VsZCBiZSBhZGRlZCBpbiB0aGVpciBvd24gZnVuY3Rpb25zLCBhbmQgY2FsbGVkIGhlcmUKIyBhcmdzOgojIDEpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDIpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1vdW50IG9mIHRpbWVzIHRvIHJldHJ5IGNvbW1hbmQsIGRlZmF1bHRzIHRvIDUKY29uZmlndXJlX3JwbV9yZXBvcygpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgY29uZmlndXJlX3JlcG9fbWFyaW5lcl9leHRlbmRlZCAiJDEiICIkezI6LTF9Igp9CgojIGRuZl9pbnN0YWxsX3BrZ3MKIyBhcmdzOgojIDEpIHBrZ3MgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IFBhY2thZ2VzIHRvIGJlIGluc3RhbGxlZAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1vdW50IG9mIHRpbWVzIHRvIHJldHJ5IGNvbW1hbmQsIGRlZmF1bHRzIHRvIDUKZG5mX2luc3RhbGxfcGtncygpIHsKICAgIGxvY2FsIC1uIHBrZ3M9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgIGRuZgogICAgICAgIC15CiAgICAgICAgaW5zdGFsbAogICAgKQogICAgCiAgICAjIFJlZmVyZW5jZTogaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIyMDYKICAgICMgYXBwZW5kIHBrZ3MgYXJyYXkgdG8gY21kCiAgICBtYXBmaWxlIC1PICQoKCAkeyNjbWRbQF19ICsgMSApKSAtZCAnICcgY21kIDw8PCAiJHtwa2dzW0BdfSIKICAgIGxvY2FsIC1yIGNtZAoKICAgIGxvZyAiQXR0ZW1wdGluZyB0byBpbnN0YWxsIHBhY2thZ2VzOiAke3BrZ3NbKl19IgogICAgcmV0cnkgY21kICIkMiIgIiR7MzotfSIKfQoKCiMgZG5mX3VwZGF0ZV9wa2dzCiMgYXJnczoKIyAxKSBleGNsdWRlcyAtIG5hbWVyZWYsIHN0cmluZyBhcnJheSwgb3B0aW9uYWw7IFBhY2thZ2VzIHRvIGV4Y2x1ZGUgZnJvbSB1cGRhdGluZwojICAgICAgIEVhY2ggaW5kZXggbXVzdCBiZSBwcmVmaXhlZCB3aXRoIC14IAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CmRuZl91cGRhdGVfcGtncygpIHsKICAgIGxvY2FsIC1uIGV4Y2x1ZGVzPSIkezE6LWVtcHR5X3N0cn0iCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGxvY2FsIC1hIGNtZD0oCiAgICAgICAgZG5mCiAgICAgICAgLXkKICAgICAgICAjIFJlcGxhY2VkIHdpdGggZXhjbHVkZXMKICAgICAgICAiIgogICAgICAgIHVwZGF0ZQogICAgICAgIC0tYWxsb3dlcmFzaW5nCiAgICApCgogICAgaWYgWyAtbiAiJHtleGNsdWRlc30iIF07IHRoZW4KICAgICAgICAjIFJlZmVyZW5jZSBodHRwczovL3d3dy5zaGVsbGNoZWNrLm5ldC93aWtpL1NDMjIwNgogICAgICAgIG1hcGZpbGUgLU8gMiBjbWQgPDw8ICIke2V4Y2x1ZGVzW0BdfSIKICAgIGVsc2UKICAgICAgICAjIFJlbW92ZSBlbXB0eSBzdHJpbmcgaWYgd2UgYXJlbid0IHJlcGxhY2luZyB0aGVtLCBwcm9iYWJseSBkb2Vzbid0IG1hdHRlciwgYnV0IHdoeSBub3QgYmUgc2FmZQogICAgICAgIHVuc2V0ICJjbWRbMl0iCiAgICBmaQogICAgbG9jYWwgLXIgY21kCgogICAgbG9nICJVcGRhdGluZyBhbGwgcGFja2FnZXMgZXhjbHVkaW5nIFwiJHtleGNsdWRlc1sqXTotfVwiIgogICAgcmV0cnkgY21kICIkMiIgIiR7MzotfSIKfQoKIyBycG1faW1wb3J0X2tleXMKIyBhcmdzOgojIDEpIGtleXMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IHJwbSBrZXlzIHRvIGJlIGltcG9ydGVkCiMgMikgd2FpdF90aW1lIC0gbmFtZXJlZiwgaW50ZWdlcjsgVGltZSB0byB3YWl0IGJlZm9yZSByZXRyeWluZyBjb21tYW5kCnJwbV9pbXBvcnRfa2V5cygpIHsKICAgIGxvY2FsIC1uIGtleXM9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBrZXkgaW4gJHtrZXlzW0BdfTsgZG8KICAgICAgICBpZiBbICR7I2tleXNbQF19IC1lcSAwIF07IHRoZW4KICAgICAgICAgICAgYnJlYWsKICAgICAgICBmaQoKICAgICAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgICAgICBycG0KICAgICAgICAgICAgLS1pbXBvcnQKICAgICAgICAgICAgLXYKICAgICAgICAgICAgIiRrZXkiCiAgICAgICAgKQoKICAgICAgICBsb2cgIkltcG9ydGluZyBycG0gcmVwb3NpdG9yeSBrZXkgJGtleSIKICAgICAgICByZXRyeSBjbWQgIiQyIiAiJHszOi19IiAmJiB1bnNldCBrZXkKICAgIGRvbmUKfQoKIyB1dGlsLWNvbW1vbi5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQojIS9iaW4vYmFzaAojIEFSTyBzZXJ2aWNlIHNldHVwIGZ1bmN0aW9ucwoKIyBlbmFibGVfc2VydmljZXMgZW5hYmxlcyB0aGUgc3lzdGVtZCBzZXJ2aWNlcyB0aGF0IGFyZSBwYXNzZWQgaW4KIyBhcmdzOgojIDEpIHNlcnZpY2VzIC0gYXJyYXk7IHNlcnZpY2VzIHRvIGJlIGVuYWJsZWQKZW5hYmxlX3NlcnZpY2VzKCkgewogICAgbG9jYWwgLW4gc3Zjcz0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHN5c3RlbWN0bCBkYWVtb24tcmVsb2FkCgogICAgbG9nICJlbmFibGluZyBzZXJ2aWNlcyAke3N2Y3NbKl19IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3Igc3ZjIGluICR7c3Zjc1tAXX07IGRvCiAgICAgICAgbG9nICJFbmFibGluZyBhbmQgc3RhcnRpbmcgJHN2YyBub3ciCiAgICAgICAgc3lzdGVtY3RsIGVuYWJsZSBcCiAgICAgICAgICAgICAgICAgIC0tbm93IFwKICAgICAgICAgICAgICAgICAgIiRzdmMiCiAgICBkb25lCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBjb250YWluZXIgaW1hZ2UKIyAyKSByb2xlIC0gbmFtZXJlZiwgc3RyaW5nOyBWTVNTIHJvbGUKIyAzKSBjb25mX2ZpbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGFybyBnYXRld2F5IGVudmlyb25tZW50IGZpbGUKY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiByb2xlPSIkMiIKICAgIGxvY2FsIC1uIGNvbmZfZmlsZT0iJDMiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tZ2F0ZXdheSBzZXJ2aWNlIgoKICAgIGxvY2FsIC1yIGFyb19nYXRld2F5X2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1nYXRld2F5JwoKICAgIHdyaXRlX2ZpbGUgYXJvX2dhdGV3YXlfY29uZl9maWxlbmFtZSBjb25mX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX2dhdGV3YXlfc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9hcm8tZ2F0ZXdheS5zZXJ2aWNlJwoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX2dhdGV3YXlfc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0ke2Fyb19nYXRld2F5X2NvbmZfZmlsZW5hbWV9CkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLWUgQUNSX1JFU09VUkNFX0lEIFwKICAtZSBEQVRBQkFTRV9BQ0NPVU5UX05BTUUgXAogIC1lIEdBVEVXQVlfRE9NQUlOUyBcCiAgLWUgR0FURVdBWV9GRUFUVVJFUyBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1tIDJnIFwKICAtcCA4MDo4MDgwIFwKICAtcCA4MDgxOjgwODEgXAogIC1wIDQ0Mzo4NDQzIFwKICAtdiAvcnVuL3N5c3RlbWQvam91cm5hbDovcnVuL3N5c3RlbWQvam91cm5hbCBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJGltYWdlIFwKICAke3JvbGUsLH0KRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgLXQgMzYwMCAlTgpUaW1lb3V0U3RvcFNlYz0zNjAwClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAiCgogICAgd3JpdGVfZmlsZSBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19nYXRld2F5X3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX3JwCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCiMgMikgcm9sZSAtIG5hbWVyZWYsIHN0cmluZzsgVk1TUyByb2xlCiMgMykgY29uZl9maWxlIC0gbmFtZXJlZiwgc3RyaW5nOyBhcm8gcnAgZW52aXJvbm1lbnQgZmlsZQpjb25maWd1cmVfc2VydmljZV9hcm9fcnAoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiByb2xlPSIkMiIKICAgIGxvY2FsIC1uIGNvbmZfZmlsZT0iJDMiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tcnAgc2VydmljZSIKCiAgICBsb2NhbCAtciBhcm9fcnBfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLXJwJwoKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX2NvbmZfZmlsZW5hbWUgY29uZl9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19ycF9zZXJ2aWNlX2ZpbGVuYW1lPScvZXRjL3N5c3RlbWQvc3lzdGVtL2Fyby1ycC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcnBfc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0ke2Fyb19ycF9jb25mX2ZpbGVuYW1lfQpFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC1lIEFDUl9SRVNPVVJDRV9JRCBcCiAgLWUgQURNSU5fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FIFwKICAtZSBBUk1fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FIFwKICAtZSBBWlVSRV9BUk1fQ0xJRU5UX0lEIFwKICAtZSBBWlVSRV9GUF9DTElFTlRfSUQgXAogIC1lIENMVVNURVJfTURNX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURNX05BTUVTUEFDRSBcCiAgLWUgQ0xVU1RFUl9NRFNEX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTiBcCiAgLWUgQ0xVU1RFUl9NRFNEX05BTUVTUEFDRSBcCiAgLWUgREFUQUJBU0VfQUNDT1VOVF9OQU1FIFwKICAtZSBET01BSU5fTkFNRSBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX1JFU09VUkNFR1JPVVAgXAogIC1lIEtFWVZBVUxUX1BSRUZJWCBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1lIE1EU0RfRU5WSVJPTk1FTlQgXAogIC1lIFJQX0ZFQVRVUkVTIFwKICAtZSBBUk9fSU5TVEFMTF9WSUFfSElWRSBcCiAgLWUgQVJPX0hJVkVfREVGQVVMVF9JTlNUQUxMRVJfUFVMTFNQRUMgXAogIC1lIEFST19BRE9QVF9CWV9ISVZFIFwKICAtZSBPSURDX0FGRF9FTkRQT0lOVCBcCiAgLWUgT0lEQ19TVE9SQUdFX0FDQ09VTlRfTkFNRSBcCiAgLWUgTVNJX1JQX0VORFBPSU5UIFwKICAtbSAyZyBcCiAgLXAgNDQzOjg0NDMgXAogIC12IC9ldGMvYXJvLXJwOi9ldGMvYXJvLXJwIFwKICAtdiAvcnVuL3N5c3RlbWQvam91cm5hbDovcnVuL3N5c3RlbWQvam91cm5hbCBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJGltYWdlIFwKICAke3JvbGUsLH0KRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgLXQgMzYwMCAlTgpUaW1lb3V0U3RvcFNlYz0zNjAwClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX3NlcnZpY2VfZmlsZW5hbWUgYXJvX3JwX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX21vbml0b3IKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBSUCBjb250YWluZXIgaW1hZ2UKY29uZmlndXJlX3NlcnZpY2VfYXJvX21vbml0b3IoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tbW9uaXRvciBzZXJ2aWNlIgoKICAgICMgRE9NQUlOX05BTUUsIENMVVNURVJfTURTRF9BQ0NPVU5ULCBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04sIEdBVEVXQVlfRE9NQUlOUywgR0FURVdBWV9SRVNPVVJDRUdST1VQLCBNRFNEX0VOVklST05NRU5UIENMVVNURVJfTURTRF9OQU1FU1BBQ0UKICAgICMgYXJlIG5vdCB1c2VkLCBidXQgY2FuJ3QgZWFzaWx5IGJlIHJlZmFjdG9yZWQgb3V0LiBTaG91bGQgYmUgcmV2aXNpdGVkIGluIHRoZSBmdXR1cmUuCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLW1vbml0b3InCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlPSJBWlVSRV9GUF9DTElFTlRfSUQ9JyRGUENMSUVOVElEJwpET01BSU5fTkFNRT0nJExPQ0FUSU9OLiRDTFVTVEVSUEFSRU5URE9NQUlOTkFNRScKQ0xVU1RFUl9NRFNEX0FDQ09VTlQ9JyRDTFVTVEVSTURTREFDQ09VTlQnCkNMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTj0nJENMVVNURVJNRFNEQ09ORklHVkVSU0lPTicKR0FURVdBWV9ET01BSU5TPSckR0FURVdBWURPTUFJTlMnCkdBVEVXQVlfUkVTT1VSQ0VHUk9VUD0nJEdBVEVXQVlSRVNPVVJDRUdST1VQTkFNRScKTURTRF9FTlZJUk9OTUVOVD0nJE1EU0RFTlZJUk9OTUVOVCcKQ0xVU1RFUl9NRFNEX05BTUVTUEFDRT0nJENMVVNURVJNRFNETkFNRVNQQUNFJwpDTFVTVEVSX01ETV9BQ0NPVU5UPSckQ0xVU1RFUk1ETUFDQ09VTlQnCkNMVVNURVJfTURNX05BTUVTUEFDRT1CQk0KREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPUJCTQpSUElNQUdFPSckaW1hZ2UnIgoKICAgIHdyaXRlX2ZpbGUgYXJvX21vbml0b3Jfc2VydmljZV9jb25mX2ZpbGVuYW1lIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLW1vbml0b3Iuc2VydmljZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21vbml0b3Jfc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9hcm8tbW9uaXRvcgpFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC1lIEFaVVJFX0ZQX0NMSUVOVF9JRCBcCiAgLWUgRE9NQUlOX05BTUUgXAogIC1lIENMVVNURVJfTURTRF9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04gXAogIC1lIEdBVEVXQVlfRE9NQUlOUyBcCiAgLWUgR0FURVdBWV9SRVNPVVJDRUdST1VQIFwKICAtZSBNRFNEX0VOVklST05NRU5UIFwKICAtZSBDTFVTVEVSX01EU0RfTkFNRVNQQUNFIFwKICAtZSBDTFVTVEVSX01ETV9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01ETV9OQU1FU1BBQ0UgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgS0VZVkFVTFRfUFJFRklYIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLW0gMi41ZyBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgbW9uaXRvcgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZW5hbWUgYXJvX21vbml0b3Jfc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9hcm9fcG9ydGFsCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCmNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19wb3J0YWwoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8gcG9ydGFsIHNlcnZpY2UiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZT0iQVpVUkVfUE9SVEFMX0FDQ0VTU19HUk9VUF9JRFM9JyRQT1JUQUxBQ0NFU1NHUk9VUElEUycKQVpVUkVfUE9SVEFMX0NMSUVOVF9JRD0nJFBPUlRBTENMSUVOVElEJwpBWlVSRV9QT1JUQUxfRUxFVkFURURfR1JPVVBfSURTPSckUE9SVEFMRUxFVkFURURHUk9VUElEUycKREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPVBvcnRhbApQT1JUQUxfSE9TVE5BTUU9JyRMT0NBVElPTi5hZG1pbi4kUlBQQVJFTlRET01BSU5OQU1FJwpSUElNQUdFPSckaW1hZ2UnIgoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLXBvcnRhbC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKU3RhcnRMaW1pdEludGVydmFsPTAKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC1lIEFaVVJFX1BPUlRBTF9BQ0NFU1NfR1JPVVBfSURTIFwKICAtZSBBWlVSRV9QT1JUQUxfQ0xJRU5UX0lEIFwKICAtZSBBWlVSRV9QT1JUQUxfRUxFVkFURURfR1JPVVBfSURTIFwKICAtZSBEQVRBQkFTRV9BQ0NPVU5UX05BTUUgXAogIC1lIEtFWVZBVUxUX1BSRUZJWCBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1lIFBPUlRBTF9IT1NUTkFNRSBcCiAgLW0gMmcgXAogIC1wIDQ0NDo4NDQ0IFwKICAtcCAyMjIyOjIyMjIgXAogIC12IC9ydW4vc3lzdGVtZC9qb3VybmFsOi9ydW4vc3lzdGVtZC9qb3VybmFsIFwKICAtdiAvdmFyL2V0dzovdmFyL2V0dzp6IFwKICAkaW1hZ2UgXAogIHBvcnRhbApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIGFyb19wb3J0YWxfc2VydmljZV9maWxlbmFtZSBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfbWRzZAojIGFyZ3M6CiMgMSkgbW9uaXRvcmluZ19yb2xlIC0gbmFtZXJlZiwgc3RyaW5nOyBjYW4gYmUgImdhdGV3YXkiIG9yICJycCIKIyAyKSBtb25pdG9yX2NvbmZpZ192ZXJzaW9uIC0gbmFtZXJlZiwgc3RyaW5nOyBtZHNkIGNvbmZpZyB2ZXJzaW9uCmNvbmZpZ3VyZV9zZXJ2aWNlX21kc2QoKSB7CiAgICBsb2NhbCAtbiByb2xlPSIkMSIKICAgIGxvY2FsIC1uIG1vbml0b3JfY29uZmlnX3ZlcnNpb249IiQyIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiY29uZmlndXJpbmcgbWRzZCBzZXJ2aWNlIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICBsb2NhbCAtciBtZHNkX3NlcnZpY2VfZGlyPSIvZXRjL3N5c3RlbWQvc3lzdGVtL21kc2Quc2VydmljZS5kIgogICAgbWtkaXIgLXAgIiRtZHNkX3NlcnZpY2VfZGlyIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRzZF9vdmVycmlkZV9jb25mX2ZpbGVuYW1lPSIkbWRzZF9zZXJ2aWNlX2Rpci9vdmVycmlkZS5jb25mIgogICAgbG9jYWwgLXIgbWRzZF9jZXJ0aWZpY2F0ZV9zYW49IiQob3BlbnNzbCB4NTA5IC1pbiAvdmFyL2xpYi93YWFnZW50L01pY3Jvc29mdC5BenVyZS5LZXlWYXVsdC5TdG9yZS9tZHNkLnBlbSAtbm9vdXQgLXN1YmplY3QgfCBzZWQgLWUgJ3MvLipDTiA9IC8vJykiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kc2Rfb3ZlcnJpZGVfY29uZl9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgbWRzZF9vdmVycmlkZV9jb25mX2ZpbGVuYW1lIG1kc2Rfb3ZlcnJpZGVfY29uZl9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGRlZmF1bHRfbWRzZF9maWxlbmFtZT0iL2V0Yy9kZWZhdWx0L21kc2QiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGRlZmF1bHRfbWRzZF9maWxlPSJNRFNEX1JPTEVfUFJFRklYPS92YXIvcnVuL21kc2QvZGVmYXVsdApNRFNEX09QVElPTlM9XCItQSAtZCAtciBcJE1EU0RfUk9MRV9QUkVGSVhcIgoKZXhwb3J0IE1PTklUT1JJTkdfR0NTX0VOVklST05NRU5UPSckTURTREVOVklST05NRU5UJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfQUNDT1VOVD0nJFJQTURTREFDQ09VTlQnCmV4cG9ydCBNT05JVE9SSU5HX0dDU19SRUdJT049JyRMT0NBVElPTicKZXhwb3J0IE1PTklUT1JJTkdfR0NTX0FVVEhfSURfVFlQRT1BdXRoS2V5VmF1bHQKZXhwb3J0IE1PTklUT1JJTkdfR0NTX0FVVEhfSUQ9JyRtZHNkX2NlcnRpZmljYXRlX3NhbicKZXhwb3J0IE1PTklUT1JJTkdfR0NTX05BTUVTUEFDRT0nJFJQTURTRE5BTUVTUEFDRScKZXhwb3J0IE1PTklUT1JJTkdfQ09ORklHX1ZFUlNJT049JyRtb25pdG9yX2NvbmZpZ192ZXJzaW9uJwpleHBvcnQgTU9OSVRPUklOR19VU0VfR0VORVZBX0NPTkZJR19TRVJWSUNFPXRydWUKCmV4cG9ydCBNT05JVE9SSU5HX1RFTkFOVD0nJExPQ0FUSU9OJwpleHBvcnQgTU9OSVRPUklOR19ST0xFPSckcm9sZScKZXhwb3J0IE1PTklUT1JJTkdfUk9MRV9JTlNUQU5DRT1cIiQoaG9zdG5hbWUpXCIKCmV4cG9ydCBNRFNEX01TR1BBQ0tfU09SVF9DT0xVTU5TPVwiMVwiIgoKICAgIHdyaXRlX2ZpbGUgZGVmYXVsdF9tZHNkX2ZpbGVuYW1lIGRlZmF1bHRfbWRzZF9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9mbHVlbnRiaXQKIyBhcmdzOgojIDEpIGNvbmZfZmlsZSAtIHN0cmluZzsgZmx1ZW5iaXQgY29uZmlndXJhdGlvbiBmaWxlCiMgMikgaW1hZ2UgLSBzdHJpbmc7IGZsdWVudGJpdCBjb250YWluZXIgaW1hZ2UgdG8gcnVuCmNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdCgpIHsKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIGZsdWVudGJpdCBzZXJ2aWNlIgoKICAgIG1rZGlyIC1wIC9ldGMvZmx1ZW50Yml0LwogICAgbWtkaXIgLXAgL3Zhci9saWIvZmx1ZW50CgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBjb25mX2ZpbGVuYW1lPScvZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZicKICAgIHdyaXRlX2ZpbGUgY29uZl9maWxlbmFtZSBjb25mX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX2ZpbGVuYW1lPScvZXRjL3N5c2NvbmZpZy9mbHVlbnRiaXQnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHN5c2NvbmZpZ19maWxlPSJGTFVFTlRCSVRJTUFHRT0kaW1hZ2UiCgogICAgd3JpdGVfZmlsZSBzeXNjb25maWdfZmlsZW5hbWUgc3lzY29uZmlnX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9mbHVlbnRiaXQuc2VydmljZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldApTdGFydExpbWl0SW50ZXJ2YWxTZWM9MAoKW1NlcnZpY2VdClJlc3RhcnRTZWM9MXMKRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2ZsdWVudGJpdApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1zZWN1cml0eS1vcHQgbGFiZWw9ZGlzYWJsZSBcCiAgLS1lbnRyeXBvaW50IC9vcHQvdGQtYWdlbnQtYml0L2Jpbi90ZC1hZ2VudC1iaXQgXAogIC0tbmV0PWhvc3QgXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtdiAvZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZjovZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZiBcCiAgLXYgL3Zhci9saWIvZmx1ZW50Oi92YXIvbGliL2ZsdWVudDp6IFwKICAtdiAvdmFyL2xvZy9qb3VybmFsOi92YXIvbG9nL2pvdXJuYWw6cm8gXAogIC12IC9ldGMvbWFjaGluZS1pZDovZXRjL21hY2hpbmUtaWQ6cm8gXAogICRpbWFnZSBcCiAgLWMgL2V0Yy9mbHVlbnRiaXQvZmx1ZW50Yml0LmNvbmYKCkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9NQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgc2VydmljZV9maWxlbmFtZSBzZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV90aW1lcnNfbWRtX21kc2QKIyBhcmdzOgojIDEpIHJvbGUgLSBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgpjb25maWd1cmVfdGltZXJzX21kbV9tZHNkKCkgewogICAgbG9jYWwgLW4gcm9sZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICBsb2NhbCBrZXl2YXVsdF9zdWZmaXggc2VjcmV0X3ByZWZpeAogICAgZ2V0X2tleXZhdWx0X3N1ZmZpeCByb2xlIGtleXZhdWx0X3N1ZmZpeCBzZWNyZXRfcHJlZml4CgogICAgZm9yIHZhciBpbiAibWRzZCIgIm1kbSI7IGRvCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9kb3dubG9hZC0kdmFyLWNyZWRlbnRpYWxzLnNlcnZpY2UiCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlPSJbVW5pdF0KRGVzY3JpcHRpb249UGVyaW9kaWMgJHZhciBjcmVkZW50aWFscyByZWZyZXNoCgpbU2VydmljZV0KVHlwZT1vbmVzaG90CkV4ZWNTdGFydD0vdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaCAkdmFyIgoKICAgICAgICB3cml0ZV9maWxlIGRvd25sb2FkX2NyZWRzX3NlcnZpY2VfZmlsZW5hbWUgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlIHRydWUKCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfdGltZXJfZmlsZW5hbWU9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vZG93bmxvYWQtJHZhci1jcmVkZW50aWFscy50aW1lciIKICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlPSJbVW5pdF0KRGVzY3JpcHRpb249UGVyaW9kaWMgJHZhciBjcmVkZW50aWFscyByZWZyZXNoCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltUaW1lcl0KT25Cb290U2VjPTBtaW4KT25DYWxlbmRhcj0wLzEyOjAwOjAwCkFjY3VyYWN5U2VjPTVzCgpbSW5zdGFsbF0KV2FudGVkQnk9dGltZXJzLnRhcmdldCIKCiAgICAgICAgd3JpdGVfZmlsZSBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlbmFtZSBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlIHRydWUKICAgIGRvbmUKCiAgICBsb2NhbCAtciBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWU9Ii91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZT0iIyEvYmluL2Jhc2gKc2V0IC1ldQoKQ09NUE9ORU5UPVwkMQplY2hvIFwiRG93bmxvYWQgXCRDT01QT05FTlQgY3JlZGVudGlhbHNcIgoKVEVNUF9ESVI9XCJcJChta3RlbXAgLWQpXCIKZXhwb3J0IEFaVVJFX0NPTkZJR19ESVI9XCJcJChta3RlbXAgLWQpXCIKCmVjaG8gXCJMb2dnaW5nIGludG8gQXp1cmUuLi5cIgpSRVRSSUVTPTMKd2hpbGUgW1sgXCRSRVRSSUVTIC1ndCAwIF1dOyBkbwogICAgaWYgYXogbG9naW4gLWkgLS1hbGxvdy1uby1zdWJzY3JpcHRpb25zCiAgICB0aGVuCiAgICAgICAgZWNobyBcImF6IGxvZ2luIHN1Y2Nlc3NmdWxcIgogICAgICAgIGJyZWFrCiAgICBlbHNlCiAgICAgICAgZWNobyBcImF6IGxvZ2luIGZhaWxlZC4gUmV0cnlpbmcuLi5cIgogICAgICAgIGxldCBSRVRSSUVTLT0xCiAgICAgICAgc2xlZXAgNQogICAgZmkKZG9uZQoKdHJhcCBcImNsZWFudXBcIiBFWElUCgpjbGVhbnVwKCkgewogIGF6IGxvZ291dAogIFtbIFwkVEVNUF9ESVIgPX4gL3RtcC8uKyBdXSAmJiBybSAtcmYgXCRURU1QX0RJUgogIFtbIFwkQVpVUkVfQ09ORklHX0RJUiA9fiAvdG1wLy4rIF1dICYmIHJtIC1yZiBcJEFaVVJFX0NPTkZJR19ESVIKfQoKaWYgW1sgXCRDT01QT05FTlQgPSBcIm1kbVwiIF1dOyB0aGVuCiAgQ1VSUkVOVF9DRVJUX0ZJTEU9XCIvZXRjL21kbS5wZW1cIgplbGlmIFtbIFwkQ09NUE9ORU5UID0gXCJtZHNkXCIgXV07IHRoZW4KICBDVVJSRU5UX0NFUlRfRklMRT1cIi92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlL21kc2QucGVtXCIKZWxzZQogIGVjaG8gSW52YWxpZCB1c2FnZSAmJiBleGl0IDEKZmkKClNFQ1JFVF9OQU1FPVwiJHNlY3JldF9wcmVmaXgtXCR7Q09NUE9ORU5UfVwiCk5FV19DRVJUX0ZJTEU9XCJcJFRFTVBfRElSL1wkQ09NUE9ORU5ULnBlbVwiCmZvciBhdHRlbXB0IGluIHsxLi41fTsgZG8KICBheiBrZXl2YXVsdCBcCiAgICBzZWNyZXQgXAogICAgZG93bmxvYWQgXAogICAgLS1maWxlIFwiXCRORVdfQ0VSVF9GSUxFXCIgXAogICAgLS1pZCBcImh0dHBzOi8vJEtFWVZBVUxUUFJFRklYLSRrZXl2YXVsdF9zdWZmaXguJEtFWVZBVUxURE5TU1VGRklYL3NlY3JldHMvXCRTRUNSRVRfTkFNRVwiIFwKICAgICYmIGJyZWFrCiAgaWYgW1sgXCRhdHRlbXB0IC1sdCA1IF1dOyB0aGVuIHNsZWVwIDEwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKaWYgWyAtZiBcJE5FV19DRVJUX0ZJTEUgXTsgdGhlbgogIGlmIFtbIFwkQ09NUE9ORU5UID0gXCJtZHNkXCIgXV07IHRoZW4KICAgIGNob3duIHN5c2xvZzpzeXNsb2cgXCRORVdfQ0VSVF9GSUxFCiAgZWxzZQogICAgc2VkIC1pIC1uZSAnMSwvRU5EIENFUlRJRklDQVRFLyBwJyBcJE5FV19DRVJUX0ZJTEUKICBmaQoKICBuZXdfY2VydF9zbj1cIlwkKG9wZW5zc2wgeDUwOSAtaW4gXCJcJE5FV19DRVJUX0ZJTEVcIiAtbm9vdXQgLXNlcmlhbCB8IGF3ayAtRj0gJ3twcmludCBcJDJ9JylcIgogIGN1cnJlbnRfY2VydF9zbj1cIlwkKG9wZW5zc2wgeDUwOSAtaW4gXCJcJENVUlJFTlRfQ0VSVF9GSUxFXCIgLW5vb3V0IC1zZXJpYWwgfCBhd2sgLUY9ICd7cHJpbnQgXCQyfScpXCIKICBpZiBbWyAhIC16IFwkbmV3X2NlcnRfc24gXV0gJiYgW1sgXCRuZXdfY2VydF9zbiAhPSBcIlwkY3VycmVudF9jZXJ0X3NuXCIgXV07IHRoZW4KICAgIGVjaG8gdXBkYXRpbmcgY2VydGlmaWNhdGUgZm9yIFwkQ09NUE9ORU5UCiAgICBjaG1vZCAwNjAwIFwkTkVXX0NFUlRfRklMRQogICAgbXYgXCRORVdfQ0VSVF9GSUxFIFwkQ1VSUkVOVF9DRVJUX0ZJTEUKICBmaQplbHNlCiAgZWNobyBGYWlsZWQgdG8gcmVmcmVzaCBjZXJ0aWZpY2F0ZSBmb3IgXCRDT01QT05FTlQgJiYgZXhpdCAxCmZpIgoKICAgIHdyaXRlX2ZpbGUgZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGVuYW1lIGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlIHRydWUKCiAgICBjaG1vZCB1K3ggL3Vzci9sb2NhbC9iaW4vZG93bmxvYWQtY3JlZGVudGlhbHMuc2gKCiAgICAkZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGVuYW1lIG1kc2QgJgogICAgd2FpdCAiJCEiCgoKICAgICRkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWUgbWRtICYKICAgIHdhaXQgIiQhIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3NlcnZpY2VfZmlsZW5hbWU9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnNlcnZpY2UiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkc19zZXJ2aWNlX2ZpbGU9IltVbml0XQpEZXNjcmlwdGlvbj1XYXRjaCBmb3IgY2hhbmdlcyBpbiBtZG0ucGVtIGFuZCByZXN0YXJ0cyB0aGUgbWRtIHNlcnZpY2UKCltTZXJ2aWNlXQpUeXBlPW9uZXNob3QKRXhlY1N0YXJ0PS91c3IvYmluL3N5c3RlbWN0bCByZXN0YXJ0IG1kbS5zZXJ2aWNlCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQiCgogICAgd3JpdGVfZmlsZSB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlbmFtZSB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGVuYW1lPScvdXNyL2xpYi9zeXN0ZW1kL3N5c3RlbS93YXRjaC1tZG0tY3JlZGVudGlhbHMucGF0aCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZT0nW1BhdGhdClBhdGhNb2RpZmllZD0vZXRjL21kbS5wZW0KCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCcKCiAgICB3cml0ZV9maWxlIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGVuYW1lIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGUgdHJ1ZQoKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkcz0nd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnBhdGgnCiAgICBzeXN0ZW1jdGwgZW5hYmxlIC0tbm93ICIkd2F0Y2hfbWRtX2NyZWRzIiB8fCBhYm9ydCAiZmFpbGVkIHRvIGVuYWJsZSBhbmQgc3RhcnQgJHdhdGNoX21kbV9jcmVkcyIKfQoKIyBjb25maWd1cmVfc2VydmljZV9tZG0KIyBhcmdzOgojIDEpIHJvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgojIDIpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBtZG0gY29udGFpbmVyIGltYWdlIHRvIHJ1bgpjb25maWd1cmVfc2VydmljZV9tZG0oKSB7CiAgICBsb2NhbCAtbiByb2xlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIG1kbSBzZXJ2aWNlIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHN5c2NvbmZpZ19tZG1fZmlsZW5hbWU9Ii9ldGMvc3lzY29uZmlnL21kbSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX21kbV9maWxlPSJNRE1GUk9OVEVORFVSTD0nJE1ETUZST05URU5EVVJMJwpNRE1JTUFHRT0nJGltYWdlJwpNRE1TT1VSQ0VFTlZJUk9OTUVOVD0nJExPQ0FUSU9OJwpNRE1TT1VSQ0VST0xFPSckcm9sZScKTURNU09VUkNFUk9MRUlOU1RBTkNFPVwiJChob3N0bmFtZSlcIiIKCiAgICB3cml0ZV9maWxlIHN5c2NvbmZpZ19tZG1fZmlsZW5hbWUgc3lzY29uZmlnX21kbV9maWxlIHRydWUKCiAgICBta2RpciAtcCAvdmFyL2V0dwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZG1fc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9tZG0uc2VydmljZSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRtX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvbWRtCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWVudHJ5cG9pbnQgL3Vzci9zYmluL01ldHJpY3NFeHRlbnNpb24gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtbSAyZyBcCiAgLXYgL2V0Yy9tZG0ucGVtOi9ldGMvbWRtLnBlbSBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJGltYWdlIFwKICAtQ2VydEZpbGUgL2V0Yy9tZG0ucGVtIFwKICAtRnJvbnRFbmRVcmwgJE1ETUZST05URU5EVVJMIFwKICAtTG9nZ2VyIENvbnNvbGUgXAogIC1Mb2dMZXZlbCBXYXJuaW5nIFwKICAtUHJpdmF0ZUtleUZpbGUgL2V0Yy9tZG0ucGVtIFwKICAtU291cmNlRW52aXJvbm1lbnQgJExPQ0FUSU9OIFwKICAtU291cmNlUm9sZSAkcm9sZSBcCiAgLVNvdXJjZVJvbGVJbnN0YW5jZSAkSE9TVE5BTUUKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgJU4KUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz0xClN0YXJ0TGltaXRJbnRlcnZhbD0wCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQiCgogICAgd3JpdGVfZmlsZSBtZG1fc2VydmljZV9maWxlbmFtZSBtZG1fc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfdm1zc19hcm9fc2VydmljZQojIGFyZ3M6CiMgMSkgciAtIG5hbWVyZWYsIHN0cmluZzsgcm9sZSBvZiBWTVNTCiMgMikgaW1hZ2VzIC0gbmFtZXJlZiwgYXNzb2NpYXRpdmUgYXJyYXk7IEFSTyBjb250YWluZXIgaW1hZ2VzCiMgMykgY29uZmlncyAtIG5hbWVyZWYsIGFzc29jaWF0aXZlIGFycmF5OyBjb25maWd1cmF0aW9uIGZpbGVzIGFuZCB2ZXJzaW9ucy4gVGhlIHZhbHVlcyBzaG91bGQgYmUgYSByZWZlcmVuY2UgdG8gdmFyaWFibGVzLCBub3QgZGVyZWZlcmVuY2VkLgojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBpcyBiZWNhdXNlIHRoZSB2YWx1ZSBpcyB1c2VkIHdoZW4gY3JlYXRpbmcgbmFtZXJlZiB2YXJpYWJsZXMgYnkgaGVscGVyIGZ1bmN0aW9ucy4KY29uZmlndXJlX3Ztc3NfYXJvX3NlcnZpY2VzKCkgewogICAgbG9jYWwgLW4gcj0iJDEiCiAgICBsb2NhbCAtbiBpbWFnZXM9IiQyIgogICAgbG9jYWwgLW4gY29uZmlncz0iJDMiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgdmVyaWZ5X3JvbGUgIiQxIgoKICAgIGlmIFsgIiRyIiA9PSAiJHJvbGVfZ2F0ZXdheSIgXTsgdGhlbgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19nYXRld2F5ICIke2ltYWdlc1sicnAiXX0iICIkMSIgIiR7Y29uZmlnc1siZ2F0ZXdheV9jb25maWciXX0iCiAgICAgICAgY29uZmlndXJlX2NlcnRzX2dhdGV3YXkKICAgIGVsaWYgWyAiJHIiID09ICIkcm9sZV9ycCIgXTsgdGhlbgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19ycCAiJHtpbWFnZXNbInJwIl19IiAiJDEiICIke2NvbmZpZ3NbInJwX2NvbmZpZyJdfSIKICAgICAgICBjb25maWd1cmVfc2VydmljZV9hcm9fbW9uaXRvciAiJHtpbWFnZXNbInJwIl19IgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19wb3J0YWwgIiR7aW1hZ2VzWyJycCJdfSIKICAgICAgICBjb25maWd1cmVfY2VydHNfcnAKICAgIGZpCgogICAgY29uZmlndXJlX3NlcnZpY2VfZmx1ZW50Yml0ICIke2NvbmZpZ3NbImZsdWVudGJpdCJdfSIgIiR7aW1hZ2VzWyJmbHVlbnRiaXQiXX0iCiAgICBjb25maWd1cmVfdGltZXJzX21kbV9tZHNkICIkMSIKICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX21kbSAiJDEiICIke2ltYWdlc1sibWRtIl19IgogICAgY29uZmlndXJlX3NlcnZpY2VfbWRzZCAiJDEiICIke2NvbmZpZ3NbIm1kc2QiXX0iCiAgICBydW5fYXpzZWNkX2NvbmZpZ19zY2FuCn0KCiMgdXRpbC1jb21tb24uc2ggZG9lcyBub3QgZXhpc3Qgd2hlbiBkZXBsb3llZCB0byBWTVNTIHZpYSBWTVNTIGV4dGVuc2lvbnMKIyBQcm92aWRlcyBzaGVsbGNoZWNrIGRlZmluaXRpb25zCnV0aWxfY29tbW9uPSJ1dGlsLWNvbW1vbi5zaCIKaWYgWyAtZiAiJHV0aWxfY29tbW9uIiBdOyB0aGVuCiAgICAjIHNoZWxsY2hlY2sgc291cmNlPXV0aWwtY29tbW9uLnNoCiAgICBzb3VyY2UgIiR1dGlsX2NvbW1vbiIKZmkKCiMgdXRpbC1zeXN0ZW0uc2ggZG9lcyBub3QgZXhpc3Qgd2hlbiBkZXBsb3llZCB0byBWTVNTIHZpYSBWTVNTIGV4dGVuc2lvbnMKIyBQcm92aWRlcyBzaGVsbGNoZWNrIGRlZmluaXRpb25zCnV0aWxfc3lzdGVtPSJ1dGlsLXN5c3RlbS5zaCIKaWYgWyAtZiAiJHV0aWxfc3lzdGVtIiBdOyB0aGVuCiAgICAjIHNoZWxsY2hlY2sgc291cmNlPXV0aWwtc3lzdGVtLnNoCiAgICBzb3VyY2UgIiR1dGlsX3N5c3RlbSIKZmkKIyEvYmluL2Jhc2gKIyBUaGlzIGZpbGUgaXMgaW50ZW5kZWQgdG8gYmUgc291cmNlZCBieSBib290c3RyYXBwaW5nIHNjcmlwdHMgZm9yIGNvbW1vbmx5IHVzZWQgZnVuY3Rpb25zCgojIGdldF9ib290X2Rldl91dWlkCiMgR2V0IHRoZSBib290IGRldmljZXMgdXVpZAojIGFyZ3M6CiMgMSkgYm9vdF9kZXZfdXVpZCAtIG5hbWVyZWYsIHN0cmluZzsgRW1wdHkgdmFyaWFibGUgZm9yIGJvb3QgZGV2aWNlIHV1aWQgYXNzaWdubWVudAojIFRha2VuIGFuZCByZWZhY3RvcmVkIGZyb20gaHR0cHM6Ly9lbmcubXMvZG9jcy9wcm9kdWN0cy9henVyZS1saW51eC9mZWF0dXJlcy9zZWN1cml0eS9maXBzCmdldF9ib290X2Rldl91dWlkKCkgewogICAgbG9jYWwgLW4gYm9vdF9kZXZfdXVpZD0iJDEiCiAgICAjIFNldCBib290X3V1aWQgdmFyaWFibGUgZm9yIHRoZSBib290IHBhcnRpdGlvbiBpZiBkaWZmZXJlbnQgZnJvbSB0aGUgcm9vdAogICAgYm9vdF9kZXY9IiQoZGYgL2Jvb3QvIHwgdGFpbCAtMSB8IGN1dCAtZCcgJyAtZjEpIgogICAgcm9vdF9kZXY9IiQoZGYgLyB8IHRhaWwgLTEgfCBjdXQgLWQnICcgLWYxKSIKCiAgICBib290X2Rldl91dWlkPSIkcm9vdF9kZXYiCiAgICBpZiBbICIkYm9vdF9kZXYiICE9ICIkcm9vdF9kZXYiIF07IHRoZW4KICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBib290X2Rldl91dWlkPSJib290PVVVSUQ9JChibGtpZCAiJGJvb3RfZGV2IiAtcyBVVUlEIC1vIHZhbHVlKSIKICAgIGZpCn0KCiMgZmlwc192ZXJpZnkKIyBWZXJpZnkgdGhhdCBmaXBzIG1vZGUgaXMgZW5hYmxlZAojIFRha2VuIGFuZCByZWZhY3RvcmVkIGZyb20gaHR0cHM6Ly9lbmcubXMvZG9jcy9wcm9kdWN0cy9henVyZS1saW51eC9mZWF0dXJlcy9zZWN1cml0eS9maXBzCmZpcHNfdmVyaWZ5KCkgewogICAgZmlwc19lbmFibGVkX3Byb2M9IiQoY2F0IC9wcm9jL3N5cy9jcnlwdG8vZmlwc19lbmFibGVkKSIKICAgIGZpcHNfZW5hYmxlZF9zeXNjdGw9IiQoc3lzY3RsIC1uIGNyeXB0by5maXBzX2VuYWJsZWQpIgogICAgaWYgWyAiJGZpcHNfZW5hYmxlZF9wcm9jIiAtbmUgMSBdIHx8IFsgIiRmaXBzX2VuYWJsZWRfc3lzY3RsIiAtbmUgMSBdOyB0aGVuCiAgICAgICAgYWJvcnQgIkZJUFMgbW9kZSBpcyBkaXNhYmxlZCIKICAgIGZpCgogICAgbG9nICJGSVBTIG1vZGUgaXMgZW5hYmxlZCIKfQoKIyBmaXBzX2NvbmZpZ3VyZQojIENvbmZpZ3VyZXMgVk0gdG8gcnVuIHdpdGggZmlwcyBtb2RlIGVuYWJsZWQKIyBUYWtlbiBhbmQgcmVmYWN0b3JlZCBmcm9tIGh0dHBzOi8vZW5nLm1zL2RvY3MvcHJvZHVjdHMvYXp1cmUtbGludXgvZmVhdHVyZXMvc2VjdXJpdHkvZmlwcwojIFRPRE8gcmVtb3ZlIHRoaXMgb25jZSBza3UgY2JsLW1hcmluZXItMi1nZW4yLWZpcHMgaXMgc3VwcG9ydGVkIGJ5IGF1dG9tYXRpYyBPUyB1cGRhdGVzCiMgUmVmZXJlbmNlOiBodHRwczovL2xlYXJuLm1pY3Jvc29mdC5jb20vZW4tdXMvYXp1cmUvdmlydHVhbC1tYWNoaW5lLXNjYWxlLXNldHMvdmlydHVhbC1tYWNoaW5lLXNjYWxlLXNldHMtYXV0b21hdGljLXVwZ3JhZGUjc3VwcG9ydGVkLW9zLWltYWdlcwpmaXBzX2NvbmZpZ3VyZSgpIHsKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgYm9vdF91dWlkCiAgICBnZXRfYm9vdF9kZXZfdXVpZCBib290X3V1aWQKCiAgICBsb2NhbCBncnViMl9lbnYKICAgIGlmIGdydWIyX2Vudj0iJChncnViMi1lZGl0ZW52IC0gbGlzdCB8IGdyZXAga2VybmVsb3B0cykiOyB0aGVuCiAgICAgICAgZ3J1YjItZWRpdGVudiAtIHNldCAiJGdydWIyX2VudiBmaXBzPTEgJGJvb3RfdXVpZCIKICAgIGVsc2UKICAgICAgICBncnViYnkgLS11cGRhdGUta2VybmVsPUFMTCAtLWFyZ3M9ImZpcHM9MSAkYm9vdF91dWlkIgogICAgZmkKCiAgICAjIGZpcHMgbW9kZSB2ZXJpZmljYXRpb24gd2lsbCBmYWlsIHVudGlsIGFmdGVyIHRoZSB2bSBoYXMgYmVlbiByZWJvb3RlZAogICAgIyBmaXBzX3ZlcmlmeQp9CgojIGNvbmZpZ3VyZV9zc2hkCiMgV2UgbmVlZCB0byBjb25maWd1cmUgUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB0byB5ZXMgaW4gb3JkZXIgZm9yIHRoZSBWTVNTIEFjY2VzcyBKSVQgdG8gd29yawpjb25maWd1cmVfc3NoZCgpIHsKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2NhbCAtciBzc2hkX2NvbmZpZz0iL2V0Yy9zc2gvc3NoZF9jb25maWciCgogICAgbG9nICJFZGl0aW5nICRzc2hkX2NvbmZpZyB0byBhbGxvdyBwYXNzd29yZCBhdXRoZW50aWNhdGlvbiIKICAgIHNlZCAtaSAncy9QYXNzd29yZEF1dGhlbnRpY2F0aW9uIG5vL1Bhc3N3b3JkQXV0aGVudGljYXRpb24geWVzL2cnICIkc3NoZF9jb25maWciCgogICAgc3lzdGVtY3RsIHJlbG9hZCBzc2hkLnNlcnZpY2UgfHwgYWJvcnQgInNzaGQgZmFpbGVkIHRvIHJlbG9hZCIKfQoKIyBjb25maWd1cmVfbG9ncm90YXRlIGNsb2JiZXJzIC9ldGMvbG9ncm90YXRlLmNvbmYKIyBhcmdzOgojIDEpIGRyb3Bpbl9maWxlcyAtIG5hbWVyZWYsIGFzc29jaWF0aXZlIGFycmF5LCBvcHRpb25hbDsgbG9ncm90YXRlIGZpbGVzIHRvIHdyaXRlIHRvIC9ldGMvbG9ncm90YXRlLmQKIyAgICAgICBLZXkgbmFtZSBkaWN0YXRlcyBmaWxlbmFtZXMgd3JpdHRlbiB0byAvZXRjL2xvZ3JvdGF0ZS5kLgojIEV4YW1wbGU6CiMgICBLZXkgZGljdGF0ZXMgdGhlIGZpbGVuYW1lIHdyaXR0ZW4gaW4gL2V0Yy9sb2dyb3RhdGUuZAojICAgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAojICAgbG9jYWwgLXJBIGxvZ3JvdGF0ZV9kcm9waW5zPSgKIyAgICAgIFsiZ2F0ZXdheSJdPSIkZ2F0ZXdheV9sb2dfZmlsZSIKIyAgICkKY29uZmlndXJlX2xvZ3JvdGF0ZSgpIHsKICAgIGxvY2FsIC1uIGRyb3Bpbl9maWxlcz0iJHsxOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGxvZ3JvdGF0ZV9jb25mX2ZpbGVuYW1lPScvZXRjL2xvZ3JvdGF0ZS5jb25mJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBsb2dyb3RhdGVfY29uZl9maWxlPScjIHNlZSAibWFuIGxvZ3JvdGF0ZSIgZm9yIGRldGFpbHMKIyByb3RhdGUgbG9nIGZpbGVzIHdlZWtseQp3ZWVrbHkKCiMga2VlcCAyIHdlZWtzIHdvcnRoIG9mIGJhY2tsb2dzCnJvdGF0ZSAyCgojIGNyZWF0ZSBuZXcgKGVtcHR5KSBsb2cgZmlsZXMgYWZ0ZXIgcm90YXRpbmcgb2xkIG9uZXMKY3JlYXRlCgojIHVzZSBkYXRlIGFzIGEgc3VmZml4IG9mIHRoZSByb3RhdGVkIGZpbGUKZGF0ZWV4dAoKIyB1bmNvbW1lbnQgdGhpcyBpZiB5b3Ugd2FudCB5b3VyIGxvZyBmaWxlcyBjb21wcmVzc2VkCmNvbXByZXNzCgojIFJQTSBwYWNrYWdlcyBkcm9wIGxvZyByb3RhdGlvbiBpbmZvcm1hdGlvbiBpbnRvIHRoaXMgZGlyZWN0b3J5CmluY2x1ZGUgL2V0Yy9sb2dyb3RhdGUuZAoKIyBubyBwYWNrYWdlcyBvd24gd3RtcCBhbmQgYnRtcCAtLSB3ZSB3aWxsIHJvdGF0ZSB0aGVtIGhlcmUKL3Zhci9sb2cvd3RtcCB7CiAgICBtb250aGx5CiAgICBjcmVhdGUgMDY2NCByb290IHV0bXAKICAgICAgICBtaW5zaXplIDFNCiAgICByb3RhdGUgMQp9CgovdmFyL2xvZy9idG1wIHsKICAgIG1pc3NpbmdvawogICAgbW9udGhseQogICAgY3JlYXRlIDA2MDAgcm9vdCB1dG1wCiAgICByb3RhdGUgMQp9JwoKICAgIHdyaXRlX2ZpbGUgbG9ncm90YXRlX2NvbmZfZmlsZW5hbWUgbG9ncm90YXRlX2NvbmZfZmlsZSB0cnVlCgogICAgaWYgWyAtbiAiJHtkcm9waW5fZmlsZXNbKl19IiBdOyB0aGVuCiAgICAgICAgbG9jYWwgLXIgbG9ncm90YXRlX2Q9Ii9ldGMvbG9ncm90YXRlLmQiCiAgICAgICAgbG9nICJXcml0aW5nIGxvZ3JvdGF0ZSBmaWxlcyB0byAkbG9ncm90YXRlX2QiCiAgICAgICAgZm9yIGRyb3Bpbl9uYW1lIGluICIkeyFkcm9waW5fZmlsZXNbQF19IjsgZG8KICAgICAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgICAgIGxvY2FsIC1yIGRyb3Bpbl9maWxlbmFtZT0iJGxvZ3JvdGF0ZV9kLyRkcm9waW5fbmFtZSIKICAgICAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgICAgIGxvY2FsIC1yIGRyb3Bpbl9maWxlPSIke2Ryb3Bpbl9maWxlc1siJGRyb3Bpbl9uYW1lIl19IgogICAgICAgICAgICB3cml0ZV9maWxlIGRyb3Bpbl9maWxlbmFtZSBkcm9waW5fZmlsZSB0cnVlCiAgICAgICAgZG9uZQogICAgZmkKfQoKIyBwdWxsX2NvbnRhaW5lcl9pbWFnZXMKIyBhcmdzOgojIDEpIHB1bGxfaW1hZ2VzIC0gbmFtZXJlZiwgc3RyaW5nIGFycmF5CiMgMikgcmVnaXN0cnlfY29uZiAtIG5hbWVyZWYsIHN0cmluZywgb3B0aW9uYWw7IHBhdGggdG8gZG9ja2VyL3BvZG1hbiBjb25maWd1cmF0aW9uIGZpbGUKcHVsbF9jb250YWluZXJfaW1hZ2VzKCkgewogICAgbG9jYWwgLW4gcHVsbF9pbWFnZXM9IiQxIgogICAgbG9jYWwgLW4gcmVnaXN0cnlfY29uZj0iJHsyOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yaSByZXRyeV90aW1lPTMwCiAgICBjbWQ9KAogICAgICAgIGF6CiAgICAgICAgbG9naW4KICAgICAgICAtaQogICAgICAgIC0tYWxsb3ctbm8tc3Vic2NyaXB0aW9ucwogICAgKQoKICAgIGxvZyAiUnVubmluZyBheiBsb2dpbiB3aXRoIHJldHJpZXMiCiAgICByZXRyeSBjbWQgcmV0cnlfdGltZQoKICAgICMgU3VwcHJlc3MgZW11bGF0aW9uIG91dHB1dCBmb3IgcG9kbWFuIGluc3RlYWQgb2YgZG9ja2VyIGZvciBheiBhY3IgY29tcGF0YWJpbGl0eQogICAgbWtkaXIgLXAgL2V0Yy9jb250YWluZXJzLwogICAgbWtkaXIgLXAgL3Jvb3QvLmRvY2tlcgogICAgdG91Y2ggL2V0Yy9jb250YWluZXJzL25vZG9ja2VyCgogICAgIyBUaGlzIG5hbWUgaXMgdXNlZCBpbiB0aGUgY2FzZSB0aGF0IGF6IGFjciBsb2dpbiBzZWFyY2hlcyBmb3IgdGhpcyBpbiBpdCdzIGVudmlyb25tZW50CiAgICBleHBvcnQgUkVHSVNUUllfQVVUSF9GSUxFPSIvcm9vdC8uZG9ja2VyL2NvbmZpZy5qc29uIgoKICAgIGlmIFsgLW4gIiR7cmVnaXN0cnlfY29uZn0iIF07IHRoZW4KICAgICAgICB3cml0ZV9maWxlIFJFR0lTVFJZX0FVVEhfRklMRSByZWdpc3RyeV9jb25mIHRydWUKICAgIGZpCgogICAgbG9nICJsb2dnaW5nIGludG8gcHJvZCBhY3IiCiAgICBjbWQ9KAogICAgICAgIGF6CiAgICAgICAgYWNyCiAgICAgICAgbG9naW4KICAgICAgICAtLW5hbWUKICAgICAgICAjIFRPRE8gcmVwbGFjZSB0aGlzIHdpdGggdmFyaWFibGUgZXhwYW5zaW9uCiAgICAgICAgIyBSZWZlcmVuY2U6IGh0dHBzOi8vd3d3LnNoZWxsY2hlY2submV0L3dpa2kvU0MyMDAxCiAgICAgICAgIiQoc2VkIC1lICdzfC4qL3x8JyA8PDwiJEFDUlJFU09VUkNFSUQiKSIKICAgICkKCiAgICByZXRyeSBjbWQgcmV0cnlfdGltZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgZm9yIGkgaW4gJHtwdWxsX2ltYWdlc1tAXX07IGRvCiAgICAgICAgbG9jYWwgLW4gaW1hZ2U9IiRpIgogICAgICAgIGNtZD0oCiAgICAgICAgICAgIHBvZG1hbgogICAgICAgICAgICBwdWxsCiAgICAgICAgICAgICIkaW1hZ2UiCiAgICAgICAgKQoKICAgICAgICBsb2cgIlB1bGxpbmcgaW1hZ2UgJGltYWdlIHdpdGggcmV0cmllcyBub3ciCiAgICAgICAgcmV0cnkgY21kIHJldHJ5X3RpbWUKICAgIGRvbmUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGNtZD0oCiAgICAgICAgYXoKICAgICAgICBsb2dvdXQKICAgICkKCiAgICBsb2cgIlJ1bm5pbmcgYXogbG9nb3V0IHdpdGggcmV0cmllcyIKICAgIHJldHJ5IGNtZCByZXRyeV90aW1lCn0KCiMgY29uZmlndXJlX2NlcnRzX2dlbmVyYWwgQ29uZmlndXJlIHN5c3RlbSBjZXJ0aWZpY2F0ZXMgY29tbW9uIHRvIGFsbCBWTVNTIGluc3RhbmNlcwpjb25maWd1cmVfY2VydHNfZ2VuZXJhbCgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgIyBzZXR0aW5nIE1PTklUT1JJTkdfR0NTX0FVVEhfSURfVFlQRT1BdXRoS2V5VmF1bHQgc2VlbXMgdG8gaGF2ZSBjYXVzZWQgbWRzZCBub3QKICAgICMgdG8gaG9ub3VyIFNTTF9DRVJUX0ZJTEUgYW55IG1vcmUsIGhlYXZlbiBvbmx5IGtub3dzIHdoeS4KICAgIGxvY2FsIC1yIHNzbF9jZXJ0c19iYXNlZGlyPSIvdXNyL2xpYi9zc2wvY2VydHMiCiAgICBta2RpciAtcCAiJHNzbF9jZXJ0c19iYXNlZGlyIgogICAgY3NwbGl0IC1mICIkc3NsX2NlcnRzX2Jhc2VkaXIvY2VydC0iIC1iICUwM2QucGVtIC9ldGMvcGtpL3Rscy9jZXJ0cy9jYS1idW5kbGUuY3J0IC9eJC8xICJ7Kn0iIDE+L2Rldi9udWxsCiAgICBjX3JlaGFzaCAiJHNzbF9jZXJ0c19iYXNlZGlyIgp9CgojIGNvbmZpZ3VyZV9jZXJ0c19ycCBDb25maWd1cmUgc3lzdGVtIGNlcnRpZmljYXRlcyBmb3IgUlAgVk1TUwojIGFyZ3M6CmNvbmZpZ3VyZV9jZXJ0c19ycCgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgdmVyaWZ5X3JvbGUgcm9sZV9ycAoKICAgIGxvY2FsIC1yIHJwX2NlcnRzX2Jhc2VkaXI9Ii9ldGMvYXJvLXJwIgogICAgbWtkaXIgLXAgIiRycF9jZXJ0c19iYXNlZGlyIgogICAgYmFzZTY0IC1kIDw8PCIkQURNSU5BUElDQUJVTkRMRSIgPiAiJHJwX2NlcnRzX2Jhc2VkaXIvYWRtaW4tY2EtYnVuZGxlLnBlbSIKICAgIGlmIFtbIC1uICIkQVJNQVBJQ0FCVU5ETEUiIF1dOyB0aGVuCiAgICBiYXNlNjQgLWQgPDw8IiRBUk1BUElDQUJVTkRMRSIgPiAiJHJwX2NlcnRzX2Jhc2VkaXIvYXJtLWNhLWJ1bmRsZS5wZW0iCiAgICBmaQogICAgY2hvd24gLVIgMTAwMDoxMDAwICIkcnBfY2VydHNfYmFzZWRpciIKCiAgICBjb25maWd1cmVfY2VydHNfZ2VuZXJhbAp9CgojIGNvbmZpZ3VyZV9jZXJ0c19nYXRld2F5IENvbmZpZ3VyZSBzeXN0ZW0gY2VydGlmaWNhdGVzIGZvciBHYXRld2F5IFZNU1MgaW5zdGFuY2VzCmNvbmZpZ3VyZV9jZXJ0c19nYXRld2F5KCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICB2ZXJpZnlfcm9sZSByb2xlX2dhdGV3YXkKICAgIGNvbmZpZ3VyZV9jZXJ0c19nZW5lcmFsCn0KCiMgY29uZmlndXJlX2NlcnRzX2RldnByb3h5IENvbmZpZ3VyZSBzeXN0ZW0gY2VydGlmaWNhdGVzIGZvciBkZXZwcm94eSBWTVNTIGluc3RhbmNlcwpjb25maWd1cmVfY2VydHNfZGV2cHJveHkoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHZlcmlmeV9yb2xlIHJvbGVfZGV2cHJveHkKCiAgICBsb2NhbCAtciBwcm94eV9jZXJ0c19iYXNlZGlyPSIvZXRjL3Byb3h5IgogICAgbWtkaXIgLXAgIiRwcm94eV9jZXJ0c19iYXNlZGlyIgogICAgYmFzZTY0IC1kIDw8PCIkUFJPWFlDRVJUIiA+ICIkcHJveHlfY2VydHNfYmFzZWRpci9wcm94eS5jcnQiCiAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUtFWSIgPiAiJHByb3h5X2NlcnRzX2Jhc2VkaXIvcHJveHkua2V5IgogICAgYmFzZTY0IC1kIDw8PCIkUFJPWFlDTElFTlRDRVJUIiA+ICIkcHJveHlfY2VydHNfYmFzZWRpci9wcm94eS1jbGllbnQuY3J0IgogICAgY2hvd24gLVIgMTAwMDoxMDAwIC9ldGMvcHJveHkKICAgIGNobW9kIDA2MDAgIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LmtleSIKfQoKY29uZmlndXJlX2F6c2VjZF9zY2FuKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHdlIGxlYXZlIGNsaWVudElkIGJsYW5rIGFzIGxvbmcgYXMgb25seSAxIG1hbmFnZWQgaWRlbnRpdHkgYXNzaWduZWQgdG8gdm1zcwogICAgIyBpZiB3ZSBoYXZlIG1vcmUgdGhhbiAxLCB3ZSB3aWxsIG5lZWQgdG8gcG9wdWxhdGUgd2l0aCBjbGllbnRJZCB1c2VkIGZvciBvZmYtbm9kZSBzY2FubmluZwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBub2Rlc2Nhbl9hZ2VudF9maWxlbmFtZT0iL2V0Yy9kZWZhdWx0L3ZzYS1ub2Rlc2Nhbi1hZ2VudC5jb25maWciCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG5vZGVzY2FuX2FnZW50X2ZpbGU9InsKICAgIFwiTmljZVwiOiAxOSwKICAgIFwiVGltZW91dFwiOiAxMDgwMCwKICAgIFwiQ2xpZW50SWRcIjogXCJcIiwKICAgIFwiVGVuYW50SWRcIjogJEFaVVJFU0VDUEFDS1ZTQVRFTkFOVElELAogICAgXCJRdWFseXNTdG9yZUJhc2VVcmxcIjogJEFaVVJFU0VDUEFDS1FVQUxZU1VSTCwKICAgIFwiUHJvY2Vzc1RpbWVvdXRcIjogMzAwLAogICAgXCJDb21tYW5kRGVsYXlcIjogMAogIH0iCgogICAgd3JpdGVfZmlsZSBub2Rlc2Nhbl9hZ2VudF9maWxlbmFtZSBub2Rlc2Nhbl9hZ2VudF9maWxlIHRydWUKfQoKIyBydW5fYXpzZWNkX2NvbmZpZ19zY2FuCnJ1bl9henNlY2RfY29uZmlnX3NjYW4oKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGNvbmZpZ3VyZV9henNlY2Rfc2NhbgoKICAgIGxvY2FsIC1hciBjb25maWdzPSgKICAgICAgICAiYmFzZWxpbmUiCiAgICAgICAgImNsYW1hdiIKICAgICAgICAic29mdHdhcmUiCiAgICApCgogICAgbG9nICJTY2FubmluZyBjb25maWd1cmF0aW9uIGZpbGVzIHdpdGggYXpzZWNkICR7Y29uZmlnc1sqXX0iCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBzY2FuIGluICR7Y29uZmlnc1tAXX07IGRvCiAgICAgICAgbG9nICJTY2FubmluZyBjb25maWcgZmlsZSAkc2NhbiBub3ciCiAgICAgICAgL3Vzci9sb2NhbC9iaW4vYXpzZWNkIGNvbmZpZyAtcyAiJHNjYW4iIC1kIFAxRAogICAgZG9uZQp9CgojIGNyZWF0ZV9yZXF1aXJlZF9kaXJzCmNyZWF0ZV9yZXF1aXJlZF9kaXJzKCkgewogICAgY3JlYXRlX2RpcnM9KAogICAgICAgIC92YXIvbG9nL2pvdXJuYWwKICAgICAgICAvdmFyL2xpYi93YWFnZW50L01pY3Jvc29mdC5BenVyZS5LZXlWYXVsdC5TdG9yZQogICAgICAgICMgRG9lcyBub3QgZXhpc3Qgb24gZGV2UHJveHlWTVNTCiAgICAgICAgL3Zhci9vcHQvbWljcm9zb2Z0L2xpbnV4bW9uYWdlbnQKICAgICkKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBkIGluICR7Y3JlYXRlX2RpcnNbQF19OyBkbwogICAgICAgIGxvZyAiQ3JlYXRpbmcgZGlyZWN0b3J5ICRkIgogICAgICAgIG1rZGlyIC1wICIkZCIgfHwgYWJvcnQgImZhaWxlZCB0byBjcmVhdGUgZGlyZWN0b3J5ICRkIgogICAgZG9uZQp9CgojIGZpcmV3YWxsZF9jb25maWd1cmVfYmFja2VuZApmaXJld2FsbGRfY29uZmlndXJlX2JhY2tlbmQoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGxvZyAiQ2hhbmdpbmcgZmlyZXdhbGxkIGJhY2tlbmQgdG8gaXB0YWJsZXMiCiAgICBjb25mX2ZpbGU9Ii9ldGMvZmlyZXdhbGxkL2ZpcmV3YWxsZC5jb25mIgogICAgc2VkIC1pICdzL0ZpcmV3YWxsQmFja2VuZD1uZnRhYmxlcy9GaXJld2FsbEJhY2tlbmQ9aXB0YWJsZXMvZycgIiRjb25mX2ZpbGUiCn0KCiMgZmlyZXdhbGxkX2NvbmZpZ3VyZQojIGFyZ3M6CiMgMSkgcG9ydHMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IHBvcnRzIHRvIGJlIGVuYWJsZWQuCiMgICAgICAgUG9ydHMgbXVzdCBiZSBwb3N0Zml4ZWQgd2l0aCAvdGNwIG9yIC91ZHAKZmlyZXdhbGxkX2NvbmZpZ3VyZSgpIHsKICAgIGxvY2FsIC1uIHBvcnRzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgZmlyZXdhbGxkX2NvbmZpZ3VyZV9iYWNrZW5kCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgc2VydmljZT0oCiAgICAgICAgImZpcmV3YWxsZCIKICAgICkKICAgIGVuYWJsZV9zZXJ2aWNlcyBzZXJ2aWNlCgogICAgbG9nICJFbmFibGluZyBwb3J0cyAke3BvcnRzWypdfSBvbiBkZWZhdWx0IGZpcmV3YWxsZCB6b25lIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgcG9ydCBpbiAke3BvcnRzW0BdfTsgZG8KICAgICAgICBsb2cgIkVuYWJsaW5nIHBvcnQgJHBvcnQgbm93IgogICAgICAgIGZpcmV3YWxsLWNtZCAiLS1hZGQtcG9ydD0kcG9ydCIgXAogICAgICAgICAgICAgICAgICAgICAtLXBlcm1hbmVudAogICAgZG9uZQoKICAgIGxvZyAiV3JpdGluZyBydW50aW1lIGNvbmZpZyB0byBwZXJtYW5lbnQgY29uZmlnIgogICAgZmlyZXdhbGwtY21kIC0tcnVudGltZS10by1wZXJtYW5lbnQKfQoKIyB1dGlsLWNvbW1vbi5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQojIS9iaW4vYmFzaAoKc2V0IC1vIGVycmV4aXQgXAogICAgLW8gcGlwZWZhaWwgXAogICAgLW8gbm91bnNldAoKbWFpbigpIHsKICAgICMgdHJhbnNhY3Rpb24gYXR0ZW1wdCByZXRyeSB0aW1lIGluIHNlY29uZHMKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJpIHJldHJ5X3dhaXRfdGltZT0zMAogICAgbG9jYWwgLXJpIHBrZ19yZXRyeV9jb3VudD02MAoKICAgIGNyZWF0ZV9yZXF1aXJlZF9kaXJzCiAgICBjb25maWd1cmVfc3NoZAogICAgY29uZmlndXJlX3JwbV9yZXBvcyByZXRyeV93YWl0X3RpbWUgXAogICAgICAgICAgICAgICAgICAgICAgICAiJHBrZ19yZXRyeV9jb3VudCIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1hciBleGNsdWRlX3BrZ3M9KAogICAgICAgICIteCBXQUxpbnV4QWdlbnQiCiAgICAgICAgIi14IFdBTGludXhBZ2VudC11ZGV2IgogICAgKQoKICAgIGRuZl91cGRhdGVfcGtncyBleGNsdWRlX3BrZ3MgXAogICAgICAgICAgICAgICAgICAgIHJldHJ5X3dhaXRfdGltZSBcCiAgICAgICAgICAgICAgICAgICAgIiRwa2dfcmV0cnlfY291bnQiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgaW5zdGFsbF9wa2dzPSgKICAgICAgICBjbGFtYXYKICAgICAgICBhenNlYy1jbGFtYXYKICAgICAgICBhenVyZS1jbGkKICAgICAgICBhenVyZS1tZHNkCiAgICAgICAgYXp1cmUtc2VjdXJpdHkKICAgICAgICBwb2RtYW4KICAgICAgICBwb2RtYW4tZG9ja2VyCiAgICAgICAgb3BlbnNzbC1wZXJsCiAgICAgICAgIyBoYWNrIC0gd2UgYXJlIGluc3RhbGxpbmcgcHl0aG9uMyBvbiBob3N0cyBkdWUgdG8gYW4gaXNzdWUgd2l0aCBBenVyZSBMaW51eCBFeHRlbnNpb25zIGh0dHBzOi8vZ2l0aHViLmNvbS9BenVyZS9henVyZS1saW51eC1leHRlbnNpb25zL3B1bGwvMTUwNQogICAgICAgIHB5dGhvbjMKICAgICAgICAjIHJlcXVpcmVkIGZvciBwb2RtYW4gbmV0d29ya2luZwogICAgICAgIGZpcmV3YWxsZAogICAgICAgICMgUmVxdWlyZWQgdG8gZW5hYmxlIGZpcHMKICAgICAgICBncnViYnkKICAgICAgICBkcmFjdXQtZmlwcwogICAgKQoKICAgIGRuZl9pbnN0YWxsX3BrZ3MgaW5zdGFsbF9wa2dzIFwKICAgICAgICAgICAgICAgICAgICAgcmV0cnlfd2FpdF90aW1lIFwKICAgICAgICAgICAgICAgICAgICAgIiRwa2dfcmV0cnlfY291bnQiCgogICAgZmlwc19jb25maWd1cmUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxMTkKICAgIGNvbmZpZ3VyZV9sb2dyb3RhdGUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxNTMgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kbWltYWdlPSIke1JQSU1BR0UlJS8qfS8ke01ETUlNQUdFIyovfSIKICAgIGxvY2FsIC1yIHJwaW1hZ2U9IiRSUElNQUdFIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBmbHVlbnRiaXRfaW1hZ2U9IiRGTFVFTlRCSVRJTUFHRSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJBIGFyb19pbWFnZXM9KAogICAgICAgIFsibWRtIl09Im1kbWltYWdlIgogICAgICAgIFsicnAiXT0icnBpbWFnZSIKICAgICAgICBbImZsdWVudGJpdCJdPSJmbHVlbnRiaXRfaW1hZ2UiCiAgICApCgogICAgcHVsbF9jb250YWluZXJfaW1hZ2VzIGFyb19pbWFnZXMKCiAgICBsb2NhbCAtciBhcm9fbmV0d29yaz0iYXJvIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtckEgbmV0d29ya3M9KAogICAgICAgIFsiJGFyb19uZXR3b3JrIl09IjE5Mi4xNjguMjU0LjAvMjQiCiAgICApCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yYSBlbmFibGVfcG9ydHM9KAogICAgICAgICMgUlAgZnJvbnRlbmQKICAgICAgICAiNDQzL3RjcCIKICAgICAgICAjIFBvcnRhbCB3ZWIKICAgICAgICAiNDQ0L3RjcCIKICAgICAgICAjIFBvcnRhbCBzc2gKICAgICAgICAiMjIyMi90Y3AiCiAgICAgICAgIyBKSVQgc3NoCiAgICAgICAgIjIyL3RjcCIKICAgICkKCiAgICBmaXJld2FsbGRfY29uZmlndXJlIGVuYWJsZV9wb3J0cwoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgZmx1ZW50Yml0X2NvbmZfZmlsZT0iW0lOUFVUXQoJTmFtZSBzeXN0ZW1kCglUYWcgam91cm5hbGQKCVN5c3RlbWRfRmlsdGVyIF9DT01NPWFybwoJREIgL3Zhci9saWIvZmx1ZW50L2pvdXJuYWxkYgoKW0ZJTFRFUl0KCU5hbWUgbW9kaWZ5CglNYXRjaCBqb3VybmFsZAoJUmVtb3ZlX3dpbGRjYXJkIF8KCVJlbW92ZSBUSU1FU1RBTVAKCltGSUxURVJdCglOYW1lIHJld3JpdGVfdGFnCglNYXRjaCBqb3VybmFsZAoJUnVsZSBcJExPR0tJTkQgYXN5bmNxb3MgYXN5bmNxb3MgdHJ1ZQoKW0ZJTFRFUl0KCU5hbWUgbW9kaWZ5CglNYXRjaCBhc3luY3FvcwoJUmVtb3ZlIENMSUVOVF9QUklOQ0lQQUxfTkFNRQoJUmVtb3ZlIEZJTEUKCVJlbW92ZSBDT01QT05FTlQKCltGSUxURVJdCglOYW1lIHJld3JpdGVfdGFnCglNYXRjaCBqb3VybmFsZAoJUnVsZSBcJExPR0tJTkQgaWZ4YXVkaXQgaWZ4YXVkaXQgZmFsc2UKCltPVVRQVVRdCglOYW1lIGZvcndhcmQKCU1hdGNoICoKCVBvcnQgMjkyMzAiCgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRzZF9jb25maWdfdmVyc2lvbj0iJFJQTURTRENPTkZJR1ZFUlNJT04iCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19ycF9jb25mX2ZpbGU9IkFDUl9SRVNPVVJDRV9JRD0nJEFDUlJFU09VUkNFSUQnCkFETUlOX0FQSV9DTElFTlRfQ0VSVF9DT01NT05fTkFNRT0nJEFETUlOQVBJQ0xJRU5UQ0VSVENPTU1PTk5BTUUnCkFSTV9BUElfQ0xJRU5UX0NFUlRfQ09NTU9OX05BTUU9JyRBUk1BUElDTElFTlRDRVJUQ09NTU9OTkFNRScKQVpVUkVfQVJNX0NMSUVOVF9JRD0nJEFSTUNMSUVOVElEJwpBWlVSRV9GUF9DTElFTlRfSUQ9JyRGUENMSUVOVElEJwpBWlVSRV9GUF9TRVJWSUNFX1BSSU5DSVBBTF9JRD0nJEZQU0VSVklDRVBSSU5DSVBBTElEJwpDTFVTVEVSX01ETV9BQ0NPVU5UPSckQ0xVU1RFUk1ETUFDQ09VTlQnCkNMVVNURVJfTURNX05BTUVTUEFDRT1SUApDTFVTVEVSX01EU0RfQUNDT1VOVD0nJENMVVNURVJNRFNEQUNDT1VOVCcKQ0xVU1RFUl9NRFNEX0NPTkZJR19WRVJTSU9OPSckQ0xVU1RFUk1EU0RDT05GSUdWRVJTSU9OJwpDTFVTVEVSX01EU0RfTkFNRVNQQUNFPSckQ0xVU1RFUk1EU0ROQU1FU1BBQ0UnCkRBVEFCQVNFX0FDQ09VTlRfTkFNRT0nJERBVEFCQVNFQUNDT1VOVE5BTUUnCkRPTUFJTl9OQU1FPSckTE9DQVRJT04uJENMVVNURVJQQVJFTlRET01BSU5OQU1FJwpHQVRFV0FZX0RPTUFJTlM9JyRHQVRFV0FZRE9NQUlOUycKR0FURVdBWV9SRVNPVVJDRUdST1VQPSckR0FURVdBWVJFU09VUkNFR1JPVVBOQU1FJwpLRVlWQVVMVF9QUkVGSVg9JyRLRVlWQVVMVFBSRUZJWCcKTURNX0FDQ09VTlQ9JyRSUE1ETUFDQ09VTlQnCk1ETV9OQU1FU1BBQ0U9JyR7cm9sZV9ycF5efScKTURTRF9FTlZJUk9OTUVOVD0nJE1EU0RFTlZJUk9OTUVOVCcKUlBfRkVBVFVSRVM9JyRSUEZFQVRVUkVTJwpSUElNQUdFPSckcnBpbWFnZScKQVJPX0lOU1RBTExfVklBX0hJVkU9JyRDTFVTVEVSU0lOU1RBTExWSUFISVZFJwpBUk9fSElWRV9ERUZBVUxUX0lOU1RBTExFUl9QVUxMU1BFQz0nJENMVVNURVJERUZBVUxUSU5TVEFMTEVSUFVMTFNQRUMnCkFST19BRE9QVF9CWV9ISVZFPSckQ0xVU1RFUlNBRE9QVEJZSElWRScKT0lEQ19BRkRfRU5EUE9JTlQ9JyRMT0NBVElPTi5vaWMuJFJQUEFSRU5URE9NQUlOTkFNRScKT0lEQ19TVE9SQUdFX0FDQ09VTlRfTkFNRT0nJE9JRENTVE9SQUdFQUNDT1VOVE5BTUUnCk1TSV9SUF9FTkRQT0lOVD0nJE1TSVJQRU5EUE9JTlQnCiIKCiAgICAjIHZhbHVlcyBhcmUgcmVmZXJlbmNlcyB0byB2YXJpYWJsZXMsIHRoZXkgc2hvdWxkIG5vdCBiZSBkZXJlZmVyZW5jZWQgaGVyZQogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtckEgYXJvX2NvbmZpZ3M9KAogICAgICAgIFsicnBfY29uZmlnIl09ImFyb19ycF9jb25mX2ZpbGUiCiAgICAgICAgWyJmbHVlbnRiaXQiXT0iZmx1ZW50Yml0X2NvbmZfZmlsZSIKICAgICAgICBbIm1kc2QiXT0ibWRzZF9jb25maWdfdmVyc2lvbiIKICAgICAgICBbIm5ldHdvcmsiXT0iYXJvX25ldHdvcmsiCiAgICApCgogICAgY29uZmlndXJlX3Ztc3NfYXJvX3NlcnZpY2VzIHJvbGVfcnAgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyb19pbWFnZXMgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyb19jb25maWdzCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgYXJvX3NlcnZpY2VzPSgKICAgICAgICAiYXJvLW1vbml0b3IiCiAgICAgICAgImFyby1wb3J0YWwiCiAgICAgICAgImFyby1ycCIKICAgICAgICAiYXpzZWNkIgogICAgICAgICJtZHNkIgogICAgICAgICJtZG0iCiAgICAgICAgImNocm9ueWQiCiAgICAgICAgImZsdWVudGJpdCIKICAgICAgICAiZG93bmxvYWQtbWRzZC1jcmVkZW50aWFscy50aW1lciIKICAgICAgICAiZG93bmxvYWQtbWRtLWNyZWRlbnRpYWxzLnRpbWVyIgogICAgICAgICJmaXJld2FsbGQiCiAgICApCgogICAgZW5hYmxlX3NlcnZpY2VzIGFyb19zZXJ2aWNlcwoKICAgIHJlYm9vdF92bQp9CgojIFRoaXMgdmFyaWFibGUgaXMgdXNlZCBieSBhei1jbGkKIyBJdCdzIGFzc3VtZWQgdGhhdCBpZiB0aGlzIHZhcmlhYmxlIGhhc24ndCBiZWVuIGNhcnJpZWQgb3ZlciwgdGhhdCBvdGhlcnMgYXJlIGFsc28gbm90IHByZXNlbnQsIHNvIHdlIGZhaWwgZWFybHkgYnkgcmV0dXJuaW5nIGFuIGVycm9yCiMgVGhpcyB3YXMgbW9zdGx5IGhlbHBmdWwgd2hlbiB0ZXN0aW5nIG9uIGEgZGV2ZWxvcG1lbnQgVk0sIGJ1dCBpcyBzdGlsbCBhcHBsaWNhYmxlCmV4cG9ydCBBWlVSRV9DTE9VRF9OQU1FPSIke0FaVVJFQ0xPVUROQU1FOj8iRmFpbGVkIHRvIGNhcnJ5IG92ZXIgdmFyaWFibGVzIn0iCgojIHV0aWwuc2ggZG9lcyBub3QgZXhpc3Qgd2hlbiBkZXBsb3llZCB0byBWTVNTIHZpYSBWTVNTIGV4dGVuc2lvbnMKIyBQcm92aWRlcyBzaGVsbGNoZWNrIGRlZmluaXRpb25zCnV0aWw9InV0aWwuc2giCmlmIFsgLWYgIiR1dGlsIiBdOyB0aGVuCiAgICAjIHNoZWxsY2hlY2sgc291cmNlPXV0aWwuc2gKICAgIHNvdXJjZSAiJHV0aWwiCmZpCgptYWluICIkQCIK')))]" + "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'ACRRESOURCEID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('acrResourceId')),''')\n','ADMINAPICLIENTCERTCOMMONNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('adminApiClientCertCommonName')),''')\n','ARMAPICLIENTCERTCOMMONNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('armApiClientCertCommonName')),''')\n','ARMCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('armClientId')),''')\n','AZURECLOUDNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureCloudName')),''')\n','AZURESECPACKQUALYSURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackQualysUrl')),''')\n','AZURESECPACKVSATENANTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackVSATenantId')),''')\n','CLUSTERMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdmAccount')),''')\n','CLUSTERMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdAccount')),''')\n','CLUSTERMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdConfigVersion')),''')\n','CLUSTERMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdNamespace')),''')\n','CLUSTERPARENTDOMAINNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterParentDomainName')),''')\n','DATABASEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('databaseAccountName')),''')\n','FLUENTBITIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fluentbitImage')),''')\n','FPCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fpClientId')),''')\n','FPTENANTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fpTenantId')),''')\n','FPSERVICEPRINCIPALID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fpServicePrincipalId')),''')\n','GATEWAYDOMAINS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayDomains')),''')\n','GATEWAYRESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayResourceGroupName')),''')\n','GATEWAYSERVICEPRINCIPALID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayServicePrincipalId')),''')\n','KEYVAULTDNSSUFFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultDNSSuffix')),''')\n','KEYVAULTPREFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultPrefix')),''')\n','MDMFRONTENDURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdmFrontendUrl')),''')\n','MDSDENVIRONMENT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdsdEnvironment')),''')\n','MSIRPENDPOINT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('msiRpEndpoint')),''')\n','PORTALACCESSGROUPIDS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalAccessGroupIds')),''')\n','PORTALCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalClientId')),''')\n','PORTALELEVATEDGROUPIDS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalElevatedGroupIds')),''')\n','RPFEATURES=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpFeatures')),''')\n','RPIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpImage')),''')\n','RPMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdmAccount')),''')\n','RPMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdAccount')),''')\n','RPMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdConfigVersion')),''')\n','RPMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdNamespace')),''')\n','RPPARENTDOMAINNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpParentDomainName')),''')\n','OIDCSTORAGEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('oidcStorageAccountName')),''')\n','CLUSTERSINSTALLVIAHIVE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clustersInstallViaHive')),''')\n','CLUSTERSADOPTBYHIVE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clustersAdoptByHive')),''')\n','CLUSTERDEFAULTINSTALLERPULLSPEC=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterDefaultInstallerPullspec')),''')\n','MISEVALIDAUDIENCES=$(base64 -d \u003c\u003c\u003c''',base64(string(parameters('miseValidAudiences'))),''')\n','MISEVALIDAPPIDS=$(base64 -d \u003c\u003c\u003c''',base64(string(parameters('miseValidAppIDs'))),''')\n','ADMINAPICABUNDLE=''',parameters('adminApiCaBundle'),'''\n','ARMAPICABUNDLE=''',parameters('armApiCaBundle'),'''\n','MDMIMAGE=''/distroless/genevamdm:2.2024.626.1539-d1a6e7-20240715t0935@sha256:372fbc981bbfdf2b9a9d0ffdca2c51ed389b291a3bcff0401e9afb0c01605823''\n','OTELIMAGE=''mcr.microsoft.com/oss/otel/opentelemetry-collector-contrib:0.95.0-linux-amd64''\n','MISEIMAGE=''/mise:1.0.02773.115-mise-cbl-mariner2.0-distroless''\n','LOCATION=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().location),''')\n','SUBSCRIPTIONID=$(base64 -d \u003c\u003c\u003c''',base64(subscription().subscriptionId),''')\n','RESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().name),''')\n','\n',base64ToString('IyEvYmluL2Jhc2gKIyBJbnRlcm5hbCBGdW5jdGlvbnMgYW5kIENvbnN0YW50cwoKIyBlbXB0eV9zdHIgLSBjb25zdGFudDsgdXNlZCBieSBmdW5jdGlvbnMgZm9yIG9wdGlvbmFsIG5hbWVyZWYgc3RyaW5nIGFyZ3VlbWVudHMKIyBlbXB0eV9zdHI9IiIKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CmRlY2xhcmUgLXIgZW1wdHlfc3RyPSIiCgojIHJvbGVfZ2F0ZXdheSAtIGNvbnN0YW50OyBJcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHRoaXMgc2hvdWxkIGJlIHJlZmVyZW5jZWQgYnkgc2NyaXB0cyBzb3VyY2luZyB0aGlzIGZpbGUKIyByb2xlX2dhdGV3YXk9ImdhdGV3YXkiCmRlY2xhcmUgLXIgcm9sZV9nYXRld2F5PSJnYXRld2F5IgojIHJvbGVfcnAgLSBjb25zdGFudDsgSXMgdXNlZCB0byBkZXRlcm1pbmUgd2hpY2ggVk1TUyBpcyBiZWluZyBib290c3RyYXBwZWQKIyB0aGlzIHNob3VsZCBiZSByZWZlcmVuY2VkIGJ5IHNjcmlwdHMgc291cmNpbmcgdGhpcyBmaWxlCiMgcm9sZV9ycD0icnAiCmRlY2xhcmUgLXIgcm9sZV9ycD0icnAiCiMgcm9sZV9kZXZwcm94eSAtIGNvbnN0YW50OyBJcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHJvbGVfZGV2cHJveHk9ImRldnByb3h5IgpkZWNsYXJlIC1yIHJvbGVfZGV2cHJveHk9ImRldnByb3h5IgoKIyBsb2cgaXMgYSB3cmFwcGVyIGZvciBlY2hvIHRoYXQgaW5jbHVkZXMgdGhlIGZ1bmN0aW9uIG5hbWUKIyBBcmdzCiMgMSkgbXNnIC0gc3RyaW5nCiMgMikgc3RhY2tfbGV2ZWwgLSBpbnQ7IG9wdGlvbmFsLCBkZWZhdWx0cyB0byB0aGUgZnVuY3Rpb24gYXQgdGhlIGJvdHRvbSBvZiB0aGUgY2FsbCBzdGFjawpsb2coKSB7CiAgICBsb2NhbCAtciBtc2c9IiR7MTotImxvZyBtZXNzYWdlIGlzIGVtcHR5In0iCiAgICBsb2NhbCAtciBzdGFja19sZXZlbD0iJHsyOi0xfSIKICAgIGVjaG8gIiR7RlVOQ05BTUVbJHtzdGFja19sZXZlbH1dfTogJHttc2d9Igp9CgojIGFib3J0IGlzIGEgd3JhcHBlciBmb3IgbG9nIHRoYXQgZXhpdHMgd2l0aCBhbiBlcnJvciBjb2RlCmFib3J0KCkgewogICAgbG9jYWwgLXJpIG9yaWdpbl9zdGFja2xldmVsPTIKICAgIGxvZyAiJHsxfSIgIiRvcmlnaW5fc3RhY2tsZXZlbCIKICAgIGxvZyAiRXhpdGluZyIKICAgIGV4aXQgMQp9CgojIHdyaXRlX2ZpbGUKIyBBcmdzCiMgMSkgZmlsZW5hbWUgLSBzdHJpbmcKIyAyKSBmaWxlX2NvbnRlbnRzIC0gc3RyaW5nCiMgMykgY2xvYmJlciAtIGJvb2xlYW47IG9wdGlvbmFsIC0gZGVmYXVsdHMgdG8gZmFsc2UKd3JpdGVfZmlsZSgpIHsKICAgIGxvY2FsIC1uIGZpbGVuYW1lPSIkMSIKICAgIGxvY2FsIC1uIGZpbGVfY29udGVudHM9IiQyIgogICAgbG9jYWwgLXIgY2xvYmJlcj0iJHszOi1mYWxzZX0iCgogICAgaWYgJGNsb2JiZXI7IHRoZW4KICAgICAgICBsb2cgIk92ZXJ3cml0aW5nIGZpbGUgJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+ICIkZmlsZW5hbWUiCiAgICBlbHNlCiAgICAgICAgbG9nICJBcHBlbmRpbmcgdG8gJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+PiAiJGZpbGVuYW1lIgogICAgZmkKfQoKIyByZXRyeSBBZGRpbmcgcmV0cnkgbG9naWMgdG8geXVtIGNvbW1hbmRzIGluIG9yZGVyIHRvIGF2b2lkIHN0YWxsaW5nIG91dCBvbiByZXNvdXJjZSBsb2NrcwojIGFyZ3M6CiMgMSkgY21kX3JldHJ5IC0gbmFtZXJlZiwgYXJyYXk7IENvbW1hbmQgYW5kIGFyZ3VlbWVudChzKSB0byByZXRyeQojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CnJldHJ5KCkgewogICAgbG9jYWwgLW4gY21kX3JldHJ5PSIkMSIKICAgIGxvY2FsIC1uIHdhaXRfdGltZT0iJDIiCiAgICBsb2NhbCAtcmkgcmV0cmllcz0iJHszOi01fSIKCiAgICAKICAgIGZvciBhdHRlbXB0IGluICQoc2VxIDEgJHJldHJpZXMpOyBkbwogICAgICAgIGxvZyAiYXR0ZW1wdCAjJHthdHRlbXB0fSAtICR7RlVOQ05BTUVbMl19IgogICAgICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgICAgICR7Y21kX3JldHJ5W0BdfSAmCgogICAgICAgIHdhaXQgLWYgJCEgJiYgcmV0dXJuIDAKICAgICAgICBzbGVlcCAiJHdhaXRfdGltZSIKICAgIGRvbmUKCiAgICBhYm9ydCAiJHtjbWRfcmV0cnlbKl19IGZhaWxlZCBhZnRlciAjJHJldHJpZXMgYXR0ZW1wdHMiCn0KCiMgdmVyaWZ5X3JvbGUKIyBhcmdzOgojIDEpIHRlc3Rfcm9sZSAtIG5hbWVyZWY7IHJvbGUgYmVpbmcgdmVyaWZpZWQKdmVyaWZ5X3JvbGUoKSB7CiAgICBsb2NhbCAtbiB0ZXN0X3JvbGU9IiQxIgoKICAgIGFsbG93ZWRfcm9sZXNfZ2xvYj0iKCRyb2xlX3JwfCRyb2xlX2dhdGV3YXl8JHJvbGVfZGV2cHJveHkpIgogICAgaWYgW1sgIiR0ZXN0X3JvbGUiID1+ICRhbGxvd2VkX3JvbGVzX2dsb2IgXV07IHRoZW4KICAgICAgICBsb2cgIlZlcmlmaWVkIHJvbGUgXCIkdGVzdF9yb2xlXCIiCiAgICBlbHNlCiAgICAgICAgYWJvcnQgImZhaWxlZCB0byB2ZXJpZnkgcm9sZSwgcm9sZSBcIiR7dGVzdF9yb2xlfVwiIG5vdCBpbiBcIiR7YWxsb3dlZF9yb2xlc19nbG9ifVwiIgogICAgZmkKfQoKIyBnZXRfa2V5dmF1bHRfc3VmZml4CiMgYXJnczoKIyAxKSBybCAtIG5hbWVyZWYsIHN0cmluZzsgcm9sZSB0byBnZXQgc2hvcnQgcm9sZSBmb3IKIyAyKSBrdl9zdWZmaXggLSBuYW1lcmVmLCBzdHJpbmc7IHNob3J0IHJvbGUgd2lsbCBiZSBhc3NpZ25lZCB0byB0aGlzIG5hbWVyZWYKIyAzKSBzZWNfcHJlZml4IC0gbmFtZXJlZiwgc3RyaW5nOyBrZXl2YXVsdCBjZXJ0aWZpY2F0ZSBwcmVmaXggd2lsbCBiZSBhc3NpZ25lZCB0byB0aGlzIG5hbWVyZWYKZ2V0X2tleXZhdWx0X3N1ZmZpeCgpIHsKICAgIGxvY2FsIC1uIHJsPSIkMSIKICAgIGxvY2FsIC1uIGt2X3N1ZmZpeD0iJDIiCiAgICBsb2NhbCAtbiBzZWNfcHJlZml4PSIkMyIKCiAgICBsb2NhbCAtciBrZXl2YXVsdF9zdWZmaXhfcnA9InN2YyIKICAgIGxvY2FsIC1yIGtleXZhdWx0X3ByZWZpeF9nYXRld2F5PSJnd3kiCgogICAgY2FzZSAiJHJsIiBpbgogICAgICAgICIkcm9sZV9nYXRld2F5IikKICAgICAgICAgICAga3Zfc3VmZml4PSIka2V5dmF1bHRfcHJlZml4X2dhdGV3YXkiCiAgICAgICAgICAgIHNlY19wcmVmaXg9IiRrZXl2YXVsdF9wcmVmaXhfZ2F0ZXdheSIKICAgICAgICAgICAgOzsKICAgICAgICAiJHJvbGVfcnAiKQogICAgICAgICAgICBrdl9zdWZmaXg9IiRrZXl2YXVsdF9zdWZmaXhfcnAiCiAgICAgICAgICAgIHNlY19wcmVmaXg9IiRyb2xlX3JwIgogICAgICAgICAgICA7OwogICAgICAgICopCiAgICAgICAgICAgIGFib3J0ICJ1bmtvd24gcm9sZSAkcmwiCiAgICAgICAgICAgIDs7CiAgICBlc2FjCn0KCiMgcmVib290X3ZtIHJlc3RvcmVzIGNhbGxzIHNodXRkb3duIC1yIGluIGEgc3Vic2hlbGwKIyBSZWJvb3RzIHNob3VsZCBzY2hlZHVsZWQgYWZ0ZXIgYWxsIFZNIGV4dGVuc2lvbnMgaGF2ZSBoYWQgdGltZSB0byBjb21wbGV0ZQojIFJlZmVyZW5jZTogaHR0cHM6Ly9sZWFybi5taWNyb3NvZnQuY29tL2VuLXVzL2F6dXJlL3ZpcnR1YWwtbWFjaGluZXMvZXh0ZW5zaW9ucy9jdXN0b20tc2NyaXB0LWxpbnV4I3RpcHMKcmVib290X3ZtKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICAoc2h1dGRvd24gLXIgbm93ICYpCn0KIyEvYmluL2Jhc2gKIyBSZXBvc2l0b3J5IGFuZCBwYWNrYWdlIG1hbmFnZW1lbnQgcmVsYXRlZCBmdW5jdGlvbnMKCmNvbmZpZ3VyZV9yZXBvX21hcmluZXJfZXh0ZW5kZWQoKSB7CiAgICBsb2NhbCAtciBleHRlbmRlZF9yZXBvX2NvbmZpZz0iaHR0cHM6Ly9wYWNrYWdlcy5taWNyb3NvZnQuY29tL2NibC1tYXJpbmVyLzIuMC9wcm9kL2V4dGVuZGVkL3g4Nl82NC9jb25maWcucmVwbyIKICAgIGN1cmwgLXNTTCAiJGV4dGVuZGVkX3JlcG9fY29uZmlnIiAtbyAvZXRjL3l1bS5yZXBvcy5kL21hcmluZXItZXh0ZW5kZWQucmVwbwoKICAgIGxvY2FsIC1yIHJlcG9fbmFtZT0iY2JsLW1hcmluZXIyLjBwcm9kZXh0ZW5kZWR4ODZfNjQiCgogICAgbG9jYWwgLXJhIGNtZD0oCiAgICAgICAgZG5mCiAgICAgICAgdXBkYXRlCiAgICAgICAgLXkKICAgICAgICAtLWVuYWJsZXJlcG89IiRyZXBvX25hbWUiCiAgICApCgogICAgbG9nICJFbmFibGluZyByZXBvICRyZXBvX25hbWUiCiAgICByZXRyeSBjbWQgIiQxIiAiJHsyOi19Igp9CgojIGNvbmZpZ3VyZV9ycG1fcmVwb3MKIyBOZXcgcmVwb3NpdG9yaWVzIHNob3VsZCBiZSBhZGRlZCBpbiB0aGVpciBvd24gZnVuY3Rpb25zLCBhbmQgY2FsbGVkIGhlcmUKIyBhcmdzOgojIDEpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDIpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1vdW50IG9mIHRpbWVzIHRvIHJldHJ5IGNvbW1hbmQsIGRlZmF1bHRzIHRvIDUKY29uZmlndXJlX3JwbV9yZXBvcygpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgY29uZmlndXJlX3JlcG9fbWFyaW5lcl9leHRlbmRlZCAiJDEiICIkezI6LTF9Igp9CgojIGRuZl9pbnN0YWxsX3BrZ3MKIyBhcmdzOgojIDEpIHBrZ3MgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IFBhY2thZ2VzIHRvIGJlIGluc3RhbGxlZAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1vdW50IG9mIHRpbWVzIHRvIHJldHJ5IGNvbW1hbmQsIGRlZmF1bHRzIHRvIDUKZG5mX2luc3RhbGxfcGtncygpIHsKICAgIGxvY2FsIC1uIHBrZ3M9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgIGRuZgogICAgICAgIC15CiAgICAgICAgaW5zdGFsbAogICAgKQogICAgCiAgICAjIFJlZmVyZW5jZTogaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIyMDYKICAgICMgYXBwZW5kIHBrZ3MgYXJyYXkgdG8gY21kCiAgICBtYXBmaWxlIC1PICQoKCAkeyNjbWRbQF19ICsgMSApKSAtZCAnICcgY21kIDw8PCAiJHtwa2dzW0BdfSIKICAgIGxvY2FsIC1yIGNtZAoKICAgIGxvZyAiQXR0ZW1wdGluZyB0byBpbnN0YWxsIHBhY2thZ2VzOiAke3BrZ3NbKl19IgogICAgcmV0cnkgY21kICIkMiIgIiR7MzotfSIKfQoKCiMgZG5mX3VwZGF0ZV9wa2dzCiMgYXJnczoKIyAxKSBleGNsdWRlcyAtIG5hbWVyZWYsIHN0cmluZyBhcnJheSwgb3B0aW9uYWw7IFBhY2thZ2VzIHRvIGV4Y2x1ZGUgZnJvbSB1cGRhdGluZwojICAgICAgIEVhY2ggaW5kZXggbXVzdCBiZSBwcmVmaXhlZCB3aXRoIC14IAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CmRuZl91cGRhdGVfcGtncygpIHsKICAgIGxvY2FsIC1uIGV4Y2x1ZGVzPSIkezE6LWVtcHR5X3N0cn0iCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGxvY2FsIC1hIGNtZD0oCiAgICAgICAgZG5mCiAgICAgICAgLXkKICAgICAgICAjIFJlcGxhY2VkIHdpdGggZXhjbHVkZXMKICAgICAgICAiIgogICAgICAgIHVwZGF0ZQogICAgICAgIC0tYWxsb3dlcmFzaW5nCiAgICApCgogICAgaWYgWyAtbiAiJHtleGNsdWRlc30iIF07IHRoZW4KICAgICAgICAjIFJlZmVyZW5jZSBodHRwczovL3d3dy5zaGVsbGNoZWNrLm5ldC93aWtpL1NDMjIwNgogICAgICAgIG1hcGZpbGUgLU8gMiBjbWQgPDw8ICIke2V4Y2x1ZGVzW0BdfSIKICAgIGVsc2UKICAgICAgICAjIFJlbW92ZSBlbXB0eSBzdHJpbmcgaWYgd2UgYXJlbid0IHJlcGxhY2luZyB0aGVtLCBwcm9iYWJseSBkb2Vzbid0IG1hdHRlciwgYnV0IHdoeSBub3QgYmUgc2FmZQogICAgICAgIHVuc2V0ICJjbWRbMl0iCiAgICBmaQogICAgbG9jYWwgLXIgY21kCgogICAgbG9nICJVcGRhdGluZyBhbGwgcGFja2FnZXMgZXhjbHVkaW5nIFwiJHtleGNsdWRlc1sqXTotfVwiIgogICAgcmV0cnkgY21kICIkMiIgIiR7MzotfSIKfQoKIyBycG1faW1wb3J0X2tleXMKIyBhcmdzOgojIDEpIGtleXMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IHJwbSBrZXlzIHRvIGJlIGltcG9ydGVkCiMgMikgd2FpdF90aW1lIC0gbmFtZXJlZiwgaW50ZWdlcjsgVGltZSB0byB3YWl0IGJlZm9yZSByZXRyeWluZyBjb21tYW5kCnJwbV9pbXBvcnRfa2V5cygpIHsKICAgIGxvY2FsIC1uIGtleXM9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBrZXkgaW4gJHtrZXlzW0BdfTsgZG8KICAgICAgICBpZiBbICR7I2tleXNbQF19IC1lcSAwIF07IHRoZW4KICAgICAgICAgICAgYnJlYWsKICAgICAgICBmaQoKICAgICAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgICAgICBycG0KICAgICAgICAgICAgLS1pbXBvcnQKICAgICAgICAgICAgLXYKICAgICAgICAgICAgIiRrZXkiCiAgICAgICAgKQoKICAgICAgICBsb2cgIkltcG9ydGluZyBycG0gcmVwb3NpdG9yeSBrZXkgJGtleSIKICAgICAgICByZXRyeSBjbWQgIiQyIiAiJHszOi19IiAmJiB1bnNldCBrZXkKICAgIGRvbmUKfQoKIyB1dGlsLWNvbW1vbi5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQojIS9iaW4vYmFzaAojIEFSTyBzZXJ2aWNlIHNldHVwIGZ1bmN0aW9ucwoKIyBlbmFibGVfc2VydmljZXMgZW5hYmxlcyB0aGUgc3lzdGVtZCBzZXJ2aWNlcyB0aGF0IGFyZSBwYXNzZWQgaW4KIyBhcmdzOgojIDEpIHNlcnZpY2VzIC0gYXJyYXk7IHNlcnZpY2VzIHRvIGJlIGVuYWJsZWQKZW5hYmxlX3NlcnZpY2VzKCkgewogICAgbG9jYWwgLW4gc3Zjcz0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHN5c3RlbWN0bCBkYWVtb24tcmVsb2FkCgogICAgbG9nICJlbmFibGluZyBzZXJ2aWNlcyAke3N2Y3NbKl19IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3Igc3ZjIGluICR7c3Zjc1tAXX07IGRvCiAgICAgICAgbG9nICJFbmFibGluZyBhbmQgc3RhcnRpbmcgJHN2YyBub3ciCiAgICAgICAgc3lzdGVtY3RsIGVuYWJsZSBcCiAgICAgICAgICAgICAgICAgIC0tbm93IFwKICAgICAgICAgICAgICAgICAgIiRzdmMiCiAgICBkb25lCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBjb250YWluZXIgaW1hZ2UKIyAyKSByb2xlIC0gbmFtZXJlZiwgc3RyaW5nOyBWTVNTIHJvbGUKIyAzKSBjb25mX2ZpbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGFybyBnYXRld2F5IGVudmlyb25tZW50IGZpbGUKIyA0KSBpcGFkZHJlc3MgLSBuYW1lcmVmLCBzdHJpbmc7IHN0YXRpYyBpcCBvZiBwb2RtYW4gbmV0d29yayB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9hcm9fZ2F0ZXdheSgpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIHJvbGU9IiQyIgogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMyIKICAgIGxvY2FsIC1uIGlwYWRkcmVzcz0iJDQiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tZ2F0ZXdheSBzZXJ2aWNlIgoKICAgIGxvY2FsIC1yIGFyb19nYXRld2F5X2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1nYXRld2F5JwogICAgbG9jYWwgLXIgYWRkX2NvbmZfZmlsZT0icG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJwpST0xFPScke3JvbGUsLH0nIgoKICAgIHdyaXRlX2ZpbGUgYXJvX2dhdGV3YXlfY29uZl9maWxlbmFtZSBjb25mX2ZpbGUgdHJ1ZQogICAgd3JpdGVfZmlsZSBhcm9fZ2F0ZXdheV9jb25mX2ZpbGVuYW1lIGFkZF9jb25mX2ZpbGUgZmFsc2UKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19nYXRld2F5X3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLWdhdGV3YXkuc2VydmljZScKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19nYXRld2F5X3NlcnZpY2VfZmlsZT0nW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLWdhdGV3YXkKRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtZSBBQ1JfUkVTT1VSQ0VfSUQgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX0ZFQVRVUkVTIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLW0gMmcgXAogIC0tbmV0d29yaz0ke1BPRE1BTl9ORVRXT1JLfSBcCiAgLS1pcCAke0lQQUREUkVTU30gXAogIC1wIDgwOjgwODAgXAogIC1wIDgwODE6ODA4MSBcCiAgLXAgNDQzOjg0NDMgXAogIC12IC9ydW4vc3lzdGVtZC9qb3VybmFsOi9ydW4vc3lzdGVtZC9qb3VybmFsIFwKICAtdiAvdmFyL2V0dzovdmFyL2V0dzp6IFwKICAkUlBJTUFHRSBcCiAgJFJPTEUKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgLXQgMzYwMCAlTgpUaW1lb3V0U3RvcFNlYz0zNjAwClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CiAgICAnCgogICAgd3JpdGVfZmlsZSBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19nYXRld2F5X3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX3JwCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCiMgMikgcm9sZSAtIG5hbWVyZWYsIHN0cmluZzsgVk1TUyByb2xlCiMgMykgY29uZl9maWxlIC0gbmFtZXJlZiwgc3RyaW5nOyBhcm8gcnAgZW52aXJvbm1lbnQgZmlsZQojIDQpIGlwYWRkcmVzcyAtIG5hbWVyZWYsIHN0cmluZzsgc3RhdGljIGlwIG9mIHBvZG1hbiBuZXR3b3JrIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19ycCgpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIHJvbGU9IiQyIgogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMyIKICAgIGxvY2FsIC1uIGlwYWRkcmVzcz0iJDQiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tcnAgc2VydmljZSIKCiAgICBsb2NhbCAtciBhcm9fcnBfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLXJwJwogICAgbG9jYWwgLXIgYWRkX2NvbmZfZmlsZT0icG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJwpST0xFPScke3JvbGUsLH0nIgoKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX2NvbmZfZmlsZW5hbWUgY29uZl9maWxlIHRydWUKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX2NvbmZfZmlsZW5hbWUgYWRkX2NvbmZfZmlsZSBmYWxzZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3JwX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLXJwLnNlcnZpY2UnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19ycF9zZXJ2aWNlX2ZpbGU9J1tVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2Fyby1ycApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC1lIEFDUl9SRVNPVVJDRV9JRCBcCiAgLWUgQURNSU5fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FIFwKICAtZSBBUk1fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FIFwKICAtZSBBWlVSRV9BUk1fQ0xJRU5UX0lEIFwKICAtZSBBWlVSRV9GUF9DTElFTlRfSUQgXAogIC1lIENMVVNURVJfTURNX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURNX05BTUVTUEFDRSBcCiAgLWUgQ0xVU1RFUl9NRFNEX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTiBcCiAgLWUgQ0xVU1RFUl9NRFNEX05BTUVTUEFDRSBcCiAgLWUgREFUQUJBU0VfQUNDT1VOVF9OQU1FIFwKICAtZSBET01BSU5fTkFNRSBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX1JFU09VUkNFR1JPVVAgXAogIC1lIEtFWVZBVUxUX1BSRUZJWCBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1lIE1EU0RfRU5WSVJPTk1FTlQgXAogIC1lIFJQX0ZFQVRVUkVTIFwKICAtZSBBUk9fSU5TVEFMTF9WSUFfSElWRSBcCiAgLWUgQVJPX0hJVkVfREVGQVVMVF9JTlNUQUxMRVJfUFVMTFNQRUMgXAogIC1lIEFST19BRE9QVF9CWV9ISVZFIFwKICAtZSBPSURDX0FGRF9FTkRQT0lOVCBcCiAgLWUgT0lEQ19TVE9SQUdFX0FDQ09VTlRfTkFNRSBcCiAgLWUgTVNJX1JQX0VORFBPSU5UIFwKICAtZSBNSVNFX0FERFJFU1MgXAogIC1tIDJnIFwKICAtLW5ldHdvcms9JHtQT0RNQU5fTkVUV09SS30gXAogIC0taXAgJHtJUEFERFJFU1N9IFwKICAtcCA0NDM6ODQ0MyBcCiAgLXYgL2V0Yy9hcm8tcnA6L2V0Yy9hcm8tcnAgXAogIC12IC9ydW4vc3lzdGVtZC9qb3VybmFsOi9ydW4vc3lzdGVtZC9qb3VybmFsIFwKICAtdiAvdmFyL2V0dzovdmFyL2V0dzp6IFwKICAkUlBJTUFHRSBcCiAgJFJPTEUKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgLXQgMzYwMCAlTgpUaW1lb3V0U3RvcFNlYz0zNjAwClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0JwoKICAgIHdyaXRlX2ZpbGUgYXJvX3JwX3NlcnZpY2VfZmlsZW5hbWUgYXJvX3JwX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX21vbml0b3IKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBSUCBjb250YWluZXIgaW1hZ2UKIyAyKSBpcGFkZHJlc3MgLSBuYW1lcmVmLCBzdHJpbmc7IHN0YXRpYyBpcCBvZiBwb2RtYW4gbmV0d29yayB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9hcm9fbW9uaXRvcigpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIGlwYWRkcmVzcz0iJDIiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8tbW9uaXRvciBzZXJ2aWNlIgoKICAgICMgRE9NQUlOX05BTUUsIENMVVNURVJfTURTRF9BQ0NPVU5ULCBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04sIEdBVEVXQVlfRE9NQUlOUywgR0FURVdBWV9SRVNPVVJDRUdST1VQLCBNRFNEX0VOVklST05NRU5UIENMVVNURVJfTURTRF9OQU1FU1BBQ0UKICAgICMgYXJlIG5vdCB1c2VkLCBidXQgY2FuJ3QgZWFzaWx5IGJlIHJlZmFjdG9yZWQgb3V0LiBTaG91bGQgYmUgcmV2aXNpdGVkIGluIHRoZSBmdXR1cmUuCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLW1vbml0b3InCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlPSJBWlVSRV9GUF9DTElFTlRfSUQ9JyRGUENMSUVOVElEJwpET01BSU5fTkFNRT0nJExPQ0FUSU9OLiRDTFVTVEVSUEFSRU5URE9NQUlOTkFNRScKQ0xVU1RFUl9NRFNEX0FDQ09VTlQ9JyRDTFVTVEVSTURTREFDQ09VTlQnCkNMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTj0nJENMVVNURVJNRFNEQ09ORklHVkVSU0lPTicKR0FURVdBWV9ET01BSU5TPSckR0FURVdBWURPTUFJTlMnCkdBVEVXQVlfUkVTT1VSQ0VHUk9VUD0nJEdBVEVXQVlSRVNPVVJDRUdST1VQTkFNRScKTURTRF9FTlZJUk9OTUVOVD0nJE1EU0RFTlZJUk9OTUVOVCcKQ0xVU1RFUl9NRFNEX05BTUVTUEFDRT0nJENMVVNURVJNRFNETkFNRVNQQUNFJwpDTFVTVEVSX01ETV9BQ0NPVU5UPSckQ0xVU1RFUk1ETUFDQ09VTlQnCkNMVVNURVJfTURNX05BTUVTUEFDRT1CQk0KREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPUJCTQpSUElNQUdFPSckaW1hZ2UnCnBvZG1hbl9uZXR3b3JrPSdwb2RtYW4nCklQQUREUkVTUz0nJGlwYWRkcmVzcyciCgogICAgd3JpdGVfZmlsZSBhcm9fbW9uaXRvcl9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX21vbml0b3Jfc2VydmljZV9jb25mX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21vbml0b3Jfc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9hcm8tbW9uaXRvci5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbW9uaXRvcl9zZXJ2aWNlX2ZpbGU9J1tVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2Fyby1tb25pdG9yCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLS1uZXR3b3JrPSR7UE9ETUFOX05FVFdPUkt9IFwKICAtLWlwICR7SVBBRERSRVNTfSBcCiAgLWUgQVpVUkVfRlBfQ0xJRU5UX0lEIFwKICAtZSBET01BSU5fTkFNRSBcCiAgLWUgQ0xVU1RFUl9NRFNEX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTiBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX1JFU09VUkNFR1JPVVAgXAogIC1lIE1EU0RfRU5WSVJPTk1FTlQgXAogIC1lIENMVVNURVJfTURTRF9OQU1FU1BBQ0UgXAogIC1lIENMVVNURVJfTURNX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURNX05BTUVTUEFDRSBcCiAgLWUgREFUQUJBU0VfQUNDT1VOVF9OQU1FIFwKICAtZSBLRVlWQVVMVF9QUkVGSVggXAogIC1lIE1ETV9BQ0NPVU5UIFwKICAtZSBNRE1fTkFNRVNQQUNFIFwKICAtbSAyLjVnIFwKICAtdiAvcnVuL3N5c3RlbWQvam91cm5hbDovcnVuL3N5c3RlbWQvam91cm5hbCBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJFJQSU1BR0UgXAogIG1vbml0b3IKUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz0xClN0YXJ0TGltaXRJbnRlcnZhbD0wCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQnCgogICAgd3JpdGVfZmlsZSBhcm9fbW9uaXRvcl9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfYXJvX3BvcnRhbAojIGFyZ3M6CiMgMSkgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IFJQIGNvbnRhaW5lciBpbWFnZQojIDIpIGlwYWRkcmVzcyAtIG5hbWVyZWYsIHN0cmluZzsgc3RhdGljIGlwIG9mIHBvZG1hbiBuZXR3b3JrIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19wb3J0YWwoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiBpcGFkZHJlc3M9IiQyIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgYXJvIHBvcnRhbCBzZXJ2aWNlIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1wb3J0YWwnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19wb3J0YWxfc2VydmljZV9jb25mX2ZpbGU9IkFaVVJFX1BPUlRBTF9BQ0NFU1NfR1JPVVBfSURTPSckUE9SVEFMQUNDRVNTR1JPVVBJRFMnCkFaVVJFX1BPUlRBTF9DTElFTlRfSUQ9JyRQT1JUQUxDTElFTlRJRCcKQVpVUkVfUE9SVEFMX0VMRVZBVEVEX0dST1VQX0lEUz0nJFBPUlRBTEVMRVZBVEVER1JPVVBJRFMnCkRBVEFCQVNFX0FDQ09VTlRfTkFNRT0nJERBVEFCQVNFQUNDT1VOVE5BTUUnCktFWVZBVUxUX1BSRUZJWD0nJEtFWVZBVUxUUFJFRklYJwpNRE1fQUNDT1VOVD0nJFJQTURNQUNDT1VOVCcKTURNX05BTUVTUEFDRT1Qb3J0YWwKUE9SVEFMX0hPU1ROQU1FPSckTE9DQVRJT04uYWRtaW4uJFJQUEFSRU5URE9NQUlOTkFNRScKUlBJTUFHRT0nJGltYWdlJwpwb2RtYW5fbmV0d29yaz0ncG9kbWFuJwpJUEFERFJFU1M9JyRpcGFkZHJlc3MnIgoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLXBvcnRhbC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZT0nW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKU3RhcnRMaW1pdEludGVydmFsPTAKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC0tbmV0d29yaz0ke1BPRE1BTl9ORVRXT1JLfSBcCiAgLS1pcCAke0lQQUREUkVTU30gXAogIC1lIEFaVVJFX1BPUlRBTF9BQ0NFU1NfR1JPVVBfSURTIFwKICAtZSBBWlVSRV9QT1JUQUxfQ0xJRU5UX0lEIFwKICAtZSBBWlVSRV9QT1JUQUxfRUxFVkFURURfR1JPVVBfSURTIFwKICAtZSBEQVRBQkFTRV9BQ0NPVU5UX05BTUUgXAogIC1lIEtFWVZBVUxUX1BSRUZJWCBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1lIFBPUlRBTF9IT1NUTkFNRSBcCiAgLW0gMmcgXAogIC1wIDQ0NDo4NDQ0IFwKICAtcCAyMjIyOjIyMjIgXAogIC12IC9ydW4vc3lzdGVtZC9qb3VybmFsOi9ydW4vc3lzdGVtZC9qb3VybmFsIFwKICAtdiAvdmFyL2V0dzovdmFyL2V0dzp6IFwKICAkUlBJTUFHRSBcCiAgcG9ydGFsClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0JwoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19wb3J0YWxfc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9hcm9fbWlzZQojIGFyZ3M6CiMgMSkgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IE1JU0UgY29udGFpbmVyIGltYWdlCiMgMikgaXBhZGRyZXNzIC0gbmFtZXJlZiwgc3RyaW5nOyBzdGF0aWMgaXAgb2YgcG9kbWFuIG5ldHdvcmsgdG8gYmUgYXR0YWNoZWQKY29uZmlndXJlX3NlcnZpY2VfYXJvX21pc2UoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiBpcGFkZHJlc3M9IiQyIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgYXJvLW1pc2Ugc2VydmljZSIKCiAgICBMT0dJTklOU1RBTkNFPSJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20iCiAgICBpZiBbWyAkQVpVUkVDTE9VRE5BTUUgPT0gIkF6dXJlVVNHb3Zlcm5tZW50IiBdXTsgdGhlbgogICAgICAgIExPR0lOSU5TVEFOQ0U9Imh0dHBzOi8vbG9naW4ubWljcm9zb2Z0b25saW5lLnVzIgogICAgZmkKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21pc2Vfc2VydmljZV9jb25mX2ZpbGVuYW1lPScvZXRjL3N5c2NvbmZpZy9hcm8tbWlzZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21pc2Vfc2VydmljZV9jb25mX2ZpbGU9IkZQQ0xJRU5USUQ9JyRGUENMSUVOVElEJwpGUFRFTkFOVElEPSckRlBURU5BTlRJRCcKTUlTRUlNQUdFPSckaW1hZ2UnCk1JU0VWQUxJREFVRElFTkNFUz0nJE1JU0VWQUxJREFVRElFTkNFUycKTUlTRVZBTElEQVBQSURTPSckTUlTRVZBTElEQVBQSURTJwpMT0dJTklOU1RBTkNFPSckTE9HSU5JTlNUQU5DRScKcG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJyIKCiAgICB3cml0ZV9maWxlIGFyb19taXNlX3NlcnZpY2VfY29uZl9maWxlbmFtZSBhcm9fbWlzZV9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgbWtkaXIgLXAgL2FwcC9taXNlCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19taXNlX2FwcHNldHRpbmdzX2ZpbGVuYW1lPScvYXBwL21pc2UvYXBwc2V0dGluZ3MuanNvbicKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21pc2VfYXBwc2V0dGluZ3NfZmlsZT0iewogICAgXCJWZXJzaW9uXCI6IFwiMVwiLAogICAgXCJIZWFydGJlYXRJbnRlcnZhbE1zXCI6IDUwMDAsCiAgICBcIkF6dXJlQWRcIjogewogICAgICAgIFwiSW5zdGFuY2VcIjogXCIkTE9HSU5JTlNUQU5DRVwiLAogICAgICAgIFwiQ2xpZW50SWRcIjogXCIkRlBDTElFTlRJRFwiLAogICAgICAgIFwiVGVuYW50SWRcIjogXCIkRlBURU5BTlRJRFwiLAogICAgICAgIFwiQXVkaWVuY2VcIjogXCJhcGk6Ly8kRlBDTElFTlRJRFwiLAogICAgICAgIFwiU2hvd1BJSVwiOiBmYWxzZSwKICAgICAgICBcIkluYm91bmRQb2xpY2llc1wiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFwiTGFiZWxcIjogXCJhcm9ycC1hcm0taW5ib3VuZC1wb2xpY3lcIiwKICAgICAgICAgICAgICAgIFwiQXV0aG9yaXR5XCI6IFwiJExPR0lOSU5TVEFOQ0UvJEZQVEVOQU5USUQvXCIKLAogICAgICAgICAgICAgICAgXCJBdXRoZW50aWNhdGlvblNjaGVtZXNcIjogWwogICAgICAgICAgICAgICAgICAgIFwiUG9QXCIKICAgICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgICBcIlZhbGlkQXVkaWVuY2VzXCI6ICRNSVNFVkFMSURBVURJRU5DRVMsCiAgICAgICAgICAgICAgICBcIlNpZ25lZEh0dHBSZXF1ZXN0VmFsaWRhdGlvblBvbGljeVwiOiB7CiAgICAgICAgICAgICAgICAgICAgXCJWYWxpZGF0ZVRzXCI6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgXCJWYWxpZGF0ZU1cIjogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBcIlZhbGlkYXRlVVwiOiB0cnVlLAogICAgICAgICAgICAgICAgICAgIFwiVmFsaWRhdGVQXCI6IHRydWUKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBcIlZhbGlkQXBwbGljYXRpb25JZHNcIjogJE1JU0VWQUxJREFQUElEUwogICAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICBcIkxvZ2dpbmdcIjogewogICAgICAgICAgICBcIkxvZ0xldmVsXCI6IFwiSW5mb3JtYXRpb25cIgogICAgICAgIH0sCiAgICAgICAgXCJNb2R1bGVzXCI6IHsKICAgICAgICAgICAgXCJUclYyXCI6IHsKICAgICAgICAgICAgICAgIFwiTW9kdWxlVHlwZVwiOiBcIlRyVjJNb2R1bGVcIiwKICAgICAgICAgICAgICAgIFwiRW5hYmxlZFwiOiB0cnVlCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgXCJBbGxvd2VkSG9zdHNcIjogXCIqXCIsCiAgICBcIktlc3RyZWxcIjogewogICAgICAgIFwiRW5kcG9pbnRzXCI6IHsKICAgICAgICAgICAgXCJIdHRwXCI6IHsKICAgICAgICAgICAgICAgIFwiVXJsXCI6IFwiaHR0cDovLyRpcGFkZHJlc3M6NTAwMFwiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgXCJMb2dnaW5nXCI6IHsKICAgICAgICBcIkxvZ0xldmVsXCI6IHsKICAgICAgICAgICAgXCJEZWZhdWx0XCI6IFwiSW5mb3JtYXRpb25cIiwKICAgICAgICAgICAgXCJNaWNyb3NvZnRcIjogXCJJbmZvcm1hdGlvblwiLAogICAgICAgICAgICBcIk1pY3Jvc29mdC5Ib3N0aW5nLkxpZmV0aW1lXCI6IFwiSW5mb3JtYXRpb25cIgogICAgICAgIH0KICAgIH0KfSIKCiAgICB3cml0ZV9maWxlIGFyb19taXNlX2FwcHNldHRpbmdzX2ZpbGVuYW1lIGFyb19taXNlX2FwcHNldHRpbmdzX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX21pc2Vfc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9hcm8tbWlzZS5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbWlzZV9zZXJ2aWNlX2ZpbGU9J1tVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0ClN0YXJ0TGltaXRJbnRlcnZhbFNlYz0wCltTZXJ2aWNlXQpSZXN0YXJ0U2VjPTFzCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9hcm8tbWlzZQpFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLXAgNTAwMDo1MDAwIFwKICAtdiAvYXBwL21pc2UvYXBwc2V0dGluZ3MuanNvbjovYXBwL2FwcHNldHRpbmdzLmpzb246eiBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLW5ldHdvcms9JHtQT0RNQU5fTkVUV09SS30gXAogIC0taXAgJHtJUEFERFJFU1N9IFwKICAtLXJtIFwKICAkTUlTRUlNQUdFCkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MwpTdGFydExpbWl0SW50ZXJ2YWw9MApbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQnCgogICAgd3JpdGVfZmlsZSBhcm9fbWlzZV9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19taXNlX3NlcnZpY2VfZmlsZSB0cnVlCn0KIyBjb25maWd1cmVfc2VydmljZV9hcm9fb3RlbF9jb2xsZWN0b3IKIyBhcmdzOgojIDEpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBPVEVMIGNvbnRhaW5lciBpbWFnZQojIDIpIHN0YXRpY19pcF9hZGRyZXNzIC0gbmFtZXJlZiwgYXJyYXk7IHN0YXRpYyBpcHMgb2YgYWxsIHNlcnZpY2VzCiMgMykgaXBhZGRyZXNzIC0gbmFtZXJlZiwgc3RyaW5nOyBzdGF0aWMgaXAgb2YgcG9kbWFuIG5ldHdvcmsgdG8gYmUgYXR0YWNoZWQKY29uZmlndXJlX3NlcnZpY2VfYXJvX290ZWxfY29sbGVjdG9yKCkgewogICAgbG9jYWwgLW4gaW1hZ2U9IiQxIgogICAgbG9jYWwgLW4gc3RhdGljX2lwX2FkZHJlc3M9IiQyIgogICAgbG9jYWwgLW4gaXBhZGRyZXNzPSIkMyIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIGFyby1vdGVsLWNvbGxlY3RvciBzZXJ2aWNlIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX290ZWxfY29sbGVjdG9yX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLW90ZWwtY29sbGVjdG9yJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fb3RlbF9jb2xsZWN0b3Jfc2VydmljZV9jb25mX2ZpbGU9IkdPTUVNTElNSVQ9MTAwME1pQgpPVEVMSU1BR0U9JyRpbWFnZScKcG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJyIKCiAgICB3cml0ZV9maWxlIGFyb19vdGVsX2NvbGxlY3Rvcl9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX290ZWxfY29sbGVjdG9yX3NlcnZpY2VfY29uZl9maWxlIHRydWUKCiAgICBta2RpciAtcCAvYXBwL290ZWwKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX290ZWxfY29sbGVjdG9yX2FwcGNvbmZpZ19maWxlbmFtZT0nL2FwcC9vdGVsL2NvbmZpZy55YW1sJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fb3RlbF9jb2xsZWN0b3JfYXBwY29uZmlnX2ZpbGU9InJlY2VpdmVyczoKICBodHRwY2hlY2s6CiAgICB0YXJnZXRzOgogICAgIyBNSVNFIEVuZHBvaW50cwogICAgICAtIGVuZHBvaW50OiBodHRwOi8vJHtzdGF0aWNfaXBfYWRkcmVzc1sibWlzZSJdfTo1MDAwL2hlYWx0aHoKICAgICAgICBtZXRob2Q6IEdFVAogICAgICAtIGVuZHBvaW50OiBodHRwOi8vJHtzdGF0aWNfaXBfYWRkcmVzc1sibWlzZSJdfTo1MDAwL3JlYWR5egogICAgICAgIG1ldGhvZDogR0VUCiAgICAjIE9URUxzIG93biBFbmRwb2ludHMKICAgICAgLSBlbmRwb2ludDogaHR0cDovLyRpcGFkZHJlc3M6MTMxMzMvaGVhbHRoegogICAgICAgIG1ldGhvZDogR0VUCiAgICAgIC0gZW5kcG9pbnQ6IGh0dHA6Ly8kaXBhZGRyZXNzOjEzMTMzL3JlYWR5egogICAgICAgIG1ldGhvZDogR0VUCiAgICBjb2xsZWN0aW9uX2ludGVydmFsOiAyMHMKcHJvY2Vzc29yczoKICBiYXRjaDoKZXh0ZW5zaW9uczoKICBoZWFsdGhfY2hlY2s6CiAgICBlbmRwb2ludDogJGlwYWRkcmVzczoxMzEzMwpleHBvcnRlcnM6CiAgb3RscDoKICAgIGVuZHBvaW50OiAke3N0YXRpY19pcF9hZGRyZXNzWyJtZG0iXX06NDMxNwogICAgdGxzOgogICAgICBpbnNlY3VyZTogdHJ1ZQpzZXJ2aWNlOgogIGV4dGVuc2lvbnM6IFtoZWFsdGhfY2hlY2tdCiAgcGlwZWxpbmVzOgogICAgbWV0cmljczoKICAgICAgcmVjZWl2ZXJzOiBbaHR0cGNoZWNrXQogICAgICBwcm9jZXNzb3JzOiBbYmF0Y2hdCiAgICAgIGV4cG9ydGVyczogW290bHBdIgoKICAgIHdyaXRlX2ZpbGUgYXJvX290ZWxfY29sbGVjdG9yX2FwcGNvbmZpZ19maWxlbmFtZSBhcm9fb3RlbF9jb2xsZWN0b3JfYXBwY29uZmlnX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX290ZWxfY29sbGVjdG9yX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLW90ZWwtY29sbGVjdG9yLnNlcnZpY2UnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19vdGVsX2NvbGxlY3Rvcl9zZXJ2aWNlX2ZpbGU9J1tVbml0XQpBZnRlcj1tZG0uc2VydmljZQpXYW50cz1tZG0uc2VydmljZQpTdGFydExpbWl0SW50ZXJ2YWxTZWM9MApbU2VydmljZV0KUmVzdGFydFNlYz0xcwpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLW90ZWwtY29sbGVjdG9yCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tbmV0d29yaz0ke1BPRE1BTl9ORVRXT1JLfSBcCiAgLS1pcCAkSVBBRERSRVNTIFwKICAtbSAyZyBcCiAgLXYgL2FwcC9vdGVsL2NvbmZpZy55YW1sOi9ldGMvb3RlbGNvbC1jb250cmliL2NvbmZpZy55YW1sOnogXAogICRPVEVMSU1BR0UKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgJU4KUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz0zClN0YXJ0TGltaXRJbnRlcnZhbD0wCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCcKCiAgICB3cml0ZV9maWxlIGFyb19vdGVsX2NvbGxlY3Rvcl9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19vdGVsX2NvbGxlY3Rvcl9zZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX21kc2QKIyBhcmdzOgojIDEpIG1vbml0b3Jpbmdfcm9sZSAtIG5hbWVyZWYsIHN0cmluZzsgY2FuIGJlICJnYXRld2F5IiBvciAicnAiCiMgMikgbW9uaXRvcl9jb25maWdfdmVyc2lvbiAtIG5hbWVyZWYsIHN0cmluZzsgbWRzZCBjb25maWcgdmVyc2lvbgpjb25maWd1cmVfc2VydmljZV9tZHNkKCkgewogICAgbG9jYWwgLW4gcm9sZT0iJDEiCiAgICBsb2NhbCAtbiBtb25pdG9yX2NvbmZpZ192ZXJzaW9uPSIkMiIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgImNvbmZpZ3VyaW5nIG1kc2Qgc2VydmljZSIKCiAgICB2ZXJpZnlfcm9sZSByb2xlCgogICAgbG9jYWwgLXIgbWRzZF9zZXJ2aWNlX2Rpcj0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9tZHNkLnNlcnZpY2UuZCIKICAgIG1rZGlyIC1wICIkbWRzZF9zZXJ2aWNlX2RpciIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kc2Rfb3ZlcnJpZGVfY29uZl9maWxlbmFtZT0iJG1kc2Rfc2VydmljZV9kaXIvb3ZlcnJpZGUuY29uZiIKICAgIGxvY2FsIC1yIG1kc2RfY2VydGlmaWNhdGVfc2FuPSIkKG9wZW5zc2wgeDUwOSAtaW4gL3Zhci9saWIvd2FhZ2VudC9NaWNyb3NvZnQuQXp1cmUuS2V5VmF1bHQuU3RvcmUvbWRzZC5wZW0gLW5vb3V0IC1zdWJqZWN0IHwgc2VkIC1lICdzLy4qQ04gPSAvLycpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZHNkX292ZXJyaWRlX2NvbmZfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIG1kc2Rfb3ZlcnJpZGVfY29uZl9maWxlbmFtZSBtZHNkX292ZXJyaWRlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBkZWZhdWx0X21kc2RfZmlsZW5hbWU9Ii9ldGMvZGVmYXVsdC9tZHNkIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBkZWZhdWx0X21kc2RfZmlsZT0iTURTRF9ST0xFX1BSRUZJWD0vdmFyL3J1bi9tZHNkL2RlZmF1bHQKTURTRF9PUFRJT05TPVwiLUEgLWQgLXIgXCRNRFNEX1JPTEVfUFJFRklYXCIKCmV4cG9ydCBNT05JVE9SSU5HX0dDU19FTlZJUk9OTUVOVD0nJE1EU0RFTlZJUk9OTUVOVCcKZXhwb3J0IE1PTklUT1JJTkdfR0NTX0FDQ09VTlQ9JyRSUE1EU0RBQ0NPVU5UJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfUkVHSU9OPSckTE9DQVRJT04nCmV4cG9ydCBNT05JVE9SSU5HX0dDU19BVVRIX0lEX1RZUEU9QXV0aEtleVZhdWx0CmV4cG9ydCBNT05JVE9SSU5HX0dDU19BVVRIX0lEPSckbWRzZF9jZXJ0aWZpY2F0ZV9zYW4nCmV4cG9ydCBNT05JVE9SSU5HX0dDU19OQU1FU1BBQ0U9JyRSUE1EU0ROQU1FU1BBQ0UnCmV4cG9ydCBNT05JVE9SSU5HX0NPTkZJR19WRVJTSU9OPSckbW9uaXRvcl9jb25maWdfdmVyc2lvbicKZXhwb3J0IE1PTklUT1JJTkdfVVNFX0dFTkVWQV9DT05GSUdfU0VSVklDRT10cnVlCgpleHBvcnQgTU9OSVRPUklOR19URU5BTlQ9JyRMT0NBVElPTicKZXhwb3J0IE1PTklUT1JJTkdfUk9MRT0nJHJvbGUnCmV4cG9ydCBNT05JVE9SSU5HX1JPTEVfSU5TVEFOQ0U9XCIkKGhvc3RuYW1lKVwiCgpleHBvcnQgTURTRF9NU0dQQUNLX1NPUlRfQ09MVU1OUz1cIjFcIiIKCiAgICB3cml0ZV9maWxlIGRlZmF1bHRfbWRzZF9maWxlbmFtZSBkZWZhdWx0X21kc2RfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3NlcnZpY2VfZmx1ZW50Yml0CiMgYXJnczoKIyAxKSBjb25mX2ZpbGUgLSBzdHJpbmc7IGZsdWVuYml0IGNvbmZpZ3VyYXRpb24gZmlsZQojIDIpIGltYWdlIC0gc3RyaW5nOyBmbHVlbnRiaXQgY29udGFpbmVyIGltYWdlIHRvIHJ1bgojIDMpIGlwYWRkcmVzcyAtIG5hbWVyZWYsIHN0cmluZzsgc3RhdGljIGlwIG9mIHBvZG1hbiBuZXR3b3JrIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdCgpIHsKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvY2FsIC1uIGlwYWRkcmVzcz0iJDMiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBmbHVlbnRiaXQgc2VydmljZSIKCiAgICBta2RpciAtcCAvZXRjL2ZsdWVudGJpdC8KICAgIG1rZGlyIC1wIC92YXIvbGliL2ZsdWVudAoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgY29uZl9maWxlbmFtZT0nL2V0Yy9mbHVlbnRiaXQvZmx1ZW50Yml0LmNvbmYnCiAgICB3cml0ZV9maWxlIGNvbmZfZmlsZW5hbWUgY29uZl9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHN5c2NvbmZpZ19maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvZmx1ZW50Yml0JwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzeXNjb25maWdfZmlsZT0iRkxVRU5UQklUSU1BR0U9JGltYWdlCnBvZG1hbl9uZXR3b3JrPSdwb2RtYW4nCklQQUREUkVTUz0nJGlwYWRkcmVzcyciCgogICAgd3JpdGVfZmlsZSBzeXNjb25maWdfZmlsZW5hbWUgc3lzY29uZmlnX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9mbHVlbnRiaXQuc2VydmljZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc2VydmljZV9maWxlPSdbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldApTdGFydExpbWl0SW50ZXJ2YWxTZWM9MAoKW1NlcnZpY2VdClJlc3RhcnRTZWM9MXMKRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2ZsdWVudGJpdApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1zZWN1cml0eS1vcHQgbGFiZWw9ZGlzYWJsZSBcCiAgLS1lbnRyeXBvaW50IC9vcHQvdGQtYWdlbnQtYml0L2Jpbi90ZC1hZ2VudC1iaXQgXAogIC0tbmV0d29yaz0ke1BPRE1BTl9ORVRXT1JLfSBcCiAgLS1pcCAke0lQQUREUkVTU30gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtdiAvZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZjovZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZiBcCiAgLXYgL3Zhci9saWIvZmx1ZW50Oi92YXIvbGliL2ZsdWVudDp6IFwKICAtdiAvdmFyL2xvZy9qb3VybmFsOi92YXIvbG9nL2pvdXJuYWw6cm8gXAogIC12IC9ldGMvbWFjaGluZS1pZDovZXRjL21hY2hpbmUtaWQ6cm8gXAogICRGTFVFTlRCSVRJTUFHRSBcCiAgLWMgL2V0Yy9mbHVlbnRiaXQvZmx1ZW50Yml0LmNvbmYKCkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9NQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0JwoKICAgIHdyaXRlX2ZpbGUgc2VydmljZV9maWxlbmFtZSBzZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV90aW1lcnNfbWRtX21kc2QKIyBhcmdzOgojIDEpIHJvbGUgLSBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgpjb25maWd1cmVfdGltZXJzX21kbV9tZHNkKCkgewogICAgbG9jYWwgLW4gcm9sZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICBsb2NhbCBrZXl2YXVsdF9zdWZmaXggc2VjcmV0X3ByZWZpeAogICAgZ2V0X2tleXZhdWx0X3N1ZmZpeCByb2xlIGtleXZhdWx0X3N1ZmZpeCBzZWNyZXRfcHJlZml4CgogICAgZm9yIHZhciBpbiAibWRzZCIgIm1kbSI7IGRvCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9kb3dubG9hZC0kdmFyLWNyZWRlbnRpYWxzLnNlcnZpY2UiCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlPSJbVW5pdF0KRGVzY3JpcHRpb249UGVyaW9kaWMgJHZhciBjcmVkZW50aWFscyByZWZyZXNoCgpbU2VydmljZV0KVHlwZT1vbmVzaG90CkV4ZWNTdGFydD0vdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaCAkdmFyIgoKICAgICAgICB3cml0ZV9maWxlIGRvd25sb2FkX2NyZWRzX3NlcnZpY2VfZmlsZW5hbWUgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlIHRydWUKCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgbG9jYWwgZG93bmxvYWRfY3JlZHNfdGltZXJfZmlsZW5hbWU9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vZG93bmxvYWQtJHZhci1jcmVkZW50aWFscy50aW1lciIKICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlPSJbVW5pdF0KRGVzY3JpcHRpb249UGVyaW9kaWMgJHZhciBjcmVkZW50aWFscyByZWZyZXNoCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltUaW1lcl0KT25Cb290U2VjPTBtaW4KT25DYWxlbmRhcj0wLzEyOjAwOjAwCkFjY3VyYWN5U2VjPTVzCgpbSW5zdGFsbF0KV2FudGVkQnk9dGltZXJzLnRhcmdldCIKCiAgICAgICAgd3JpdGVfZmlsZSBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlbmFtZSBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlIHRydWUKICAgIGRvbmUKCiAgICBsb2NhbCAtciBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWU9Ii91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZT0iIyEvYmluL2Jhc2gKc2V0IC1ldQoKQ09NUE9ORU5UPVwkMQplY2hvIFwiRG93bmxvYWQgXCRDT01QT05FTlQgY3JlZGVudGlhbHNcIgoKVEVNUF9ESVI9XCJcJChta3RlbXAgLWQpXCIKZXhwb3J0IEFaVVJFX0NPTkZJR19ESVI9XCJcJChta3RlbXAgLWQpXCIKCmVjaG8gXCJMb2dnaW5nIGludG8gQXp1cmUuLi5cIgpSRVRSSUVTPTMKd2hpbGUgW1sgXCRSRVRSSUVTIC1ndCAwIF1dOyBkbwogICAgaWYgYXogbG9naW4gLWkgLS1hbGxvdy1uby1zdWJzY3JpcHRpb25zCiAgICB0aGVuCiAgICAgICAgZWNobyBcImF6IGxvZ2luIHN1Y2Nlc3NmdWxcIgogICAgICAgIGJyZWFrCiAgICBlbHNlCiAgICAgICAgZWNobyBcImF6IGxvZ2luIGZhaWxlZC4gUmV0cnlpbmcuLi5cIgogICAgICAgIGxldCBSRVRSSUVTLT0xCiAgICAgICAgc2xlZXAgNQogICAgZmkKZG9uZQoKdHJhcCBcImNsZWFudXBcIiBFWElUCgpjbGVhbnVwKCkgewogIGF6IGxvZ291dAogIFtbIFwkVEVNUF9ESVIgPX4gL3RtcC8uKyBdXSAmJiBybSAtcmYgXCRURU1QX0RJUgogIFtbIFwkQVpVUkVfQ09ORklHX0RJUiA9fiAvdG1wLy4rIF1dICYmIHJtIC1yZiBcJEFaVVJFX0NPTkZJR19ESVIKfQoKaWYgW1sgXCRDT01QT05FTlQgPSBcIm1kbVwiIF1dOyB0aGVuCiAgQ1VSUkVOVF9DRVJUX0ZJTEU9XCIvZXRjL21kbS5wZW1cIgplbGlmIFtbIFwkQ09NUE9ORU5UID0gXCJtZHNkXCIgXV07IHRoZW4KICBDVVJSRU5UX0NFUlRfRklMRT1cIi92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlL21kc2QucGVtXCIKZWxzZQogIGVjaG8gSW52YWxpZCB1c2FnZSAmJiBleGl0IDEKZmkKClNFQ1JFVF9OQU1FPVwiJHNlY3JldF9wcmVmaXgtXCR7Q09NUE9ORU5UfVwiCk5FV19DRVJUX0ZJTEU9XCJcJFRFTVBfRElSL1wkQ09NUE9ORU5ULnBlbVwiCmZvciBhdHRlbXB0IGluIHsxLi41fTsgZG8KICBheiBrZXl2YXVsdCBcCiAgICBzZWNyZXQgXAogICAgZG93bmxvYWQgXAogICAgLS1maWxlIFwiXCRORVdfQ0VSVF9GSUxFXCIgXAogICAgLS1pZCBcImh0dHBzOi8vJEtFWVZBVUxUUFJFRklYLSRrZXl2YXVsdF9zdWZmaXguJEtFWVZBVUxURE5TU1VGRklYL3NlY3JldHMvXCRTRUNSRVRfTkFNRVwiIFwKICAgICYmIGJyZWFrCiAgaWYgW1sgXCRhdHRlbXB0IC1sdCA1IF1dOyB0aGVuIHNsZWVwIDEwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKaWYgWyAtZiBcJE5FV19DRVJUX0ZJTEUgXTsgdGhlbgogIGlmIFtbIFwkQ09NUE9ORU5UID0gXCJtZHNkXCIgXV07IHRoZW4KICAgIGNob3duIHN5c2xvZzpzeXNsb2cgXCRORVdfQ0VSVF9GSUxFCiAgZWxzZQogICAgc2VkIC1pIC1uZSAnMSwvRU5EIENFUlRJRklDQVRFLyBwJyBcJE5FV19DRVJUX0ZJTEUKICBmaQoKICBuZXdfY2VydF9zbj1cIlwkKG9wZW5zc2wgeDUwOSAtaW4gXCJcJE5FV19DRVJUX0ZJTEVcIiAtbm9vdXQgLXNlcmlhbCB8IGF3ayAtRj0gJ3twcmludCBcJDJ9JylcIgogIGN1cnJlbnRfY2VydF9zbj1cIlwkKG9wZW5zc2wgeDUwOSAtaW4gXCJcJENVUlJFTlRfQ0VSVF9GSUxFXCIgLW5vb3V0IC1zZXJpYWwgfCBhd2sgLUY9ICd7cHJpbnQgXCQyfScpXCIKICBpZiBbWyAhIC16IFwkbmV3X2NlcnRfc24gXV0gJiYgW1sgXCRuZXdfY2VydF9zbiAhPSBcIlwkY3VycmVudF9jZXJ0X3NuXCIgXV07IHRoZW4KICAgIGVjaG8gdXBkYXRpbmcgY2VydGlmaWNhdGUgZm9yIFwkQ09NUE9ORU5UCiAgICBjaG1vZCAwNjAwIFwkTkVXX0NFUlRfRklMRQogICAgbXYgXCRORVdfQ0VSVF9GSUxFIFwkQ1VSUkVOVF9DRVJUX0ZJTEUKICBmaQplbHNlCiAgZWNobyBGYWlsZWQgdG8gcmVmcmVzaCBjZXJ0aWZpY2F0ZSBmb3IgXCRDT01QT05FTlQgJiYgZXhpdCAxCmZpIgoKICAgIHdyaXRlX2ZpbGUgZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGVuYW1lIGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlIHRydWUKCiAgICBjaG1vZCB1K3ggL3Vzci9sb2NhbC9iaW4vZG93bmxvYWQtY3JlZGVudGlhbHMuc2gKCiAgICAkZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGVuYW1lIG1kc2QgJgogICAgd2FpdCAiJCEiCgoKICAgICRkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWUgbWRtICYKICAgIHdhaXQgIiQhIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3NlcnZpY2VfZmlsZW5hbWU9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnNlcnZpY2UiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkc19zZXJ2aWNlX2ZpbGU9IltVbml0XQpEZXNjcmlwdGlvbj1XYXRjaCBmb3IgY2hhbmdlcyBpbiBtZG0ucGVtIGFuZCByZXN0YXJ0cyB0aGUgbWRtIHNlcnZpY2UKCltTZXJ2aWNlXQpUeXBlPW9uZXNob3QKRXhlY1N0YXJ0PS91c3IvYmluL3N5c3RlbWN0bCByZXN0YXJ0IG1kbS5zZXJ2aWNlCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQiCgogICAgd3JpdGVfZmlsZSB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlbmFtZSB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlIHRydWUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGVuYW1lPScvdXNyL2xpYi9zeXN0ZW1kL3N5c3RlbS93YXRjaC1tZG0tY3JlZGVudGlhbHMucGF0aCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZT0nW1BhdGhdClBhdGhNb2RpZmllZD0vZXRjL21kbS5wZW0KCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCcKCiAgICB3cml0ZV9maWxlIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGVuYW1lIHdhdGNoX21kbV9jcmVkc19wYXRoX2ZpbGUgdHJ1ZQoKICAgIGxvY2FsIC1yIHdhdGNoX21kbV9jcmVkcz0nd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnBhdGgnCiAgICBzeXN0ZW1jdGwgZW5hYmxlIC0tbm93ICIkd2F0Y2hfbWRtX2NyZWRzIiB8fCBhYm9ydCAiZmFpbGVkIHRvIGVuYWJsZSBhbmQgc3RhcnQgJHdhdGNoX21kbV9jcmVkcyIKfQoKIyBjb25maWd1cmVfc2VydmljZV9tZG0KIyBhcmdzOgojIDEpIHJvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgojIDIpIGltYWdlIC0gbmFtZXJlZiwgc3RyaW5nOyBtZG0gY29udGFpbmVyIGltYWdlIHRvIHJ1bgojIDMpIGlwYWRkcmVzcyAtIG5hbWVyZWYsIHN0cmluZzsgc3RhdGljIGlwIG9mIHBvZG1hbiBuZXR3b3JrIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX21kbSgpIHsKICAgIGxvY2FsIC1uIHJvbGU9IiQxIgogICAgbG9jYWwgLW4gaW1hZ2U9IiQyIgogICAgbG9jYWwgLW4gaXBhZGRyZXNzPSIkMyIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIG1kbSBzZXJ2aWNlIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIHN5c2NvbmZpZ19tZG1fZmlsZW5hbWU9Ii9ldGMvc3lzY29uZmlnL21kbSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX21kbV9maWxlPSJNRE1GUk9OVEVORFVSTD0nJE1ETUZST05URU5EVVJMJwpNRE1JTUFHRT0nJGltYWdlJwpNRE1TT1VSQ0VFTlZJUk9OTUVOVD0nJExPQ0FUSU9OJwpNRE1TT1VSQ0VST0xFPSckcm9sZScKTURNU09VUkNFUk9MRUlOU1RBTkNFPVwiJChob3N0bmFtZSlcIgpNRE1fSU5QVVQ9c3RhdHNkX2xvY2FsLG90bHBfZ3JwYwpNRE1fTkFNRVNQQUNFPSdPVEVMJwpNRE1fQUNDT1VOVD0nQXp1cmVSZWRIYXRPcGVuU2hpZnRSUCcKcG9kbWFuX25ldHdvcms9J3BvZG1hbicKSVBBRERSRVNTPSckaXBhZGRyZXNzJyIKCiAgICB3cml0ZV9maWxlIHN5c2NvbmZpZ19tZG1fZmlsZW5hbWUgc3lzY29uZmlnX21kbV9maWxlIHRydWUKCiAgICBta2RpciAtcCAvdmFyL2V0dwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZG1fc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9tZG0uc2VydmljZSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRtX3NlcnZpY2VfZmlsZT0nW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvbWRtCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLWVudHJ5cG9pbnQgL3Vzci9zYmluL01ldHJpY3NFeHRlbnNpb24gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtLW5ldHdvcms9JHtQT0RNQU5fTkVUV09SS30gXAogIC0taXAgJHtJUEFERFJFU1N9IFwKICAtbSAyZyBcCiAgLXYgL2V0Yy9tZG0ucGVtOi9ldGMvbWRtLnBlbSBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJE1ETUlNQUdFIFwKICAtSW5wdXQgJE1ETV9JTlBVVCBcCiAgLU1ldHJpY05hbWVzcGFjZSAkTURNX05BTUVTUEFDRSBcCiAgLU1vbml0b3JpbmdBY2NvdW50ICRNRE1fQUNDT1VOVCBcCiAgLUNlcnRGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLUZyb250RW5kVXJsICRNRE1GUk9OVEVORFVSTCBcCiAgLUxvZ2dlciBDb25zb2xlIFwKICAtTG9nTGV2ZWwgV2FybmluZyBcCiAgLVByaXZhdGVLZXlGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLVNvdXJjZUVudmlyb25tZW50ICRNRE1TT1VSQ0VFTlZJUk9OTUVOVCBcCiAgLVNvdXJjZVJvbGUgJE1ETVNPVVJDRVJPTEUgXAogIC1Tb3VyY2VSb2xlSW5zdGFuY2UgJE1ETVNPVVJDRVJPTEVJTlNUQU5DRQpFeGVjU3RvcD0vdXNyL2Jpbi9wb2RtYW4gc3RvcCAlTgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCcKCiAgICB3cml0ZV9maWxlIG1kbV9zZXJ2aWNlX2ZpbGVuYW1lIG1kbV9zZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV92bXNzX2Fyb19zZXJ2aWNlCiMgYXJnczoKIyAxKSByIC0gbmFtZXJlZiwgc3RyaW5nOyByb2xlIG9mIFZNU1MKIyAyKSBpbWFnZXMgLSBuYW1lcmVmLCBhc3NvY2lhdGl2ZSBhcnJheTsgQVJPIGNvbnRhaW5lciBpbWFnZXMKIyAzKSBjb25maWdzIC0gbmFtZXJlZiwgYXNzb2NpYXRpdmUgYXJyYXk7IGNvbmZpZ3VyYXRpb24gZmlsZXMgYW5kIHZlcnNpb25zLiBUaGUgdmFsdWVzIHNob3VsZCBiZSBhIHJlZmVyZW5jZSB0byB2YXJpYWJsZXMsIG5vdCBkZXJlZmVyZW5jZWQuCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGlzIGJlY2F1c2UgdGhlIHZhbHVlIGlzIHVzZWQgd2hlbiBjcmVhdGluZyBuYW1lcmVmIHZhcmlhYmxlcyBieSBoZWxwZXIgZnVuY3Rpb25zLgpjb25maWd1cmVfdm1zc19hcm9fc2VydmljZXMoKSB7CiAgICBsb2NhbCAtbiByPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlcz0iJDIiCiAgICBsb2NhbCAtbiBjb25maWdzPSIkMyIKICAgIGxvZyAic3RhcnRpbmciCiAgICB2ZXJpZnlfcm9sZSAiJDEiCgogICAgaWYgWyAiJHIiID09ICIkcm9sZV9nYXRld2F5IiBdOyB0aGVuCiAgICAgICAgY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkgIiR7aW1hZ2VzWyJycCJdfSIgIiQxIiAiJHtjb25maWdzWyJnYXRld2F5X2NvbmZpZyJdfSIgIiR7Y29uZmlnc1sic3RhdGljX2lwX2FkZHJlc3MiXX1bImdhdGV3YXkiXSIKICAgICAgICBjb25maWd1cmVfY2VydHNfZ2F0ZXdheQogICAgZWxpZiBbICIkciIgPT0gIiRyb2xlX3JwIiBdOyB0aGVuCiAgICAgICAgY29uZmlndXJlX3NlcnZpY2VfYXJvX3JwICIke2ltYWdlc1sicnAiXX0iICIkMSIgIiR7Y29uZmlnc1sicnBfY29uZmlnIl19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfVsicnAiXSIKICAgICAgICBjb25maWd1cmVfc2VydmljZV9hcm9fbW9uaXRvciAiJHtpbWFnZXNbInJwIl19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfVsibW9uaXRvciJdIgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19wb3J0YWwgIiR7aW1hZ2VzWyJycCJdfSIgIiR7Y29uZmlnc1sic3RhdGljX2lwX2FkZHJlc3MiXX1bInBvcnRhbCJdIgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19taXNlICIke2ltYWdlc1sibWlzZSJdfSIgIiR7Y29uZmlnc1sic3RhdGljX2lwX2FkZHJlc3MiXX1bIm1pc2UiXSIKICAgICAgICBjb25maWd1cmVfc2VydmljZV9hcm9fb3RlbF9jb2xsZWN0b3IgIiR7aW1hZ2VzWyJvdGVsIl19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfSIgIiR7Y29uZmlnc1sic3RhdGljX2lwX2FkZHJlc3MiXX1bIm90ZWxfY29sbGVjdG9yIl0iCiAgICAgICAgY29uZmlndXJlX2NlcnRzX3JwCiAgICBmaQoKICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdCAiJHtjb25maWdzWyJmbHVlbnRiaXQiXX0iICIke2ltYWdlc1siZmx1ZW50Yml0Il19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfVsiZmx1ZW50Yml0Il0iCiAgICBjb25maWd1cmVfdGltZXJzX21kbV9tZHNkICIkMSIKICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX21kbSAiJDEiICIke2ltYWdlc1sibWRtIl19IiAiJHtjb25maWdzWyJzdGF0aWNfaXBfYWRkcmVzcyJdfVsibWRtIl0iCiAgICBjb25maWd1cmVfc2VydmljZV9tZHNkICIkMSIgIiR7Y29uZmlnc1sibWRzZCJdfSIKICAgIHJ1bl9henNlY2RfY29uZmlnX3NjYW4KfQoKIyB1dGlsLWNvbW1vbi5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQoKIyB1dGlsLXN5c3RlbS5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbF9zeXN0ZW09InV0aWwtc3lzdGVtLnNoIgppZiBbIC1mICIkdXRpbF9zeXN0ZW0iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1zeXN0ZW0uc2gKICAgIHNvdXJjZSAiJHV0aWxfc3lzdGVtIgpmaQojIS9iaW4vYmFzaAojIFRoaXMgZmlsZSBpcyBpbnRlbmRlZCB0byBiZSBzb3VyY2VkIGJ5IGJvb3RzdHJhcHBpbmcgc2NyaXB0cyBmb3IgY29tbW9ubHkgdXNlZCBmdW5jdGlvbnMKCiMgZ2V0X2Jvb3RfZGV2X3V1aWQKIyBHZXQgdGhlIGJvb3QgZGV2aWNlcyB1dWlkCiMgYXJnczoKIyAxKSBib290X2Rldl91dWlkIC0gbmFtZXJlZiwgc3RyaW5nOyBFbXB0eSB2YXJpYWJsZSBmb3IgYm9vdCBkZXZpY2UgdXVpZCBhc3NpZ25tZW50CiMgVGFrZW4gYW5kIHJlZmFjdG9yZWQgZnJvbSBodHRwczovL2VuZy5tcy9kb2NzL3Byb2R1Y3RzL2F6dXJlLWxpbnV4L2ZlYXR1cmVzL3NlY3VyaXR5L2ZpcHMKZ2V0X2Jvb3RfZGV2X3V1aWQoKSB7CiAgICBsb2NhbCAtbiBib290X2Rldl91dWlkPSIkMSIKICAgICMgU2V0IGJvb3RfdXVpZCB2YXJpYWJsZSBmb3IgdGhlIGJvb3QgcGFydGl0aW9uIGlmIGRpZmZlcmVudCBmcm9tIHRoZSByb290CiAgICBib290X2Rldj0iJChkZiAvYm9vdC8gfCB0YWlsIC0xIHwgY3V0IC1kJyAnIC1mMSkiCiAgICByb290X2Rldj0iJChkZiAvIHwgdGFpbCAtMSB8IGN1dCAtZCcgJyAtZjEpIgoKICAgIGJvb3RfZGV2X3V1aWQ9IiRyb290X2RldiIKICAgIGlmIFsgIiRib290X2RldiIgIT0gIiRyb290X2RldiIgXTsgdGhlbgogICAgICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgICAgIGJvb3RfZGV2X3V1aWQ9ImJvb3Q9VVVJRD0kKGJsa2lkICIkYm9vdF9kZXYiIC1zIFVVSUQgLW8gdmFsdWUpIgogICAgZmkKfQoKIyBmaXBzX3ZlcmlmeQojIFZlcmlmeSB0aGF0IGZpcHMgbW9kZSBpcyBlbmFibGVkCiMgVGFrZW4gYW5kIHJlZmFjdG9yZWQgZnJvbSBodHRwczovL2VuZy5tcy9kb2NzL3Byb2R1Y3RzL2F6dXJlLWxpbnV4L2ZlYXR1cmVzL3NlY3VyaXR5L2ZpcHMKZmlwc192ZXJpZnkoKSB7CiAgICBmaXBzX2VuYWJsZWRfcHJvYz0iJChjYXQgL3Byb2Mvc3lzL2NyeXB0by9maXBzX2VuYWJsZWQpIgogICAgZmlwc19lbmFibGVkX3N5c2N0bD0iJChzeXNjdGwgLW4gY3J5cHRvLmZpcHNfZW5hYmxlZCkiCiAgICBpZiBbICIkZmlwc19lbmFibGVkX3Byb2MiIC1uZSAxIF0gfHwgWyAiJGZpcHNfZW5hYmxlZF9zeXNjdGwiIC1uZSAxIF07IHRoZW4KICAgICAgICBhYm9ydCAiRklQUyBtb2RlIGlzIGRpc2FibGVkIgogICAgZmkKCiAgICBsb2cgIkZJUFMgbW9kZSBpcyBlbmFibGVkIgp9CgojIGZpcHNfY29uZmlndXJlCiMgQ29uZmlndXJlcyBWTSB0byBydW4gd2l0aCBmaXBzIG1vZGUgZW5hYmxlZAojIFRha2VuIGFuZCByZWZhY3RvcmVkIGZyb20gaHR0cHM6Ly9lbmcubXMvZG9jcy9wcm9kdWN0cy9henVyZS1saW51eC9mZWF0dXJlcy9zZWN1cml0eS9maXBzCiMgVE9ETyByZW1vdmUgdGhpcyBvbmNlIHNrdSBjYmwtbWFyaW5lci0yLWdlbjItZmlwcyBpcyBzdXBwb3J0ZWQgYnkgYXV0b21hdGljIE9TIHVwZGF0ZXMKIyBSZWZlcmVuY2U6IGh0dHBzOi8vbGVhcm4ubWljcm9zb2Z0LmNvbS9lbi11cy9henVyZS92aXJ0dWFsLW1hY2hpbmUtc2NhbGUtc2V0cy92aXJ0dWFsLW1hY2hpbmUtc2NhbGUtc2V0cy1hdXRvbWF0aWMtdXBncmFkZSNzdXBwb3J0ZWQtb3MtaW1hZ2VzCmZpcHNfY29uZmlndXJlKCkgewogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCBib290X3V1aWQKICAgIGdldF9ib290X2Rldl91dWlkIGJvb3RfdXVpZAoKICAgIGxvY2FsIGdydWIyX2VudgogICAgaWYgZ3J1YjJfZW52PSIkKGdydWIyLWVkaXRlbnYgLSBsaXN0IHwgZ3JlcCBrZXJuZWxvcHRzKSI7IHRoZW4KICAgICAgICBncnViMi1lZGl0ZW52IC0gc2V0ICIkZ3J1YjJfZW52IGZpcHM9MSAkYm9vdF91dWlkIgogICAgZWxzZQogICAgICAgIGdydWJieSAtLXVwZGF0ZS1rZXJuZWw9QUxMIC0tYXJncz0iZmlwcz0xICRib290X3V1aWQiCiAgICBmaQoKICAgICMgZmlwcyBtb2RlIHZlcmlmaWNhdGlvbiB3aWxsIGZhaWwgdW50aWwgYWZ0ZXIgdGhlIHZtIGhhcyBiZWVuIHJlYm9vdGVkCiAgICAjIGZpcHNfdmVyaWZ5Cn0KCiMgY29uZmlndXJlX3NzaGQKIyBXZSBuZWVkIHRvIGNvbmZpZ3VyZSBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIHRvIHllcyBpbiBvcmRlciBmb3IgdGhlIFZNU1MgQWNjZXNzIEpJVCB0byB3b3JrCmNvbmZpZ3VyZV9zc2hkKCkgewogICAgbG9nICJzdGFydGluZyIKICAgIGxvY2FsIC1yIHNzaGRfY29uZmlnPSIvZXRjL3NzaC9zc2hkX2NvbmZpZyIKCiAgICBsb2cgIkVkaXRpbmcgJHNzaGRfY29uZmlnIHRvIGFsbG93IHBhc3N3b3JkIGF1dGhlbnRpY2F0aW9uIgogICAgc2VkIC1pICdzL1Bhc3N3b3JkQXV0aGVudGljYXRpb24gbm8vUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB5ZXMvZycgIiRzc2hkX2NvbmZpZyIKCiAgICBzeXN0ZW1jdGwgcmVsb2FkIHNzaGQuc2VydmljZSB8fCBhYm9ydCAic3NoZCBmYWlsZWQgdG8gcmVsb2FkIgp9CgojIGNvbmZpZ3VyZV9sb2dyb3RhdGUgY2xvYmJlcnMgL2V0Yy9sb2dyb3RhdGUuY29uZgojIGFyZ3M6CiMgMSkgZHJvcGluX2ZpbGVzIC0gbmFtZXJlZiwgYXNzb2NpYXRpdmUgYXJyYXksIG9wdGlvbmFsOyBsb2dyb3RhdGUgZmlsZXMgdG8gd3JpdGUgdG8gL2V0Yy9sb2dyb3RhdGUuZAojICAgICAgIEtleSBuYW1lIGRpY3RhdGVzIGZpbGVuYW1lcyB3cml0dGVuIHRvIC9ldGMvbG9ncm90YXRlLmQuCiMgRXhhbXBsZToKIyAgIEtleSBkaWN0YXRlcyB0aGUgZmlsZW5hbWUgd3JpdHRlbiBpbiAvZXRjL2xvZ3JvdGF0ZS5kCiMgICBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiMgICBsb2NhbCAtckEgbG9ncm90YXRlX2Ryb3BpbnM9KAojICAgICAgWyJnYXRld2F5Il09IiRnYXRld2F5X2xvZ19maWxlIgojICAgKQpjb25maWd1cmVfbG9ncm90YXRlKCkgewogICAgbG9jYWwgLW4gZHJvcGluX2ZpbGVzPSIkezE6LWVtcHR5X3N0cn0iCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbG9ncm90YXRlX2NvbmZfZmlsZW5hbWU9Jy9ldGMvbG9ncm90YXRlLmNvbmYnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGxvZ3JvdGF0ZV9jb25mX2ZpbGU9JyMgc2VlICJtYW4gbG9ncm90YXRlIiBmb3IgZGV0YWlscwojIHJvdGF0ZSBsb2cgZmlsZXMgd2Vla2x5CndlZWtseQoKIyBrZWVwIDIgd2Vla3Mgd29ydGggb2YgYmFja2xvZ3MKcm90YXRlIDIKCiMgY3JlYXRlIG5ldyAoZW1wdHkpIGxvZyBmaWxlcyBhZnRlciByb3RhdGluZyBvbGQgb25lcwpjcmVhdGUKCiMgdXNlIGRhdGUgYXMgYSBzdWZmaXggb2YgdGhlIHJvdGF0ZWQgZmlsZQpkYXRlZXh0CgojIHVuY29tbWVudCB0aGlzIGlmIHlvdSB3YW50IHlvdXIgbG9nIGZpbGVzIGNvbXByZXNzZWQKY29tcHJlc3MKCiMgUlBNIHBhY2thZ2VzIGRyb3AgbG9nIHJvdGF0aW9uIGluZm9ybWF0aW9uIGludG8gdGhpcyBkaXJlY3RvcnkKaW5jbHVkZSAvZXRjL2xvZ3JvdGF0ZS5kCgojIG5vIHBhY2thZ2VzIG93biB3dG1wIGFuZCBidG1wIC0tIHdlIHdpbGwgcm90YXRlIHRoZW0gaGVyZQovdmFyL2xvZy93dG1wIHsKICAgIG1vbnRobHkKICAgIGNyZWF0ZSAwNjY0IHJvb3QgdXRtcAogICAgICAgIG1pbnNpemUgMU0KICAgIHJvdGF0ZSAxCn0KCi92YXIvbG9nL2J0bXAgewogICAgbWlzc2luZ29rCiAgICBtb250aGx5CiAgICBjcmVhdGUgMDYwMCByb290IHV0bXAKICAgIHJvdGF0ZSAxCn0nCgogICAgd3JpdGVfZmlsZSBsb2dyb3RhdGVfY29uZl9maWxlbmFtZSBsb2dyb3RhdGVfY29uZl9maWxlIHRydWUKCiAgICBpZiBbIC1uICIke2Ryb3Bpbl9maWxlc1sqXX0iIF07IHRoZW4KICAgICAgICBsb2NhbCAtciBsb2dyb3RhdGVfZD0iL2V0Yy9sb2dyb3RhdGUuZCIKICAgICAgICBsb2cgIldyaXRpbmcgbG9ncm90YXRlIGZpbGVzIHRvICRsb2dyb3RhdGVfZCIKICAgICAgICBmb3IgZHJvcGluX25hbWUgaW4gIiR7IWRyb3Bpbl9maWxlc1tAXX0iOyBkbwogICAgICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICAgICAgbG9jYWwgLXIgZHJvcGluX2ZpbGVuYW1lPSIkbG9ncm90YXRlX2QvJGRyb3Bpbl9uYW1lIgogICAgICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICAgICAgbG9jYWwgLXIgZHJvcGluX2ZpbGU9IiR7ZHJvcGluX2ZpbGVzWyIkZHJvcGluX25hbWUiXX0iCiAgICAgICAgICAgIHdyaXRlX2ZpbGUgZHJvcGluX2ZpbGVuYW1lIGRyb3Bpbl9maWxlIHRydWUKICAgICAgICBkb25lCiAgICBmaQp9CgojIHB1bGxfY29udGFpbmVyX2ltYWdlcwojIGFyZ3M6CiMgMSkgcHVsbF9pbWFnZXMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXkKIyAyKSByZWdpc3RyeV9jb25mIC0gbmFtZXJlZiwgc3RyaW5nLCBvcHRpb25hbDsgcGF0aCB0byBkb2NrZXIvcG9kbWFuIGNvbmZpZ3VyYXRpb24gZmlsZQpwdWxsX2NvbnRhaW5lcl9pbWFnZXMoKSB7CiAgICBsb2NhbCAtbiBwdWxsX2ltYWdlcz0iJDEiCiAgICBsb2NhbCAtbiByZWdpc3RyeV9jb25mPSIkezI6LWVtcHR5X3N0cn0iCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJpIHJldHJ5X3RpbWU9MzAKICAgIGNtZD0oCiAgICAgICAgYXoKICAgICAgICBsb2dpbgogICAgICAgIC1pCiAgICAgICAgLS1hbGxvdy1uby1zdWJzY3JpcHRpb25zCiAgICApCgogICAgbG9nICJSdW5uaW5nIGF6IGxvZ2luIHdpdGggcmV0cmllcyIKICAgIHJldHJ5IGNtZCByZXRyeV90aW1lCgogICAgIyBTdXBwcmVzcyBlbXVsYXRpb24gb3V0cHV0IGZvciBwb2RtYW4gaW5zdGVhZCBvZiBkb2NrZXIgZm9yIGF6IGFjciBjb21wYXRhYmlsaXR5CiAgICBta2RpciAtcCAvZXRjL2NvbnRhaW5lcnMvCiAgICBta2RpciAtcCAvcm9vdC8uZG9ja2VyCiAgICB0b3VjaCAvZXRjL2NvbnRhaW5lcnMvbm9kb2NrZXIKCiAgICAjIFRoaXMgbmFtZSBpcyB1c2VkIGluIHRoZSBjYXNlIHRoYXQgYXogYWNyIGxvZ2luIHNlYXJjaGVzIGZvciB0aGlzIGluIGl0J3MgZW52aXJvbm1lbnQKICAgIGV4cG9ydCBSRUdJU1RSWV9BVVRIX0ZJTEU9Ii9yb290Ly5kb2NrZXIvY29uZmlnLmpzb24iCgogICAgaWYgWyAtbiAiJHtyZWdpc3RyeV9jb25mfSIgXTsgdGhlbgogICAgICAgIHdyaXRlX2ZpbGUgUkVHSVNUUllfQVVUSF9GSUxFIHJlZ2lzdHJ5X2NvbmYgdHJ1ZQogICAgZmkKCiAgICBsb2cgImxvZ2dpbmcgaW50byBwcm9kIGFjciIKICAgIGNtZD0oCiAgICAgICAgYXoKICAgICAgICBhY3IKICAgICAgICBsb2dpbgogICAgICAgIC0tbmFtZQogICAgICAgICMgVE9ETyByZXBsYWNlIHRoaXMgd2l0aCB2YXJpYWJsZSBleHBhbnNpb24KICAgICAgICAjIFJlZmVyZW5jZTogaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIwMDEKICAgICAgICAiJChzZWQgLWUgJ3N8LiovfHwnIDw8PCIkQUNSUkVTT1VSQ0VJRCIpIgogICAgKQoKICAgIHJldHJ5IGNtZCByZXRyeV90aW1lCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgaSBpbiAke3B1bGxfaW1hZ2VzW0BdfTsgZG8KICAgICAgICBsb2NhbCAtbiBpbWFnZT0iJGkiCiAgICAgICAgY21kPSgKICAgICAgICAgICAgcG9kbWFuCiAgICAgICAgICAgIHB1bGwKICAgICAgICAgICAgIiRpbWFnZSIKICAgICAgICApCgogICAgICAgIGxvZyAiUHVsbGluZyBpbWFnZSAkaW1hZ2Ugd2l0aCByZXRyaWVzIG5vdyIKICAgICAgICByZXRyeSBjbWQgcmV0cnlfdGltZQogICAgZG9uZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgY21kPSgKICAgICAgICBhegogICAgICAgIGxvZ291dAogICAgKQoKICAgIGxvZyAiUnVubmluZyBheiBsb2dvdXQgd2l0aCByZXRyaWVzIgogICAgcmV0cnkgY21kIHJldHJ5X3RpbWUKfQoKIyBjb25maWd1cmVfY2VydHNfZ2VuZXJhbCBDb25maWd1cmUgc3lzdGVtIGNlcnRpZmljYXRlcyBjb21tb24gdG8gYWxsIFZNU1MgaW5zdGFuY2VzCmNvbmZpZ3VyZV9jZXJ0c19nZW5lcmFsKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNldHRpbmcgTU9OSVRPUklOR19HQ1NfQVVUSF9JRF9UWVBFPUF1dGhLZXlWYXVsdCBzZWVtcyB0byBoYXZlIGNhdXNlZCBtZHNkIG5vdAogICAgIyB0byBob25vdXIgU1NMX0NFUlRfRklMRSBhbnkgbW9yZSwgaGVhdmVuIG9ubHkga25vd3Mgd2h5LgogICAgbG9jYWwgLXIgc3NsX2NlcnRzX2Jhc2VkaXI9Ii91c3IvbGliL3NzbC9jZXJ0cyIKICAgIG1rZGlyIC1wICIkc3NsX2NlcnRzX2Jhc2VkaXIiCiAgICBjc3BsaXQgLWYgIiRzc2xfY2VydHNfYmFzZWRpci9jZXJ0LSIgLWIgJTAzZC5wZW0gL2V0Yy9wa2kvdGxzL2NlcnRzL2NhLWJ1bmRsZS5jcnQgL14kLzEgInsqfSIgMT4vZGV2L251bGwKICAgIGNfcmVoYXNoICIkc3NsX2NlcnRzX2Jhc2VkaXIiCn0KCiMgY29uZmlndXJlX2NlcnRzX3JwIENvbmZpZ3VyZSBzeXN0ZW0gY2VydGlmaWNhdGVzIGZvciBSUCBWTVNTCiMgYXJnczoKY29uZmlndXJlX2NlcnRzX3JwKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICB2ZXJpZnlfcm9sZSByb2xlX3JwCgogICAgbG9jYWwgLXIgcnBfY2VydHNfYmFzZWRpcj0iL2V0Yy9hcm8tcnAiCiAgICBta2RpciAtcCAiJHJwX2NlcnRzX2Jhc2VkaXIiCiAgICBiYXNlNjQgLWQgPDw8IiRBRE1JTkFQSUNBQlVORExFIiA+ICIkcnBfY2VydHNfYmFzZWRpci9hZG1pbi1jYS1idW5kbGUucGVtIgogICAgaWYgW1sgLW4gIiRBUk1BUElDQUJVTkRMRSIgXV07IHRoZW4KICAgIGJhc2U2NCAtZCA8PDwiJEFSTUFQSUNBQlVORExFIiA+ICIkcnBfY2VydHNfYmFzZWRpci9hcm0tY2EtYnVuZGxlLnBlbSIKICAgIGZpCiAgICBjaG93biAtUiAxMDAwOjEwMDAgIiRycF9jZXJ0c19iYXNlZGlyIgoKICAgIGNvbmZpZ3VyZV9jZXJ0c19nZW5lcmFsCn0KCiMgY29uZmlndXJlX2NlcnRzX2dhdGV3YXkgQ29uZmlndXJlIHN5c3RlbSBjZXJ0aWZpY2F0ZXMgZm9yIEdhdGV3YXkgVk1TUyBpbnN0YW5jZXMKY29uZmlndXJlX2NlcnRzX2dhdGV3YXkoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIHZlcmlmeV9yb2xlIHJvbGVfZ2F0ZXdheQogICAgY29uZmlndXJlX2NlcnRzX2dlbmVyYWwKfQoKIyBjb25maWd1cmVfY2VydHNfZGV2cHJveHkgQ29uZmlndXJlIHN5c3RlbSBjZXJ0aWZpY2F0ZXMgZm9yIGRldnByb3h5IFZNU1MgaW5zdGFuY2VzCmNvbmZpZ3VyZV9jZXJ0c19kZXZwcm94eSgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgdmVyaWZ5X3JvbGUgcm9sZV9kZXZwcm94eQoKICAgIGxvY2FsIC1yIHByb3h5X2NlcnRzX2Jhc2VkaXI9Ii9ldGMvcHJveHkiCiAgICBta2RpciAtcCAiJHByb3h5X2NlcnRzX2Jhc2VkaXIiCiAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUNFUlQiID4gIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LmNydCIKICAgIGJhc2U2NCAtZCA8PDwiJFBST1hZS0VZIiA+ICIkcHJveHlfY2VydHNfYmFzZWRpci9wcm94eS5rZXkiCiAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUNMSUVOVENFUlQiID4gIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LWNsaWVudC5jcnQiCiAgICBjaG93biAtUiAxMDAwOjEwMDAgL2V0Yy9wcm94eQogICAgY2htb2QgMDYwMCAiJHByb3h5X2NlcnRzX2Jhc2VkaXIvcHJveHkua2V5Igp9Cgpjb25maWd1cmVfYXpzZWNkX3NjYW4oKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgICMgd2UgbGVhdmUgY2xpZW50SWQgYmxhbmsgYXMgbG9uZyBhcyBvbmx5IDEgbWFuYWdlZCBpZGVudGl0eSBhc3NpZ25lZCB0byB2bXNzCiAgICAjIGlmIHdlIGhhdmUgbW9yZSB0aGFuIDEsIHdlIHdpbGwgbmVlZCB0byBwb3B1bGF0ZSB3aXRoIGNsaWVudElkIHVzZWQgZm9yIG9mZi1ub2RlIHNjYW5uaW5nCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG5vZGVzY2FuX2FnZW50X2ZpbGVuYW1lPSIvZXRjL2RlZmF1bHQvdnNhLW5vZGVzY2FuLWFnZW50LmNvbmZpZyIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbm9kZXNjYW5fYWdlbnRfZmlsZT0iewogICAgXCJOaWNlXCI6IDE5LAogICAgXCJUaW1lb3V0XCI6IDEwODAwLAogICAgXCJDbGllbnRJZFwiOiBcIlwiLAogICAgXCJUZW5hbnRJZFwiOiAkQVpVUkVTRUNQQUNLVlNBVEVOQU5USUQsCiAgICBcIlF1YWx5c1N0b3JlQmFzZVVybFwiOiAkQVpVUkVTRUNQQUNLUVVBTFlTVVJMLAogICAgXCJQcm9jZXNzVGltZW91dFwiOiAzMDAsCiAgICBcIkNvbW1hbmREZWxheVwiOiAwCiAgfSIKCiAgICB3cml0ZV9maWxlIG5vZGVzY2FuX2FnZW50X2ZpbGVuYW1lIG5vZGVzY2FuX2FnZW50X2ZpbGUgdHJ1ZQp9CgojIHJ1bl9henNlY2RfY29uZmlnX3NjYW4KcnVuX2F6c2VjZF9jb25maWdfc2NhbigpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgY29uZmlndXJlX2F6c2VjZF9zY2FuCgogICAgbG9jYWwgLWFyIGNvbmZpZ3M9KAogICAgICAgICJiYXNlbGluZSIKICAgICAgICAiY2xhbWF2IgogICAgICAgICJzb2Z0d2FyZSIKICAgICkKCiAgICBsb2cgIlNjYW5uaW5nIGNvbmZpZ3VyYXRpb24gZmlsZXMgd2l0aCBhenNlY2QgJHtjb25maWdzWypdfSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgZm9yIHNjYW4gaW4gJHtjb25maWdzW0BdfTsgZG8KICAgICAgICBsb2cgIlNjYW5uaW5nIGNvbmZpZyBmaWxlICRzY2FuIG5vdyIKICAgICAgICAvdXNyL2xvY2FsL2Jpbi9henNlY2QgY29uZmlnIC1zICIkc2NhbiIgLWQgUDFECiAgICBkb25lCn0KCiMgY3JlYXRlX3JlcXVpcmVkX2RpcnMKY3JlYXRlX3JlcXVpcmVkX2RpcnMoKSB7CiAgICBjcmVhdGVfZGlycz0oCiAgICAgICAgL3Zhci9sb2cvam91cm5hbAogICAgICAgIC92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlCiAgICAgICAgIyBEb2VzIG5vdCBleGlzdCBvbiBkZXZQcm94eVZNU1MKICAgICAgICAvdmFyL29wdC9taWNyb3NvZnQvbGludXhtb25hZ2VudAogICAgKQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgZm9yIGQgaW4gJHtjcmVhdGVfZGlyc1tAXX07IGRvCiAgICAgICAgbG9nICJDcmVhdGluZyBkaXJlY3RvcnkgJGQiCiAgICAgICAgbWtkaXIgLXAgIiRkIiB8fCBhYm9ydCAiZmFpbGVkIHRvIGNyZWF0ZSBkaXJlY3RvcnkgJGQiCiAgICBkb25lCn0KCiMgZmlyZXdhbGxkX2NvbmZpZ3VyZV9iYWNrZW5kCmZpcmV3YWxsZF9jb25maWd1cmVfYmFja2VuZCgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgbG9nICJDaGFuZ2luZyBmaXJld2FsbGQgYmFja2VuZCB0byBpcHRhYmxlcyIKICAgIGNvbmZfZmlsZT0iL2V0Yy9maXJld2FsbGQvZmlyZXdhbGxkLmNvbmYiCiAgICBzZWQgLWkgJ3MvRmlyZXdhbGxCYWNrZW5kPW5mdGFibGVzL0ZpcmV3YWxsQmFja2VuZD1pcHRhYmxlcy9nJyAiJGNvbmZfZmlsZSIKfQoKIyBmaXJld2FsbGRfY29uZmlndXJlCiMgYXJnczoKIyAxKSBwb3J0cyAtIG5hbWVyZWYsIHN0cmluZyBhcnJheTsgcG9ydHMgdG8gYmUgZW5hYmxlZC4KIyAgICAgICBQb3J0cyBtdXN0IGJlIHBvc3RmaXhlZCB3aXRoIC90Y3Agb3IgL3VkcApmaXJld2FsbGRfY29uZmlndXJlKCkgewogICAgbG9jYWwgLW4gcG9ydHM9IiQxIgogICAgbG9nICJzdGFydGluZyIKCiAgICBmaXJld2FsbGRfY29uZmlndXJlX2JhY2tlbmQKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yYSBzZXJ2aWNlPSgKICAgICAgICAiZmlyZXdhbGxkIgogICAgKQogICAgZW5hYmxlX3NlcnZpY2VzIHNlcnZpY2UKCiAgICBsb2cgIkVuYWJsaW5nIHBvcnRzICR7cG9ydHNbKl19IG9uIGRlZmF1bHQgZmlyZXdhbGxkIHpvbmUiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBwb3J0IGluICR7cG9ydHNbQF19OyBkbwogICAgICAgIGxvZyAiRW5hYmxpbmcgcG9ydCAkcG9ydCBub3ciCiAgICAgICAgZmlyZXdhbGwtY21kICItLWFkZC1wb3J0PSRwb3J0IiBcCiAgICAgICAgICAgICAgICAgICAgIC0tcGVybWFuZW50CiAgICBkb25lCgogICAgbG9nICJXcml0aW5nIHJ1bnRpbWUgY29uZmlnIHRvIHBlcm1hbmVudCBjb25maWciCiAgICBmaXJld2FsbC1jbWQgLS1ydW50aW1lLXRvLXBlcm1hbmVudAp9CgojIHV0aWwtY29tbW9uLnNoIGRvZXMgbm90IGV4aXN0IHdoZW4gZGVwbG95ZWQgdG8gVk1TUyB2aWEgVk1TUyBleHRlbnNpb25zCiMgUHJvdmlkZXMgc2hlbGxjaGVjayBkZWZpbml0aW9ucwp1dGlsX2NvbW1vbj0idXRpbC1jb21tb24uc2giCmlmIFsgLWYgIiR1dGlsX2NvbW1vbiIgXTsgdGhlbgogICAgIyBzaGVsbGNoZWNrIHNvdXJjZT11dGlsLWNvbW1vbi5zaAogICAgc291cmNlICIkdXRpbF9jb21tb24iCmZpCiMhL2Jpbi9iYXNoCgpzZXQgLW8gZXJyZXhpdCBcCiAgICAtbyBwaXBlZmFpbCBcCiAgICAtbyBub3Vuc2V0CgptYWluKCkgewogICAgIyB0cmFuc2FjdGlvbiBhdHRlbXB0IHJldHJ5IHRpbWUgaW4gc2Vjb25kcwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmkgcmV0cnlfd2FpdF90aW1lPTMwCiAgICBsb2NhbCAtcmkgcGtnX3JldHJ5X2NvdW50PTYwCgogICAgY3JlYXRlX3JlcXVpcmVkX2RpcnMKICAgIGNvbmZpZ3VyZV9zc2hkCiAgICBjb25maWd1cmVfcnBtX3JlcG9zIHJldHJ5X3dhaXRfdGltZSBcCiAgICAgICAgICAgICAgICAgICAgICAgICIkcGtnX3JldHJ5X2NvdW50IgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLWFyIGV4Y2x1ZGVfcGtncz0oCiAgICAgICAgIi14IFdBTGludXhBZ2VudCIKICAgICAgICAiLXggV0FMaW51eEFnZW50LXVkZXYiCiAgICApCgogICAgZG5mX3VwZGF0ZV9wa2dzIGV4Y2x1ZGVfcGtncyBcCiAgICAgICAgICAgICAgICAgICAgcmV0cnlfd2FpdF90aW1lIFwKICAgICAgICAgICAgICAgICAgICAiJHBrZ19yZXRyeV9jb3VudCIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yYSBpbnN0YWxsX3BrZ3M9KAogICAgICAgIGNsYW1hdgogICAgICAgIGF6c2VjLWNsYW1hdgogICAgICAgIGF6dXJlLWNsaQogICAgICAgIGF6dXJlLW1kc2QKICAgICAgICBhenVyZS1zZWN1cml0eQogICAgICAgIHBvZG1hbgogICAgICAgIHBvZG1hbi1kb2NrZXIKICAgICAgICBvcGVuc3NsLXBlcmwKICAgICAgICAjIGhhY2sgLSB3ZSBhcmUgaW5zdGFsbGluZyBweXRob24zIG9uIGhvc3RzIGR1ZSB0byBhbiBpc3N1ZSB3aXRoIEF6dXJlIExpbnV4IEV4dGVuc2lvbnMgaHR0cHM6Ly9naXRodWIuY29tL0F6dXJlL2F6dXJlLWxpbnV4LWV4dGVuc2lvbnMvcHVsbC8xNTA1CiAgICAgICAgcHl0aG9uMwogICAgICAgICMgcmVxdWlyZWQgZm9yIHBvZG1hbiBuZXR3b3JraW5nCiAgICAgICAgZmlyZXdhbGxkCiAgICAgICAgIyBSZXF1aXJlZCB0byBlbmFibGUgZmlwcwogICAgICAgIGdydWJieQogICAgICAgIGRyYWN1dC1maXBzCiAgICApCgogICAgZG5mX2luc3RhbGxfcGtncyBpbnN0YWxsX3BrZ3MgXAogICAgICAgICAgICAgICAgICAgICAgcmV0cnlfd2FpdF90aW1lIFwKICAgICAgICAgICAgICAgICAgICAgICIkcGtnX3JldHJ5X2NvdW50IgoKICAgIGZpcHNfY29uZmlndXJlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTE5CiAgICBjb25maWd1cmVfbG9ncm90YXRlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTUzIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZG1pbWFnZT0iJHtSUElNQUdFJSUvKn0vJHtNRE1JTUFHRSMqL30iCiAgICBsb2NhbCAtciBycGltYWdlPSIkUlBJTUFHRSIKICAgIGxvY2FsIC1yIG1pc2VpbWFnZT0iJHtSUElNQUdFJSUvKn0vJHtNSVNFSU1BR0UjKi99IgogICAgbG9jYWwgLXIgb3RlbGltYWdlPSIkT1RFTElNQUdFIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBmbHVlbnRiaXRfaW1hZ2U9IiRGTFVFTlRCSVRJTUFHRSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJBIGFyb19pbWFnZXM9KAogICAgICAgIFsibWRtIl09Im1kbWltYWdlIgogICAgICAgIFsicnAiXT0icnBpbWFnZSIKICAgICAgICBbImZsdWVudGJpdCJdPSJmbHVlbnRiaXRfaW1hZ2UiCiAgICAgICAgWyJtaXNlIl09Im1pc2VpbWFnZSIKICAgICAgICBbIm90ZWwiXT0ib3RlbGltYWdlIgogICAgKQoKICAgIHB1bGxfY29udGFpbmVyX2ltYWdlcyBhcm9faW1hZ2VzCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgZW5hYmxlX3BvcnRzPSgKICAgICAgICAjIFJQIGZyb250ZW5kCiAgICAgICAgIjQ0My90Y3AiCiAgICAgICAgIyBQb3J0YWwgd2ViCiAgICAgICAgIjQ0NC90Y3AiCiAgICAgICAgIyBQb3J0YWwgc3NoCiAgICAgICAgIjIyMjIvdGNwIgogICAgICAgICMgSklUIHNzaAogICAgICAgICIyMi90Y3AiCiAgICApCgogICAgZmlyZXdhbGxkX2NvbmZpZ3VyZSBlbmFibGVfcG9ydHMKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGZsdWVudGJpdF9jb25mX2ZpbGU9IltJTlBVVF0KCU5hbWUgc3lzdGVtZAoJVGFnIGpvdXJuYWxkCglTeXN0ZW1kX0ZpbHRlciBfQ09NTT1hcm8KCURCIC92YXIvbGliL2ZsdWVudC9qb3VybmFsZGIKCltGSUxURVJdCglOYW1lIG1vZGlmeQoJTWF0Y2ggam91cm5hbGQKCVJlbW92ZV93aWxkY2FyZCBfCglSZW1vdmUgVElNRVNUQU1QCgpbRklMVEVSXQoJTmFtZSByZXdyaXRlX3RhZwoJTWF0Y2ggam91cm5hbGQKCVJ1bGUgXCRMT0dLSU5EIGFzeW5jcW9zIGFzeW5jcW9zIHRydWUKCltGSUxURVJdCglOYW1lIG1vZGlmeQoJTWF0Y2ggYXN5bmNxb3MKCVJlbW92ZSBDTElFTlRfUFJJTkNJUEFMX05BTUUKCVJlbW92ZSBGSUxFCglSZW1vdmUgQ09NUE9ORU5UCgpbRklMVEVSXQoJTmFtZSByZXdyaXRlX3RhZwoJTWF0Y2ggam91cm5hbGQKCVJ1bGUgXCRMT0dLSU5EIGlmeGF1ZGl0IGlmeGF1ZGl0IGZhbHNlCgpbT1VUUFVUXQoJTmFtZSBmb3J3YXJkCglNYXRjaCAqCglQb3J0IDI5MjMwIgoKICAgICMgdmFsdWVzIGFyZSByZWZlcmVuY2VzIHRvIHZhcmlhYmxlcywgdGhleSBzaG91bGQgbm90IGJlIGRlcmVmZXJlbmNlZCBoZXJlCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yQSBhcm9fY29uZmlncz0oCiAgICAgICAgWyJycF9jb25maWciXT0iYXJvX3JwX2NvbmZfZmlsZSIKICAgICAgICBbImZsdWVudGJpdCJdPSJmbHVlbnRiaXRfY29uZl9maWxlIgogICAgICAgIFsibWRzZCJdPSJtZHNkX2NvbmZpZ192ZXJzaW9uIgogICAgICAgIFsic3RhdGljX2lwX2FkZHJlc3MiXT0ic3RhdGljX2lwX2FkZHJlc3NlcyIKICAgICkKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICMgdXNlIGRlZmF1bHQgcG9kbWFuIG5ldHdvcmsgd2l0aCByYW5nZSAxMC44OC4wLjAvMTYKICAgIGxvY2FsIC1yQSBzdGF0aWNfaXBfYWRkcmVzc2VzPSgKICAgICAgICBbInJwIl09IjEwLjg4LjAuMiIKICAgICAgICBbIm1vbml0b3IiXT0iMTAuODguMC4zIgogICAgICAgIFsicG9ydGFsIl09IjEwLjg4LjAuNCIKICAgICAgICBbIm1pc2UiXT0iMTAuODguMC41IgogICAgICAgIFsib3RlbF9jb2xsZWN0b3IiXT0iMTAuODguMC42IgogICAgICAgIFsiZmx1ZW50Yml0Il09IjEwLjg4LjAuNyIKICAgICAgICBbIm1kbSJdPSIxMC44OC4wLjgiCiAgICApCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZHNkX2NvbmZpZ192ZXJzaW9uPSIkUlBNRFNEQ09ORklHVkVSU0lPTiIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3JwX2NvbmZfZmlsZT0iQUNSX1JFU09VUkNFX0lEPSckQUNSUkVTT1VSQ0VJRCcKQURNSU5fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FPSckQURNSU5BUElDTElFTlRDRVJUQ09NTU9OTkFNRScKQVJNX0FQSV9DTElFTlRfQ0VSVF9DT01NT05fTkFNRT0nJEFSTUFQSUNMSUVOVENFUlRDT01NT05OQU1FJwpBWlVSRV9BUk1fQ0xJRU5UX0lEPSckQVJNQ0xJRU5USUQnCkFaVVJFX0ZQX0NMSUVOVF9JRD0nJEZQQ0xJRU5USUQnCkFaVVJFX0ZQX1NFUlZJQ0VfUFJJTkNJUEFMX0lEPSckRlBTRVJWSUNFUFJJTkNJUEFMSUQnCkNMVVNURVJfTURNX0FDQ09VTlQ9JyRDTFVTVEVSTURNQUNDT1VOVCcKQ0xVU1RFUl9NRE1fTkFNRVNQQUNFPVJQCkNMVVNURVJfTURTRF9BQ0NPVU5UPSckQ0xVU1RFUk1EU0RBQ0NPVU5UJwpDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT049JyRDTFVTVEVSTURTRENPTkZJR1ZFUlNJT04nCkNMVVNURVJfTURTRF9OQU1FU1BBQ0U9JyRDTFVTVEVSTURTRE5BTUVTUEFDRScKREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKRE9NQUlOX05BTUU9JyRMT0NBVElPTi4kQ0xVU1RFUlBBUkVOVERPTUFJTk5BTUUnCkdBVEVXQVlfRE9NQUlOUz0nJEdBVEVXQVlET01BSU5TJwpHQVRFV0FZX1JFU09VUkNFR1JPVVA9JyRHQVRFV0FZUkVTT1VSQ0VHUk9VUE5BTUUnCktFWVZBVUxUX1BSRUZJWD0nJEtFWVZBVUxUUFJFRklYJwpNRE1fQUNDT1VOVD0nJFJQTURNQUNDT1VOVCcKTURNX05BTUVTUEFDRT0nJHtyb2xlX3JwXl59JwpNRFNEX0VOVklST05NRU5UPSckTURTREVOVklST05NRU5UJwpNSVNFX0FERFJFU1M9J2h0dHA6Ly8ke3N0YXRpY19pcF9hZGRyZXNzZXNbIm1pc2UiXX06NTAwMCcKUlBfRkVBVFVSRVM9JyRSUEZFQVRVUkVTJwpSUElNQUdFPSckcnBpbWFnZScKQVJPX0lOU1RBTExfVklBX0hJVkU9JyRDTFVTVEVSU0lOU1RBTExWSUFISVZFJwpBUk9fSElWRV9ERUZBVUxUX0lOU1RBTExFUl9QVUxMU1BFQz0nJENMVVNURVJERUZBVUxUSU5TVEFMTEVSUFVMTFNQRUMnCkFST19BRE9QVF9CWV9ISVZFPSckQ0xVU1RFUlNBRE9QVEJZSElWRScKT0lEQ19BRkRfRU5EUE9JTlQ9JyRMT0NBVElPTi5vaWMuJFJQUEFSRU5URE9NQUlOTkFNRScKT0lEQ19TVE9SQUdFX0FDQ09VTlRfTkFNRT0nJE9JRENTVE9SQUdFQUNDT1VOVE5BTUUnCk1TSV9SUF9FTkRQT0lOVD0nJE1TSVJQRU5EUE9JTlQnCiIKCiAgICBjb25maWd1cmVfdm1zc19hcm9fc2VydmljZXMgcm9sZV9ycCBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJvX2ltYWdlcyBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJvX2NvbmZpZ3MKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yYSBhcm9fc2VydmljZXM9KAogICAgICAgICJhcm8tbWlzZSIKICAgICAgICAiYXJvLW1vbml0b3IiCiAgICAgICAgImFyby1vdGVsLWNvbGxlY3RvciIKICAgICAgICAiYXJvLXBvcnRhbCIKICAgICAgICAiYXJvLXJwIgogICAgICAgICJhenNlY2QiCiAgICAgICAgIm1kc2QiCiAgICAgICAgIm1kbSIKICAgICAgICAiY2hyb255ZCIKICAgICAgICAiZmx1ZW50Yml0IgogICAgICAgICJkb3dubG9hZC1tZHNkLWNyZWRlbnRpYWxzLnRpbWVyIgogICAgICAgICJkb3dubG9hZC1tZG0tY3JlZGVudGlhbHMudGltZXIiCiAgICAgICAgImZpcmV3YWxsZCIKICAgICkKCiAgICBlbmFibGVfc2VydmljZXMgYXJvX3NlcnZpY2VzCgogICAgcmVib290X3ZtCn0KCiMgVGhpcyB2YXJpYWJsZSBpcyB1c2VkIGJ5IGF6LWNsaQojIEl0J3MgYXNzdW1lZCB0aGF0IGlmIHRoaXMgdmFyaWFibGUgaGFzbid0IGJlZW4gY2FycmllZCBvdmVyLCB0aGF0IG90aGVycyBhcmUgYWxzbyBub3QgcHJlc2VudCwgc28gd2UgZmFpbCBlYXJseSBieSByZXR1cm5pbmcgYW4gZXJyb3IKIyBUaGlzIHdhcyBtb3N0bHkgaGVscGZ1bCB3aGVuIHRlc3Rpbmcgb24gYSBkZXZlbG9wbWVudCBWTSwgYnV0IGlzIHN0aWxsIGFwcGxpY2FibGUKZXhwb3J0IEFaVVJFX0NMT1VEX05BTUU9IiR7QVpVUkVDTE9VRE5BTUU6PyJGYWlsZWQgdG8gY2Fycnkgb3ZlciB2YXJpYWJsZXMifSIKCiMgdXRpbC5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFByb3ZpZGVzIHNoZWxsY2hlY2sgZGVmaW5pdGlvbnMKdXRpbD0idXRpbC5zaCIKaWYgWyAtZiAiJHV0aWwiIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC5zaAogICAgc291cmNlICIkdXRpbCIKZmkKCm1haW4gIiRAIgo=')))]" } } }, diff --git a/pkg/deploy/config.go b/pkg/deploy/config.go index fbcf1552661..24eb6acefaa 100644 --- a/pkg/deploy/config.go +++ b/pkg/deploy/config.go @@ -63,6 +63,7 @@ type Configuration struct { ExtraServiceKeyvaultAccessPolicies []interface{} `json:"extraServiceKeyvaultAccessPolicies,omitempty" value:"required"` FluentbitImage *string `json:"fluentbitImage,omitempty" value:"required"` FPClientID *string `json:"fpClientId,omitempty" value:"required"` + FPTENANTID *string `json:"fpTenantId,omitempty" value:"required"` FPServerCertCommonName *string `json:"fpServerCertCommonName,omitempty"` FPServicePrincipalID *string `json:"fpServicePrincipalId,omitempty" value:"required"` GatewayDomains []string `json:"gatewayDomains,omitempty"` @@ -78,6 +79,8 @@ type Configuration struct { KeyvaultPrefix *string `json:"keyvaultPrefix,omitempty" value:"required"` MDMFrontendURL *string `json:"mdmFrontendUrl,omitempty" value:"required"` MDSDEnvironment *string `json:"mdsdEnvironment,omitempty" value:"required"` + MISEVALIDAUDIENCES []string `json:"miseValidAudiences,omitempty"` + MISEVALIDAPPIDs []string `json:"miseValidAppIDs,omitempty"` NonZonalRegions []string `json:"nonZonalRegions,omitempty"` PortalAccessGroupIDs []string `json:"portalAccessGroupIds,omitempty" value:"required"` PortalClientID *string `json:"portalClientId,omitempty" value:"required"` diff --git a/pkg/deploy/devconfig.go b/pkg/deploy/devconfig.go index bdf26d496c0..5751687ef01 100644 --- a/pkg/deploy/devconfig.go +++ b/pkg/deploy/devconfig.go @@ -152,6 +152,7 @@ func DevConfig(_env env.Core) (*Config, error) { }, FluentbitImage: ptr.To(version.FluentbitImage(azureUniquePrefix + "aro." + _env.Environment().ContainerRegistryDNSSuffix)), FPClientID: ptr.To(os.Getenv("AZURE_FP_CLIENT_ID")), + FPTENANTID: ptr.To(os.Getenv("AZURE_TENANT_ID")), FPServicePrincipalID: ptr.To(os.Getenv("AZURE_FP_SERVICE_PRINCIPAL_ID")), GatewayDomains: []string{ "eastus-shared.ppe.warm.ingest.monitor.core.windows.net", @@ -174,6 +175,13 @@ func DevConfig(_env env.Core) (*Config, error) { MDMFrontendURL: ptr.To("https://global.ppe.microsoftmetrics.com/"), MDSDEnvironment: ptr.To(version.DevGenevaLoggingEnvironment), MsiRpEndpoint: ptr.To("https://iamaplaceholder.com"), + MISEVALIDAUDIENCES: []string{ + "https://management.core.windows.net/", + _env.Environment().ResourceManagerEndpoint, + }, + MISEVALIDAPPIDs: []string{ + "2187cde1-7e28-4645-9104-19edfa500053", + }, PortalAccessGroupIDs: []string{ os.Getenv("AZURE_PORTAL_ACCESS_GROUP_IDS"), }, @@ -191,6 +199,7 @@ func DevConfig(_env env.Core) (*Config, error) { "EnableOCMEndpoints", "RequireOIDCStorageWebEndpoint", "UseMockMsiRp", + "EnableMISE", }, // TODO update this to support FF RPImagePrefix: ptr.To(azureUniquePrefix + "aro.azurecr.io/aro"), diff --git a/pkg/deploy/generator/resources_rp.go b/pkg/deploy/generator/resources_rp.go index 4eed41ea00a..80719cf79ed 100644 --- a/pkg/deploy/generator/resources_rp.go +++ b/pkg/deploy/generator/resources_rp.go @@ -376,6 +376,7 @@ func (g *generator) rpVMSS() *arm.Resource { "databaseAccountName", "fluentbitImage", "fpClientId", + "fpTenantId", "fpServicePrincipalId", "gatewayDomains", "gatewayResourceGroupName", @@ -409,6 +410,18 @@ func (g *generator) rpVMSS() *arm.Resource { ) } + // convert array variables to string using ARM string() function to be passed via customScript later + for _, variable := range []string{ + "miseValidAudiences", + "miseValidAppIDs", + } { + parts = append(parts, + fmt.Sprintf("'%s=$(base64 -d <<<'''", strings.ToUpper(variable)), + fmt.Sprintf("base64(string(parameters('%s')))", variable), + "''')\n'", + ) + } + for _, variable := range []string{ "adminApiCaBundle", "armApiCaBundle", @@ -424,6 +437,14 @@ func (g *generator) rpVMSS() *arm.Resource { "'MDMIMAGE=''"+version.MdmImage("")+"''\n'", ) + parts = append(parts, + "'OTELIMAGE=''"+version.OTelImage("")+"''\n'", + ) + + parts = append(parts, + "'MISEIMAGE=''"+version.MiseImage("")+"''\n'", + ) + parts = append(parts, "'LOCATION=$(base64 -d <<<'''", "base64(resourceGroup().location)", diff --git a/pkg/deploy/generator/scripts/gatewayVMSS.sh b/pkg/deploy/generator/scripts/gatewayVMSS.sh index 0e2b5a9f4a8..76bce5470d4 100644 --- a/pkg/deploy/generator/scripts/gatewayVMSS.sh +++ b/pkg/deploy/generator/scripts/gatewayVMSS.sh @@ -118,6 +118,15 @@ RPIMAGE='$rpimage'" ["gateway_config"]="aro_gateway_conf_file" ["fluentbit"]="fluentbit_conf_file" ["mdsd"]="mdsd_config_version" + ["static_ip_address"]="static_ip_addresses" + ) + + # shellcheck disable=SC2034 + # use default podman network with range 10.88.0.0/16 + local -rA static_ip_addresses=( + ["gateway"]="10.88.0.2" + ["fluentbit"]="10.88.0.7" + ["mdm"]="10.88.0.8" ) configure_vmss_aro_services role_gateway \ diff --git a/pkg/deploy/generator/scripts/rpVMSS.sh b/pkg/deploy/generator/scripts/rpVMSS.sh index 7fc396d03b5..0ca8e883d6d 100644 --- a/pkg/deploy/generator/scripts/rpVMSS.sh +++ b/pkg/deploy/generator/scripts/rpVMSS.sh @@ -45,8 +45,8 @@ main() { ) dnf_install_pkgs install_pkgs \ - retry_wait_time \ - "$pkg_retry_count" + retry_wait_time \ + "$pkg_retry_count" fips_configure @@ -56,6 +56,8 @@ main() { # shellcheck disable=SC2153 disable=SC2034 local -r mdmimage="${RPIMAGE%%/*}/${MDMIMAGE#*/}" local -r rpimage="$RPIMAGE" + local -r miseimage="${RPIMAGE%%/*}/${MISEIMAGE#*/}" + local -r otelimage="$OTELIMAGE" # shellcheck disable=SC2034 local -r fluentbit_image="$FLUENTBITIMAGE" # shellcheck disable=SC2034 @@ -63,15 +65,12 @@ main() { ["mdm"]="mdmimage" ["rp"]="rpimage" ["fluentbit"]="fluentbit_image" + ["mise"]="miseimage" + ["otel"]="otelimage" ) pull_container_images aro_images - local -r aro_network="aro" - # shellcheck disable=SC2034 - local -rA networks=( - ["$aro_network"]="192.168.254.0/24" - ) # shellcheck disable=SC2034 local -ra enable_ports=( # RP frontend @@ -121,6 +120,26 @@ main() { Match * Port 29230" + # values are references to variables, they should not be dereferenced here + # shellcheck disable=SC2034 + local -rA aro_configs=( + ["rp_config"]="aro_rp_conf_file" + ["fluentbit"]="fluentbit_conf_file" + ["mdsd"]="mdsd_config_version" + ["static_ip_address"]="static_ip_addresses" + ) + + # shellcheck disable=SC2034 + # use default podman network with range 10.88.0.0/16 + local -rA static_ip_addresses=( + ["rp"]="10.88.0.2" + ["monitor"]="10.88.0.3" + ["portal"]="10.88.0.4" + ["mise"]="10.88.0.5" + ["otel_collector"]="10.88.0.6" + ["fluentbit"]="10.88.0.7" + ["mdm"]="10.88.0.8" + ) # shellcheck disable=SC2034 local -r mdsd_config_version="$RPMDSDCONFIGVERSION" @@ -144,6 +163,7 @@ KEYVAULT_PREFIX='$KEYVAULTPREFIX' MDM_ACCOUNT='$RPMDMACCOUNT' MDM_NAMESPACE='${role_rp^^}' MDSD_ENVIRONMENT='$MDSDENVIRONMENT' +MISE_ADDRESS='http://${static_ip_addresses["mise"]}:5000' RP_FEATURES='$RPFEATURES' RPIMAGE='$rpimage' ARO_INSTALL_VIA_HIVE='$CLUSTERSINSTALLVIAHIVE' @@ -154,22 +174,15 @@ OIDC_STORAGE_ACCOUNT_NAME='$OIDCSTORAGEACCOUNTNAME' MSI_RP_ENDPOINT='$MSIRPENDPOINT' " - # values are references to variables, they should not be dereferenced here - # shellcheck disable=SC2034 - local -rA aro_configs=( - ["rp_config"]="aro_rp_conf_file" - ["fluentbit"]="fluentbit_conf_file" - ["mdsd"]="mdsd_config_version" - ["network"]="aro_network" - ) - configure_vmss_aro_services role_rp \ aro_images \ aro_configs # shellcheck disable=SC2034 local -ra aro_services=( + "aro-mise" "aro-monitor" + "aro-otel-collector" "aro-portal" "aro-rp" "azsecd" diff --git a/pkg/deploy/generator/scripts/util-services.sh b/pkg/deploy/generator/scripts/util-services.sh index 45b5c1a4035..fbc5eae76e2 100644 --- a/pkg/deploy/generator/scripts/util-services.sh +++ b/pkg/deploy/generator/scripts/util-services.sh @@ -25,27 +25,33 @@ enable_services() { # 1) image - nameref, string; container image # 2) role - nameref, string; VMSS role # 3) conf_file - nameref, string; aro gateway environment file +# 4) ipaddress - nameref, string; static ip of podman network to be attached configure_service_aro_gateway() { local -n image="$1" local -n role="$2" local -n conf_file="$3" + local -n ipaddress="$4" log "starting" log "Configuring aro-gateway service" local -r aro_gateway_conf_filename='/etc/sysconfig/aro-gateway' + local -r add_conf_file="podman_network='podman' +IPADDRESS='$ipaddress' +ROLE='${role,,}'" write_file aro_gateway_conf_filename conf_file true + write_file aro_gateway_conf_filename add_conf_file false # shellcheck disable=SC2034 local -r aro_gateway_service_filename='/etc/systemd/system/aro-gateway.service' # shellcheck disable=SC2034 - local -r aro_gateway_service_file="[Unit] + local -r aro_gateway_service_file='[Unit] After=network-online.target Wants=network-online.target [Service] -EnvironmentFile=${aro_gateway_conf_filename} +EnvironmentFile=/etc/sysconfig/aro-gateway ExecStartPre=-/usr/bin/podman rm -f %N ExecStart=/usr/bin/podman run \ --hostname %H \ @@ -59,13 +65,15 @@ ExecStart=/usr/bin/podman run \ -e MDM_ACCOUNT \ -e MDM_NAMESPACE \ -m 2g \ + --network=${PODMAN_NETWORK} \ + --ip ${IPADDRESS} \ -p 80:8080 \ -p 8081:8081 \ -p 443:8443 \ -v /run/systemd/journal:/run/systemd/journal \ -v /var/etw:/var/etw:z \ - $image \ - ${role,,} + $RPIMAGE \ + $ROLE ExecStop=/usr/bin/podman stop -t 3600 %N TimeoutStopSec=3600 Restart=always @@ -74,7 +82,7 @@ StartLimitInterval=0 [Install] WantedBy=multi-user.target - " + ' write_file aro_gateway_service_filename aro_gateway_service_file true } @@ -84,26 +92,32 @@ WantedBy=multi-user.target # 1) image - nameref, string; RP container image # 2) role - nameref, string; VMSS role # 3) conf_file - nameref, string; aro rp environment file +# 4) ipaddress - nameref, string; static ip of podman network to be attached configure_service_aro_rp() { local -n image="$1" local -n role="$2" local -n conf_file="$3" + local -n ipaddress="$4" log "starting" log "Configuring aro-rp service" local -r aro_rp_conf_filename='/etc/sysconfig/aro-rp' + local -r add_conf_file="podman_network='podman' +IPADDRESS='$ipaddress' +ROLE='${role,,}'" write_file aro_rp_conf_filename conf_file true + write_file aro_rp_conf_filename add_conf_file false # shellcheck disable=SC2034 local -r aro_rp_service_filename='/etc/systemd/system/aro-rp.service' # shellcheck disable=SC2034 - local -r aro_rp_service_file="[Unit] + local -r aro_rp_service_file='[Unit] After=network-online.target Wants=network-online.target [Service] -EnvironmentFile=${aro_rp_conf_filename} +EnvironmentFile=/etc/sysconfig/aro-rp ExecStartPre=-/usr/bin/podman rm -f %N ExecStart=/usr/bin/podman run \ --hostname %H \ @@ -135,13 +149,16 @@ ExecStart=/usr/bin/podman run \ -e OIDC_AFD_ENDPOINT \ -e OIDC_STORAGE_ACCOUNT_NAME \ -e MSI_RP_ENDPOINT \ + -e MISE_ADDRESS \ -m 2g \ + --network=${PODMAN_NETWORK} \ + --ip ${IPADDRESS} \ -p 443:8443 \ -v /etc/aro-rp:/etc/aro-rp \ -v /run/systemd/journal:/run/systemd/journal \ -v /var/etw:/var/etw:z \ - $image \ - ${role,,} + $RPIMAGE \ + $ROLE ExecStop=/usr/bin/podman stop -t 3600 %N TimeoutStopSec=3600 Restart=always @@ -149,7 +166,7 @@ RestartSec=1 StartLimitInterval=0 [Install] -WantedBy=multi-user.target" +WantedBy=multi-user.target' write_file aro_rp_service_filename aro_rp_service_file true } @@ -157,8 +174,10 @@ WantedBy=multi-user.target" # configure_service_aro_monitor # args: # 1) image - nameref, string; RP container image +# 2) ipaddress - nameref, string; static ip of podman network to be attached configure_service_aro_monitor() { local -n image="$1" + local -n ipaddress="$2" log "starting" log "Configuring aro-monitor service" @@ -181,14 +200,16 @@ DATABASE_ACCOUNT_NAME='$DATABASEACCOUNTNAME' KEYVAULT_PREFIX='$KEYVAULTPREFIX' MDM_ACCOUNT='$RPMDMACCOUNT' MDM_NAMESPACE=BBM -RPIMAGE='$image'" +RPIMAGE='$image' +podman_network='podman' +IPADDRESS='$ipaddress'" write_file aro_monitor_service_conf_filename aro_monitor_service_conf_file true # shellcheck disable=SC2034 local -r aro_monitor_service_filename='/etc/systemd/system/aro-monitor.service' # shellcheck disable=SC2034 - local -r aro_monitor_service_file="[Unit] + local -r aro_monitor_service_file='[Unit] After=network-online.target Wants=network-online.target @@ -200,6 +221,8 @@ ExecStart=/usr/bin/podman run \ --name %N \ --rm \ --cap-drop net_raw \ + --network=${PODMAN_NETWORK} \ + --ip ${IPADDRESS} \ -e AZURE_FP_CLIENT_ID \ -e DOMAIN_NAME \ -e CLUSTER_MDSD_ACCOUNT \ @@ -217,14 +240,14 @@ ExecStart=/usr/bin/podman run \ -m 2.5g \ -v /run/systemd/journal:/run/systemd/journal \ -v /var/etw:/var/etw:z \ - $image \ + $RPIMAGE \ monitor Restart=always RestartSec=1 StartLimitInterval=0 [Install] -WantedBy=multi-user.target" +WantedBy=multi-user.target' write_file aro_monitor_service_filename aro_monitor_service_file true } @@ -232,8 +255,10 @@ WantedBy=multi-user.target" # configure_service_aro_portal # args: # 1) image - nameref, string; RP container image +# 2) ipaddress - nameref, string; static ip of podman network to be attached configure_service_aro_portal() { local -n image="$1" + local -n ipaddress="$2" log "starting" log "Configuring aro portal service" @@ -248,14 +273,16 @@ KEYVAULT_PREFIX='$KEYVAULTPREFIX' MDM_ACCOUNT='$RPMDMACCOUNT' MDM_NAMESPACE=Portal PORTAL_HOSTNAME='$LOCATION.admin.$RPPARENTDOMAINNAME' -RPIMAGE='$image'" +RPIMAGE='$image' +podman_network='podman' +IPADDRESS='$ipaddress'" write_file aro_portal_service_conf_filename aro_portal_service_conf_file true # shellcheck disable=SC2034 local -r aro_portal_service_filename='/etc/systemd/system/aro-portal.service' # shellcheck disable=SC2034 - local -r aro_portal_service_file="[Unit] + local -r aro_portal_service_file='[Unit] After=network-online.target Wants=network-online.target StartLimitInterval=0 @@ -268,6 +295,8 @@ ExecStart=/usr/bin/podman run \ --name %N \ --rm \ --cap-drop net_raw \ + --network=${PODMAN_NETWORK} \ + --ip ${IPADDRESS} \ -e AZURE_PORTAL_ACCESS_GROUP_IDS \ -e AZURE_PORTAL_CLIENT_ID \ -e AZURE_PORTAL_ELEVATED_GROUP_IDS \ @@ -281,17 +310,224 @@ ExecStart=/usr/bin/podman run \ -p 2222:2222 \ -v /run/systemd/journal:/run/systemd/journal \ -v /var/etw:/var/etw:z \ - $image \ + $RPIMAGE \ portal Restart=always RestartSec=1 [Install] -WantedBy=multi-user.target" +WantedBy=multi-user.target' write_file aro_portal_service_filename aro_portal_service_file true } +# configure_service_aro_mise +# args: +# 1) image - nameref, string; MISE container image +# 2) ipaddress - nameref, string; static ip of podman network to be attached +configure_service_aro_mise() { + local -n image="$1" + local -n ipaddress="$2" + log "starting" + log "Configuring aro-mise service" + + LOGININSTANCE="https://login.microsoftonline.com" + if [[ $AZURECLOUDNAME == "AzureUSGovernment" ]]; then + LOGININSTANCE="https://login.microsoftonline.us" + fi + # shellcheck disable=SC2034 + local -r aro_mise_service_conf_filename='/etc/sysconfig/aro-mise' + # shellcheck disable=SC2034 + local -r aro_mise_service_conf_file="FPCLIENTID='$FPCLIENTID' +FPTENANTID='$FPTENANTID' +MISEIMAGE='$image' +MISEVALIDAUDIENCES='$MISEVALIDAUDIENCES' +MISEVALIDAPPIDS='$MISEVALIDAPPIDS' +LOGININSTANCE='$LOGININSTANCE' +podman_network='podman' +IPADDRESS='$ipaddress'" + + write_file aro_mise_service_conf_filename aro_mise_service_conf_file true + + mkdir -p /app/mise + # shellcheck disable=SC2034 + local -r aro_mise_appsettings_filename='/app/mise/appsettings.json' + # shellcheck disable=SC2034 + local -r aro_mise_appsettings_file="{ + \"Version\": \"1\", + \"HeartbeatIntervalMs\": 5000, + \"AzureAd\": { + \"Instance\": \"$LOGININSTANCE\", + \"ClientId\": \"$FPCLIENTID\", + \"TenantId\": \"$FPTENANTID\", + \"Audience\": \"api://$FPCLIENTID\", + \"ShowPII\": false, + \"InboundPolicies\": [ + { + \"Label\": \"arorp-arm-inbound-policy\", + \"Authority\": \"$LOGININSTANCE/$FPTENANTID/\" +, + \"AuthenticationSchemes\": [ + \"PoP\" + ], + \"ValidAudiences\": $MISEVALIDAUDIENCES, + \"SignedHttpRequestValidationPolicy\": { + \"ValidateTs\": true, + \"ValidateM\": true, + \"ValidateU\": true, + \"ValidateP\": true + }, + \"ValidApplicationIds\": $MISEVALIDAPPIDS + } + ], + \"Logging\": { + \"LogLevel\": \"Information\" + }, + \"Modules\": { + \"TrV2\": { + \"ModuleType\": \"TrV2Module\", + \"Enabled\": true + } + } + }, + \"AllowedHosts\": \"*\", + \"Kestrel\": { + \"Endpoints\": { + \"Http\": { + \"Url\": \"http://$ipaddress:5000\" + } + } + }, + \"Logging\": { + \"LogLevel\": { + \"Default\": \"Information\", + \"Microsoft\": \"Information\", + \"Microsoft.Hosting.Lifetime\": \"Information\" + } + } +}" + + write_file aro_mise_appsettings_filename aro_mise_appsettings_file true + + # shellcheck disable=SC2034 + local -r aro_mise_service_filename='/etc/systemd/system/aro-mise.service' + # shellcheck disable=SC2034 + local -r aro_mise_service_file='[Unit] +After=network-online.target +Wants=network-online.target +StartLimitIntervalSec=0 +[Service] +RestartSec=1s +EnvironmentFile=/etc/sysconfig/aro-mise +ExecStartPre=-/usr/bin/podman rm -f %N +ExecStart=/usr/bin/podman run \ + -p 5000:5000 \ + -v /app/mise/appsettings.json:/app/appsettings.json:z \ + --hostname %H \ + --name %N \ + --network=${PODMAN_NETWORK} \ + --ip ${IPADDRESS} \ + --rm \ + $MISEIMAGE +ExecStop=/usr/bin/podman stop %N +Restart=always +RestartSec=3 +StartLimitInterval=0 +[Install] +WantedBy=multi-user.target' + + write_file aro_mise_service_filename aro_mise_service_file true +} +# configure_service_aro_otel_collector +# args: +# 1) image - nameref, string; OTEL container image +# 2) static_ip_address - nameref, array; static ips of all services +# 3) ipaddress - nameref, string; static ip of podman network to be attached +configure_service_aro_otel_collector() { + local -n image="$1" + local -n static_ip_address="$2" + local -n ipaddress="$3" + log "starting" + log "Configuring aro-otel-collector service" + + # shellcheck disable=SC2034 + local -r aro_otel_collector_service_conf_filename='/etc/sysconfig/aro-otel-collector' + # shellcheck disable=SC2034 + local -r aro_otel_collector_service_conf_file="GOMEMLIMIT=1000MiB +OTELIMAGE='$image' +podman_network='podman' +IPADDRESS='$ipaddress'" + + write_file aro_otel_collector_service_conf_filename aro_otel_collector_service_conf_file true + + mkdir -p /app/otel + # shellcheck disable=SC2034 + local -r aro_otel_collector_appconfig_filename='/app/otel/config.yaml' + # shellcheck disable=SC2034 + local -r aro_otel_collector_appconfig_file="receivers: + httpcheck: + targets: + # MISE Endpoints + - endpoint: http://${static_ip_address["mise"]}:5000/healthz + method: GET + - endpoint: http://${static_ip_address["mise"]}:5000/readyz + method: GET + # OTELs own Endpoints + - endpoint: http://$ipaddress:13133/healthz + method: GET + - endpoint: http://$ipaddress:13133/readyz + method: GET + collection_interval: 20s +processors: + batch: +extensions: + health_check: + endpoint: $ipaddress:13133 +exporters: + otlp: + endpoint: ${static_ip_address["mdm"]}:4317 + tls: + insecure: true +service: + extensions: [health_check] + pipelines: + metrics: + receivers: [httpcheck] + processors: [batch] + exporters: [otlp]" + + write_file aro_otel_collector_appconfig_filename aro_otel_collector_appconfig_file true + + # shellcheck disable=SC2034 + local -r aro_otel_collector_service_filename='/etc/systemd/system/aro-otel-collector.service' + # shellcheck disable=SC2034 + local -r aro_otel_collector_service_file='[Unit] +After=mdm.service +Wants=mdm.service +StartLimitIntervalSec=0 +[Service] +RestartSec=1s +EnvironmentFile=/etc/sysconfig/aro-otel-collector +ExecStartPre=-/usr/bin/podman rm -f %N +ExecStart=/usr/bin/podman run \ + --hostname %H \ + --name %N \ + --rm \ + --network=${PODMAN_NETWORK} \ + --ip $IPADDRESS \ + -m 2g \ + -v /app/otel/config.yaml:/etc/otelcol-contrib/config.yaml:z \ + $OTELIMAGE +ExecStop=/usr/bin/podman stop %N +Restart=always +RestartSec=3 +StartLimitInterval=0 +[Install] +WantedBy=multi-user.target' + + write_file aro_otel_collector_service_filename aro_otel_collector_service_file true +} + # configure_service_mdsd # args: # 1) monitoring_role - nameref, string; can be "gateway" or "rp" @@ -344,10 +580,12 @@ export MDSD_MSGPACK_SORT_COLUMNS=\"1\"" # args: # 1) conf_file - string; fluenbit configuration file # 2) image - string; fluentbit container image to run +# 3) ipaddress - nameref, string; static ip of podman network to be attached configure_service_fluentbit() { # shellcheck disable=SC2034 local -n conf_file="$1" local -n image="$2" + local -n ipaddress="$3" log "starting" log "Configuring fluentbit service" @@ -361,14 +599,16 @@ configure_service_fluentbit() { # shellcheck disable=SC2034 local -r sysconfig_filename='/etc/sysconfig/fluentbit' # shellcheck disable=SC2034 - local -r sysconfig_file="FLUENTBITIMAGE=$image" + local -r sysconfig_file="FLUENTBITIMAGE=$image +podman_network='podman' +IPADDRESS='$ipaddress'" write_file sysconfig_filename sysconfig_file true # shellcheck disable=SC2034 local -r service_filename='/etc/systemd/system/fluentbit.service' # shellcheck disable=SC2034 - local -r service_file="[Unit] + local -r service_file='[Unit] After=network-online.target Wants=network-online.target StartLimitIntervalSec=0 @@ -380,7 +620,8 @@ ExecStartPre=-/usr/bin/podman rm -f %N ExecStart=/usr/bin/podman run \ --security-opt label=disable \ --entrypoint /opt/td-agent-bit/bin/td-agent-bit \ - --net=host \ + --network=${PODMAN_NETWORK} \ + --ip ${IPADDRESS} \ --hostname %H \ --name %N \ --rm \ @@ -389,7 +630,7 @@ ExecStart=/usr/bin/podman run \ -v /var/lib/fluent:/var/lib/fluent:z \ -v /var/log/journal:/var/log/journal:ro \ -v /etc/machine-id:/etc/machine-id:ro \ - $image \ + $FLUENTBITIMAGE \ -c /etc/fluentbit/fluentbit.conf ExecStop=/usr/bin/podman stop %N @@ -398,7 +639,7 @@ RestartSec=5 StartLimitInterval=0 [Install] -WantedBy=multi-user.target" +WantedBy=multi-user.target' write_file service_filename service_file true } @@ -563,9 +804,11 @@ WantedBy=multi-user.target' # args: # 1) role - nameref, string; can be "gateway" or "rp" # 2) image - nameref, string; mdm container image to run +# 3) ipaddress - nameref, string; static ip of podman network to be attached configure_service_mdm() { local -n role="$1" local -n image="$2" + local -n ipaddress="$3" log "starting" log "Configuring mdm service" @@ -578,7 +821,12 @@ configure_service_mdm() { MDMIMAGE='$image' MDMSOURCEENVIRONMENT='$LOCATION' MDMSOURCEROLE='$role' -MDMSOURCEROLEINSTANCE=\"$(hostname)\"" +MDMSOURCEROLEINSTANCE=\"$(hostname)\" +MDM_INPUT=statsd_local,otlp_grpc +MDM_NAMESPACE='OTEL' +MDM_ACCOUNT='AzureRedHatOpenShiftRP' +podman_network='podman' +IPADDRESS='$ipaddress'" write_file sysconfig_mdm_filename sysconfig_mdm_file true @@ -586,7 +834,7 @@ MDMSOURCEROLEINSTANCE=\"$(hostname)\"" # shellcheck disable=SC2034 local -r mdm_service_filename="/etc/systemd/system/mdm.service" # shellcheck disable=SC2034 - local -r mdm_service_file="[Unit] + local -r mdm_service_file='[Unit] After=network-online.target Wants=network-online.target @@ -599,25 +847,30 @@ ExecStart=/usr/bin/podman run \ --name %N \ --rm \ --cap-drop net_raw \ + --network=${PODMAN_NETWORK} \ + --ip ${IPADDRESS} \ -m 2g \ -v /etc/mdm.pem:/etc/mdm.pem \ -v /var/etw:/var/etw:z \ - $image \ + $MDMIMAGE \ + -Input $MDM_INPUT \ + -MetricNamespace $MDM_NAMESPACE \ + -MonitoringAccount $MDM_ACCOUNT \ -CertFile /etc/mdm.pem \ -FrontEndUrl $MDMFRONTENDURL \ -Logger Console \ -LogLevel Warning \ -PrivateKeyFile /etc/mdm.pem \ - -SourceEnvironment $LOCATION \ - -SourceRole $role \ - -SourceRoleInstance $HOSTNAME + -SourceEnvironment $MDMSOURCEENVIRONMENT \ + -SourceRole $MDMSOURCEROLE \ + -SourceRoleInstance $MDMSOURCEROLEINSTANCE ExecStop=/usr/bin/podman stop %N Restart=always RestartSec=1 StartLimitInterval=0 [Install] -WantedBy=multi-user.target" +WantedBy=multi-user.target' write_file mdm_service_filename mdm_service_file true } @@ -636,18 +889,20 @@ configure_vmss_aro_services() { verify_role "$1" if [ "$r" == "$role_gateway" ]; then - configure_service_aro_gateway "${images["rp"]}" "$1" "${configs["gateway_config"]}" + configure_service_aro_gateway "${images["rp"]}" "$1" "${configs["gateway_config"]}" "${configs["static_ip_address"]}["gateway"]" configure_certs_gateway elif [ "$r" == "$role_rp" ]; then - configure_service_aro_rp "${images["rp"]}" "$1" "${configs["rp_config"]}" - configure_service_aro_monitor "${images["rp"]}" - configure_service_aro_portal "${images["rp"]}" + configure_service_aro_rp "${images["rp"]}" "$1" "${configs["rp_config"]}" "${configs["static_ip_address"]}["rp"]" + configure_service_aro_monitor "${images["rp"]}" "${configs["static_ip_address"]}["monitor"]" + configure_service_aro_portal "${images["rp"]}" "${configs["static_ip_address"]}["portal"]" + configure_service_aro_mise "${images["mise"]}" "${configs["static_ip_address"]}["mise"]" + configure_service_aro_otel_collector "${images["otel"]}" "${configs["static_ip_address"]}" "${configs["static_ip_address"]}["otel_collector"]" configure_certs_rp fi - configure_service_fluentbit "${configs["fluentbit"]}" "${images["fluentbit"]}" + configure_service_fluentbit "${configs["fluentbit"]}" "${images["fluentbit"]}" "${configs["static_ip_address"]}["fluentbit"]" configure_timers_mdm_mdsd "$1" - configure_service_mdm "$1" "${images["mdm"]}" + configure_service_mdm "$1" "${images["mdm"]}" "${configs["static_ip_address"]}["mdm"]" configure_service_mdsd "$1" "${configs["mdsd"]}" run_azsecd_config_scan } diff --git a/pkg/deploy/generator/templates_rp.go b/pkg/deploy/generator/templates_rp.go index 42872e9cf69..cc4d400655f 100644 --- a/pkg/deploy/generator/templates_rp.go +++ b/pkg/deploy/generator/templates_rp.go @@ -49,6 +49,7 @@ func (g *generator) rpTemplate() *arm.Template { "disableCosmosDBFirewall", "fluentbitImage", "fpClientId", + "fpTenantId", "fpServicePrincipalId", "ipRules", "keyvaultPrefix", @@ -59,6 +60,8 @@ func (g *generator) rpTemplate() *arm.Template { "ipRules", "mdmFrontendUrl", "mdsdEnvironment", + "miseValidAudiences", + "miseValidAppIDs", "nonZonalRegions", "portalAccessGroupIds", "portalClientId", @@ -115,6 +118,10 @@ func (g *generator) rpTemplate() *arm.Template { case "rpVmssCapacity": p.Type = "int" p.DefaultValue = 3 + case "miseValidAudiences": + p.Type = "array" + case "miseValidAppIDs": + p.Type = "array" case "nonZonalRegions": p.Type = "array" p.DefaultValue = []string{ diff --git a/pkg/env/env.go b/pkg/env/env.go index 4031bc0e166..29718ae8cd7 100644 --- a/pkg/env/env.go +++ b/pkg/env/env.go @@ -24,6 +24,7 @@ import ( "github.com/Azure/ARO-RP/pkg/util/clientauthorizer" "github.com/Azure/ARO-RP/pkg/util/keyvault" "github.com/Azure/ARO-RP/pkg/util/liveconfig" + "github.com/Azure/ARO-RP/pkg/util/miseadapter" ) type Feature int @@ -39,6 +40,8 @@ const ( FeatureEnableOCMEndpoints FeatureRequireOIDCStorageWebEndpoint FeatureUseMockMsiRp + FeatureEnableMISE + FeatureEnforceMISE ) const ( @@ -80,6 +83,7 @@ type Interface interface { InitializeAuthorizers() error ArmClientAuthorizer() clientauthorizer.ClientAuthorizer AdminClientAuthorizer() clientauthorizer.ClientAuthorizer + MISEAuthorizer() miseadapter.MISEAdapter ClusterGenevaLoggingAccount() string ClusterGenevaLoggingConfigVersion() string ClusterGenevaLoggingEnvironment() string diff --git a/pkg/env/prod.go b/pkg/env/prod.go index e46e454c949..f603339d902 100644 --- a/pkg/env/prod.go +++ b/pkg/env/prod.go @@ -32,6 +32,7 @@ import ( "github.com/Azure/ARO-RP/pkg/util/computeskus" "github.com/Azure/ARO-RP/pkg/util/keyvault" "github.com/Azure/ARO-RP/pkg/util/liveconfig" + "github.com/Azure/ARO-RP/pkg/util/miseadapter" "github.com/Azure/ARO-RP/pkg/util/version" ) @@ -50,6 +51,7 @@ type prod struct { armClientAuthorizer clientauthorizer.ClientAuthorizer adminClientAuthorizer clientauthorizer.ClientAuthorizer + miseAuthorizer miseadapter.MISEAdapter acrDomain string vmskus map[string]*mgmtcompute.ResourceSku @@ -223,20 +225,36 @@ func newProd(ctx context.Context, log *logrus.Entry, component ServiceComponent) return p, nil } +func (p *prod) MISEAuthorizer() miseadapter.MISEAdapter { + return p.miseAuthorizer +} + func (p *prod) InitializeAuthorizers() error { - if !p.FeatureIsSet(FeatureEnableDevelopmentAuthorizer) { - p.armClientAuthorizer = clientauthorizer.NewARM(p.log, p.Core) - } else { - armClientAuthorizer, err := clientauthorizer.NewSubjectNameAndIssuer( - p.log, - "/etc/aro-rp/arm-ca-bundle.pem", - os.Getenv("ARM_API_CLIENT_CERT_COMMON_NAME"), + if p.FeatureIsSet(FeatureEnableMISE) { + err := ValidateVars( + "MISE_ADDRESS", ) if err != nil { return err } + p.miseAuthorizer = miseadapter.NewAuthorizer(os.Getenv("MISE_ADDRESS"), p.log) + } - p.armClientAuthorizer = armClientAuthorizer + if !p.FeatureIsSet(FeatureEnforceMISE) { + if !p.FeatureIsSet(FeatureEnableDevelopmentAuthorizer) { + p.armClientAuthorizer = clientauthorizer.NewARM(p.log, p.Core) + } else { + armClientAuthorizer, err := clientauthorizer.NewSubjectNameAndIssuer( + p.log, + "/etc/aro-rp/arm-ca-bundle.pem", + os.Getenv("ARM_API_CLIENT_CERT_COMMON_NAME"), + ) + if err != nil { + return err + } + + p.armClientAuthorizer = armClientAuthorizer + } } adminClientAuthorizer, err := clientauthorizer.NewSubjectNameAndIssuer( diff --git a/pkg/env/zz_generated_feature_enumer.go b/pkg/env/zz_generated_feature_enumer.go index c43b9ebdac2..7dda2619db9 100644 --- a/pkg/env/zz_generated_feature_enumer.go +++ b/pkg/env/zz_generated_feature_enumer.go @@ -7,11 +7,11 @@ import ( "strings" ) -const _FeatureName = "FeatureDisableDenyAssignmentsFeatureDisableSignedCertificatesFeatureEnableDevelopmentAuthorizerFeatureRequireD2sV3WorkersFeatureDisableReadinessDelayFeatureEnableOCMEndpointsFeatureRequireOIDCStorageWebEndpointFeatureUseMockMsiRp" +const _FeatureName = "FeatureDisableDenyAssignmentsFeatureDisableSignedCertificatesFeatureEnableDevelopmentAuthorizerFeatureRequireD2sV3WorkersFeatureDisableReadinessDelayFeatureEnableOCMEndpointsFeatureRequireOIDCStorageWebEndpointFeatureUseMockMsiRpFeatureEnableMISEFeatureEnforceMISE" -var _FeatureIndex = [...]uint8{0, 29, 61, 95, 121, 149, 174, 210, 229} +var _FeatureIndex = [...]uint16{0, 29, 61, 95, 121, 149, 174, 210, 229, 246, 264} -const _FeatureLowerName = "featuredisabledenyassignmentsfeaturedisablesignedcertificatesfeatureenabledevelopmentauthorizerfeaturerequired2sv3workersfeaturedisablereadinessdelayfeatureenableocmendpointsfeaturerequireoidcstoragewebendpointfeatureusemockmsirp" +const _FeatureLowerName = "featuredisabledenyassignmentsfeaturedisablesignedcertificatesfeatureenabledevelopmentauthorizerfeaturerequired2sv3workersfeaturedisablereadinessdelayfeatureenableocmendpointsfeaturerequireoidcstoragewebendpointfeatureusemockmsirpfeatureenablemisefeatureenforcemise" func (i Feature) String() string { if i < 0 || i >= Feature(len(_FeatureIndex)-1) { @@ -32,9 +32,11 @@ func _FeatureNoOp() { _ = x[FeatureEnableOCMEndpoints-(5)] _ = x[FeatureRequireOIDCStorageWebEndpoint-(6)] _ = x[FeatureUseMockMsiRp-(7)] + _ = x[FeatureEnableMISE-(8)] + _ = x[FeatureEnforceMISE-(9)] } -var _FeatureValues = []Feature{FeatureDisableDenyAssignments, FeatureDisableSignedCertificates, FeatureEnableDevelopmentAuthorizer, FeatureRequireD2sV3Workers, FeatureDisableReadinessDelay, FeatureEnableOCMEndpoints, FeatureRequireOIDCStorageWebEndpoint, FeatureUseMockMsiRp} +var _FeatureValues = []Feature{FeatureDisableDenyAssignments, FeatureDisableSignedCertificates, FeatureEnableDevelopmentAuthorizer, FeatureRequireD2sV3Workers, FeatureDisableReadinessDelay, FeatureEnableOCMEndpoints, FeatureRequireOIDCStorageWebEndpoint, FeatureUseMockMsiRp, FeatureEnableMISE, FeatureEnforceMISE} var _FeatureNameToValueMap = map[string]Feature{ _FeatureName[0:29]: FeatureDisableDenyAssignments, @@ -53,6 +55,10 @@ var _FeatureNameToValueMap = map[string]Feature{ _FeatureLowerName[174:210]: FeatureRequireOIDCStorageWebEndpoint, _FeatureName[210:229]: FeatureUseMockMsiRp, _FeatureLowerName[210:229]: FeatureUseMockMsiRp, + _FeatureName[229:246]: FeatureEnableMISE, + _FeatureLowerName[229:246]: FeatureEnableMISE, + _FeatureName[246:264]: FeatureEnforceMISE, + _FeatureLowerName[246:264]: FeatureEnforceMISE, } var _FeatureNames = []string{ @@ -64,6 +70,8 @@ var _FeatureNames = []string{ _FeatureName[149:174], _FeatureName[174:210], _FeatureName[210:229], + _FeatureName[229:246], + _FeatureName[246:264], } // FeatureString retrieves an enum value from the enum constants string name. diff --git a/pkg/frontend/frontend.go b/pkg/frontend/frontend.go index 83e9d97b660..1cdfc1fe529 100644 --- a/pkg/frontend/frontend.go +++ b/pkg/frontend/frontend.go @@ -148,8 +148,12 @@ func NewFrontend(ctx context.Context, Apis: api.APIs, }, authMiddleware: middleware.AuthMiddleware{ - AdminAuth: _env.AdminClientAuthorizer(), - ArmAuth: _env.ArmClientAuthorizer(), + Log: baseLog, + EnableMISE: _env.FeatureIsSet(env.FeatureEnableMISE), + EnforceMISE: _env.FeatureIsSet(env.FeatureEnforceMISE), + AdminAuth: _env.AdminClientAuthorizer(), + ArmAuth: _env.ArmClientAuthorizer(), + MiseAuth: _env.MISEAuthorizer(), }, dbGroup: dbGroup, apis: apis, diff --git a/pkg/frontend/middleware/authenticated.go b/pkg/frontend/middleware/authenticated.go index 45003eb284b..9937ee362ff 100644 --- a/pkg/frontend/middleware/authenticated.go +++ b/pkg/frontend/middleware/authenticated.go @@ -7,27 +7,55 @@ import ( "net/http" "strings" + "github.com/sirupsen/logrus" + "github.com/Azure/ARO-RP/pkg/api" "github.com/Azure/ARO-RP/pkg/api/admin" "github.com/Azure/ARO-RP/pkg/util/clientauthorizer" + "github.com/Azure/ARO-RP/pkg/util/miseadapter" ) type AuthMiddleware struct { + Log *logrus.Entry + + EnableMISE bool + EnforceMISE bool + AdminAuth clientauthorizer.ClientAuthorizer ArmAuth clientauthorizer.ClientAuthorizer + MiseAuth miseadapter.MISEAdapter } func (a AuthMiddleware) Authenticate(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var err error + var authenticated bool + // Admin API authorisation (Geneva Actions) is performed via mutual TLS + // authentication apiVersion := r.URL.Query().Get(api.APIVersionKey) - var clientAuthorizer clientauthorizer.ClientAuthorizer if apiVersion == admin.APIVersion || strings.HasPrefix(r.URL.Path, "/admin") { - clientAuthorizer = a.AdminAuth + authenticated = a.AdminAuth.IsAuthorized(r.TLS) } else { - clientAuthorizer = a.ArmAuth + // ARM traffic is authenticated via either MISE or mutual TLS + // authentication + if a.EnableMISE { + authenticated, err = a.MiseAuth.IsAuthorized(r.Context(), r) + if authenticated { + a.Log.Infoln("MISE authorization successful") + } else { + a.Log.Errorf("MISE authorization unsuccessful, enforcing: %t, error: %s", a.EnforceMISE, err) + } + } + + // If we do not enforce MISE, then fall back to checking the TLS + // certificate + if !a.EnforceMISE && !authenticated { + a.Log.Warnln("MISE authorization unsuccessful/disabled, fallback to TLS certificate authentication") + authenticated = a.ArmAuth.IsAuthorized(r.TLS) + } } - if !clientAuthorizer.IsAuthorized(r.TLS) { + if !authenticated { api.WriteError(w, http.StatusForbidden, api.CloudErrorCodeForbidden, "", "Forbidden.") return } diff --git a/pkg/frontend/ready_get.go b/pkg/frontend/ready_get.go index b62a6a7ff79..bc5f53c3e18 100644 --- a/pkg/frontend/ready_get.go +++ b/pkg/frontend/ready_get.go @@ -24,9 +24,18 @@ func (f *frontend) checkReady() bool { _, okOcpVersions := f.lastOcpVersionsChangefeed.Load().(time.Time) _, okPlatformWorkloadIdentityRoleSets := f.lastPlatformWorkloadIdentityRoleSetsChangefeed.Load().(time.Time) + var miseAuthReady, armAuthReady, authReady bool + if f.authMiddleware.EnableMISE { + miseAuthReady = f.env.MISEAuthorizer().IsReady() + } + // skip ARM Authorizer is MISE is Enforcing + if !f.authMiddleware.EnforceMISE { + armAuthReady = f.env.ArmClientAuthorizer().IsReady() + } + authReady = miseAuthReady || armAuthReady return okOcpVersions && okPlatformWorkloadIdentityRoleSets && f.ready.Load().(bool) && - f.env.ArmClientAuthorizer().IsReady() && + authReady && f.env.AdminClientAuthorizer().IsReady() } diff --git a/pkg/frontend/security_test.go b/pkg/frontend/security_test.go index c59e03280fe..c4591dba2cf 100644 --- a/pkg/frontend/security_test.go +++ b/pkg/frontend/security_test.go @@ -22,6 +22,7 @@ import ( "github.com/Azure/ARO-RP/pkg/util/azureclient" "github.com/Azure/ARO-RP/pkg/util/clientauthorizer" "github.com/Azure/ARO-RP/pkg/util/log/audit" + "github.com/Azure/ARO-RP/pkg/util/miseadapter" mock_env "github.com/Azure/ARO-RP/pkg/util/mocks/env" mock_keyvault "github.com/Azure/ARO-RP/pkg/util/mocks/keyvault" utiltls "github.com/Azure/ARO-RP/pkg/util/tls" @@ -50,6 +51,7 @@ func TestSecurity(t *testing.T) { t.Fatal(err) } + log := logrus.NewEntry(logrus.StandardLogger()) controller := gomock.NewController(t) defer controller.Finish() @@ -64,9 +66,12 @@ func TestSecurity(t *testing.T) { _env.EXPECT().ServiceKeyvault().AnyTimes().Return(keyvault) _env.EXPECT().ArmClientAuthorizer().AnyTimes().Return(clientauthorizer.NewOne(validclientcerts[0].Raw)) _env.EXPECT().AdminClientAuthorizer().AnyTimes().Return(clientauthorizer.NewOne(validadminclientcerts[0].Raw)) + _env.EXPECT().MISEAuthorizer().AnyTimes().Return(miseadapter.NewFakeAuthorizer("http://aro-mise-test:5000", log, http.DefaultClient)) _env.EXPECT().Listen().AnyTimes().Return(l, nil) _env.EXPECT().FeatureIsSet(env.FeatureDisableReadinessDelay).AnyTimes().Return(false) _env.EXPECT().FeatureIsSet(env.FeatureEnableOCMEndpoints).AnyTimes().Return(true) + _env.EXPECT().FeatureIsSet(env.FeatureEnableMISE).AnyTimes().Return(false) + _env.EXPECT().FeatureIsSet(env.FeatureEnforceMISE).AnyTimes().Return(false) invalidclientkey, invalidclientcerts, err := utiltls.GenerateKeyAndCertificate("invalidclient", nil, nil, false, true) if err != nil { @@ -76,7 +81,6 @@ func TestSecurity(t *testing.T) { pool := x509.NewCertPool() pool.AddCert(servercerts[0]) - log := logrus.NewEntry(logrus.StandardLogger()) auditHook, auditEntry := testlog.NewAudit() f, err := NewFrontend(ctx, auditEntry, log, _env, database.NewDBGroup(), api.APIs, &noop.Noop{}, &noop.Noop{}, nil, nil, nil, nil, nil, nil) if err != nil { diff --git a/pkg/frontend/shared_test.go b/pkg/frontend/shared_test.go index 0bd32983bef..1aa601a2768 100644 --- a/pkg/frontend/shared_test.go +++ b/pkg/frontend/shared_test.go @@ -26,6 +26,7 @@ import ( "github.com/Azure/ARO-RP/pkg/env" "github.com/Azure/ARO-RP/pkg/util/azureclient" "github.com/Azure/ARO-RP/pkg/util/clientauthorizer" + "github.com/Azure/ARO-RP/pkg/util/miseadapter" mock_clusterdata "github.com/Azure/ARO-RP/pkg/util/mocks/clusterdata" mock_env "github.com/Azure/ARO-RP/pkg/util/mocks/env" mock_keyvault "github.com/Azure/ARO-RP/pkg/util/mocks/keyvault" @@ -86,7 +87,7 @@ type testInfra struct { } func newTestInfra(t *testing.T) *testInfra { - return newTestInfraWithFeatures(t, map[env.Feature]bool{env.FeatureRequireD2sV3Workers: false, env.FeatureDisableReadinessDelay: false, env.FeatureEnableOCMEndpoints: false}) + return newTestInfraWithFeatures(t, map[env.Feature]bool{env.FeatureRequireD2sV3Workers: false, env.FeatureDisableReadinessDelay: false, env.FeatureEnableOCMEndpoints: false, env.FeatureEnableMISE: false, env.FeatureEnforceMISE: false}) } func newTestInfraWithFeatures(t *testing.T, features map[env.Feature]bool) *testInfra { @@ -100,6 +101,8 @@ func newTestInfraWithFeatures(t *testing.T, features map[env.Feature]bool) *test keyvault := mock_keyvault.NewMockManager(controller) keyvault.EXPECT().GetCertificateSecret(gomock.Any(), env.RPServerSecretName).AnyTimes().Return(serverkey, servercerts, nil) + log := logrus.NewEntry(logrus.StandardLogger()) + _env := mock_env.NewMockInterface(controller) _env.EXPECT().IsLocalDevelopmentMode().AnyTimes().Return(false) _env.EXPECT().Environment().AnyTimes().Return(&azureclient.PublicCloud) @@ -108,6 +111,7 @@ func newTestInfraWithFeatures(t *testing.T, features map[env.Feature]bool) *test _env.EXPECT().ServiceKeyvault().AnyTimes().Return(keyvault) _env.EXPECT().ArmClientAuthorizer().AnyTimes().Return(clientauthorizer.NewOne(clientcerts[0].Raw)) _env.EXPECT().AdminClientAuthorizer().AnyTimes().Return(clientauthorizer.NewOne(clientcerts[0].Raw)) + _env.EXPECT().MISEAuthorizer().AnyTimes().Return(miseadapter.NewFakeAuthorizer("http://aro-mise-test:5000", log, http.DefaultClient)) _env.EXPECT().Domain().AnyTimes().Return("aro.example") _env.EXPECT().Listen().AnyTimes().Return(l, nil) for f, val := range features { @@ -118,7 +122,6 @@ func newTestInfraWithFeatures(t *testing.T, features map[env.Feature]bool) *test enricherMock.EXPECT().Enrich(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() _, auditEntry := testlog.NewAudit() - log := logrus.NewEntry(logrus.StandardLogger()) fixture := testdatabase.NewFixture() checker := testdatabase.NewChecker() diff --git a/pkg/util/miseadapter/authorizer.go b/pkg/util/miseadapter/authorizer.go new file mode 100644 index 00000000000..6ce86f19fe9 --- /dev/null +++ b/pkg/util/miseadapter/authorizer.go @@ -0,0 +1,74 @@ +package miseadapter + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/sirupsen/logrus" +) + +type MISEAdapter interface { + IsAuthorized(ctx context.Context, r *http.Request) (bool, error) + IsReady() bool +} + +type miseAdapter struct { + client *Client + log *logrus.Entry +} + +func NewAuthorizer(miseAddress string, log *logrus.Entry) MISEAdapter { + return &miseAdapter{ + client: New(http.DefaultClient, miseAddress), + log: log, + } +} + +func (m *miseAdapter) IsAuthorized(ctx context.Context, r *http.Request) (bool, error) { + remoteAddr, _, _ := strings.Cut(r.RemoteAddr, ":") + + i := Input{ + OriginalUri: fmt.Sprintf("http://%s%s", r.Host, r.URL.Path), + OriginalMethod: r.Method, + OriginalIPAddress: remoteAddr, + AuthorizationHeader: r.Header.Get("Authorization"), + } + + result, err := m.client.ValidateRequest(ctx, i, m.log) + if err != nil { + return false, err + } + + if result.StatusCode != http.StatusOK { + m.log.Errorf("mise authentication failed with %d: %s", result.StatusCode, result.ErrorDescription) + return false, nil + } + + return true, nil +} + +func (m *miseAdapter) IsReady() bool { + req, err := http.NewRequest(http.MethodGet, m.client.miseAddress+"/readyz", nil) + if err != nil { + m.log.Errorf("mise request create failed, %s", err) + return false + } + m.client.httpClient = &http.Client{ + Timeout: 5 * time.Second, + } + resp, respErr := m.client.httpClient.Do(req) + if respErr != nil { + m.log.Errorf("mise readyz failed, %s", err) + return false + } + + defer resp.Body.Close() + + return resp.StatusCode == http.StatusOK +} diff --git a/pkg/util/miseadapter/authorizer_fake.go b/pkg/util/miseadapter/authorizer_fake.go new file mode 100644 index 00000000000..7b659520c1d --- /dev/null +++ b/pkg/util/miseadapter/authorizer_fake.go @@ -0,0 +1,38 @@ +package miseadapter + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "context" + "net/http" + + "github.com/sirupsen/logrus" +) + +type FakeMISEAdapter interface { + IsAuthorized(ctx context.Context, r *http.Request) (bool, error) + IsReady() bool +} + +type fakemiseAdapter struct { + client *Client + log *logrus.Entry + authorized bool + ready bool +} + +func NewFakeAuthorizer(miseAddress string, log *logrus.Entry, fakeclient *http.Client) MISEAdapter { + return &fakemiseAdapter{ + client: New(fakeclient, miseAddress), + log: log, + } +} + +func (fake *fakemiseAdapter) IsAuthorized(ctx context.Context, r *http.Request) (bool, error) { + return fake.authorized, nil +} + +func (fake *fakemiseAdapter) IsReady() bool { + return fake.ready +} diff --git a/pkg/util/miseadapter/miseadapter.go b/pkg/util/miseadapter/miseadapter.go new file mode 100644 index 00000000000..441916a2789 --- /dev/null +++ b/pkg/util/miseadapter/miseadapter.go @@ -0,0 +1,194 @@ +package miseadapter + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "context" + "encoding/base64" + "net/http" + "strings" + + "github.com/sirupsen/logrus" +) + +type ( + // Client can delegate token validation to the Mise container. + Client struct { + httpClient *http.Client + miseAddress string + } + + // Input is the set of input options for Client. + Input struct { + // OriginalUri is the Uri of the original request being validated. + OriginalUri string + + // OriginalMethod is the method of the original request being validated. + OriginalMethod string + + // OriginalIpAddress is the IP address of original request being validated. + OriginalIPAddress string + + // AuthorizationHeader is the authorization header of the original request being validated. + AuthorizationHeader string + + // ReturnAllActorClaims specifies whether to return all claims from the actor token. + ReturnAllActorClaims bool + + // ReturnAllSubjectClaims specifies whether to return all claims from the subject token. + ReturnAllSubjectClaims bool + + // ActorClaimsToReturn specifies the specific claims to return from the actor token if present. + ActorClaimsToReturn []string + + // SubjectClaimsToReturn specifies the specific claims to return from the subject token. + SubjectClaimsToReturn []string + } + + // Result is the authentication result. + Result struct { + // ActorClaims is the set of claims extracted from the actor token based on the input options. + ActorClaims map[string][]string + + // SubjectClaims is the set of claims extracted from the subject token based on the input options. + SubjectClaims map[string][]string + + // ErrorDescription is the description of the error from validating the token. + ErrorDescription []string + + // WWWAuthenticate is the value of the WWWAuthenticate header when the request is unauthorized. + WWWAuthenticate []string + + // StatusCode is the status code that the Mise container returns as a result of validating the token. + StatusCode int + } +) + +// New creates a Client able to delegate token validation. +func New(httpClient *http.Client, miseAddress string) *Client { + return &Client{ + httpClient: httpClient, + miseAddress: miseAddress, + } +} + +// ValidateRequest transforms the Input object to a request to the Mise container and returns +// the Result object. +func (c Client) ValidateRequest(ctx context.Context, input Input, log *logrus.Entry) (Result, error) { + req, reqErr := createRequest(ctx, c.miseAddress, input) + if reqErr != nil { + return Result{}, reqErr + } + + resp, respErr := c.httpClient.Do(req) + if respErr != nil { + return Result{}, respErr + } + + defer resp.Body.Close() + + return parseResponseIntoResult(resp) +} + +func createRequest(ctx context.Context, miseAddress string, input Input) (*http.Request, error) { + req, reqErr := http.NewRequestWithContext(ctx, http.MethodPost, miseAddress+"/ValidateRequest", nil) + if reqErr != nil { + return nil, reqErr + } + + req.Header.Add("Authorization", input.AuthorizationHeader) + req.Header.Add("Original-Uri", input.OriginalUri) + req.Header.Add("Original-Method", input.OriginalMethod) + req.Header.Add("X-Forwarded-For", input.OriginalIPAddress) + + if input.ReturnAllActorClaims { + req.Header.Add("Return-All-Actor-Token-Claims", "1") + } else { + for _, val := range input.ActorClaimsToReturn { + headerKey := "Return-Actor-Token-Claim-" + val + req.Header.Add(headerKey, "1") + } + } + + if input.ReturnAllSubjectClaims { + req.Header.Add("Return-All-Subject-Token-Claims", "1") + } else { + for _, val := range input.SubjectClaimsToReturn { + headerKey := "Return-Subject-Token-Claim-" + val + req.Header.Add(headerKey, "1") + } + } + + return req, nil +} + +func parseResponseIntoResult(response *http.Response) (Result, error) { + res := Result{ + StatusCode: response.StatusCode, + SubjectClaims: map[string][]string{}, + ActorClaims: map[string][]string{}, + } + + subjectTokenClaimPrefix := "Subject-Token-Claim-" + actorTokenClaimPrefix := "Actor-Token-Claim-" + encodedSubjectTokenClaimPrefix := "Subject-Token-Encoded-Claim-" + encodedActorTokenClaimPrefix := "Actor-Token-Encoded-Claim-" + + if response.StatusCode == http.StatusOK { + for k, v := range response.Header { + if strings.HasPrefix(k, subjectTokenClaimPrefix) { + claim := k[len(subjectTokenClaimPrefix):] + // Header will come in from the container, for example, as Subject-Token-Claim-oid + // but go on parsing the response header will canonicalize the header to Subject-Token-Claim-Oid + // the name should always be lower case. + claim = strings.ToLower(claim) + res.SubjectClaims[claim] = append(res.SubjectClaims[claim], v...) + } else if strings.HasPrefix(k, actorTokenClaimPrefix) { + claim := k[len(actorTokenClaimPrefix):] + // See comment above above about casing for Subject token claims + claim = strings.ToLower(claim) + res.ActorClaims[claim] = append(res.ActorClaims[claim], v...) + } else if strings.HasPrefix(k, encodedSubjectTokenClaimPrefix) { + claim := k[len(encodedSubjectTokenClaimPrefix):] + // See comment above above about casing for Subject token claims + claim = strings.ToLower(claim) + decodedValues, err := decodeClaims(v) + if err != nil { + return res, err + } + res.SubjectClaims[claim] = append(res.SubjectClaims[claim], decodedValues...) + } else if strings.HasPrefix(k, encodedActorTokenClaimPrefix) { + claim := k[len(encodedActorTokenClaimPrefix):] + // See comment above above about casing for Subject token claims + claim = strings.ToLower(claim) + decodedValues, err := decodeClaims(v) + if err != nil { + return res, err + } + res.ActorClaims[claim] = append(res.ActorClaims[claim], decodedValues...) + } + } + } else { + res.ErrorDescription = response.Header["Error-Description"] + + if response.StatusCode == http.StatusUnauthorized { + res.WWWAuthenticate = response.Header["Www-Authenticate"] + } + } + + return res, nil +} + +func decodeClaims(encodedClaims []string) ([]string, error) { + values := make([]string, len(encodedClaims)) + for i := range encodedClaims { + enc, err := base64.StdEncoding.DecodeString(encodedClaims[i]) + if err != nil { + return nil, err + } + values[i] = string(enc) + } + + return values, nil +} diff --git a/pkg/util/miseadapter/miseadapter_test.go b/pkg/util/miseadapter/miseadapter_test.go new file mode 100644 index 00000000000..f24ebf3ef35 --- /dev/null +++ b/pkg/util/miseadapter/miseadapter_test.go @@ -0,0 +1,257 @@ +package miseadapter + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "context" + "net/http" + "sort" + "testing" + + "github.com/go-test/deep" +) + +func Test_createRequest(t *testing.T) { + miseAddress := "http://localhost:5000" + + translatedRequest, err := http.NewRequestWithContext(context.Background(), http.MethodPost, miseAddress+"/ValidateRequest", nil) + if err != nil { + t.Fatal(err) + } + + translatedRequest.Header = http.Header{ + "Original-Uri": []string{"http://1.2.3.4/view"}, + "Original-Method": []string{http.MethodGet}, + "X-Forwarded-For": []string{"http://2.3.4.5"}, + "Authorization": []string{"Bearer token"}, + "Return-All-Actor-Token-Claims": []string{"1"}, + "Return-All-Subject-Token-Claims": []string{"1"}, + } + + translatedRequestWithSpecificClaims, err := http.NewRequestWithContext(context.Background(), http.MethodPost, miseAddress+"/ValidateRequest", nil) + if err != nil { + t.Fatal(err) + } + + translatedRequestWithSpecificClaims.Header = http.Header{ + "Original-Uri": []string{"http://1.2.3.4/view"}, + "Original-Method": []string{http.MethodGet}, + "X-Forwarded-For": []string{"http://2.3.4.5"}, + "Authorization": []string{"Bearer token"}, + "Return-Actor-Token-Claim-Tid": []string{"1"}, + "Return-Subject-Token-Claim-Tid": []string{"1"}, + } + + type args struct { + ctx context.Context + miseAddress string + input Input + } + tests := []struct { + name string + args args + want *http.Request + wantErr bool + }{ + { + name: "Input is translated", + args: args{ + ctx: context.Background(), + miseAddress: miseAddress, + input: Input{ + OriginalUri: "http://1.2.3.4/view", + OriginalMethod: http.MethodGet, + OriginalIPAddress: "http://2.3.4.5", + AuthorizationHeader: "Bearer token", + ReturnAllActorClaims: true, + ReturnAllSubjectClaims: true, + }, + }, + want: translatedRequest, + wantErr: false, + }, + { + name: "Input is translated with specific claims", + args: args{ + ctx: context.Background(), + miseAddress: miseAddress, + input: Input{ + OriginalUri: "http://1.2.3.4/view", + OriginalMethod: http.MethodGet, + OriginalIPAddress: "http://2.3.4.5", + AuthorizationHeader: "Bearer token", + ActorClaimsToReturn: []string{"tid"}, + SubjectClaimsToReturn: []string{"tid"}, + }, + }, + want: translatedRequestWithSpecificClaims, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := createRequest(tt.args.ctx, tt.args.miseAddress, tt.args.input) + if (err != nil) != tt.wantErr { + t.Errorf("createRequest() error = %v, wantErr %v", err, tt.wantErr) + return + } + + if diff := deep.Equal(tt.want, got); diff != nil { + t.Errorf("-want/+got:\n%s", diff) + return + } + }) + } +} + +func Test_parseResponseIntoResult(t *testing.T) { + type args struct { + response *http.Response + } + + tests := []struct { + name string + args args + want Result + wantErr bool + }{ + { + name: "parse OK response and claims", + args: args{ + response: &http.Response{ + StatusCode: http.StatusOK, + Header: http.Header{ + http.CanonicalHeaderKey("Subject-Token-Claim-tid"): []string{"tid-2"}, + http.CanonicalHeaderKey("Actor-Token-Claim-tid"): []string{"tid-1"}, + }, + }, + }, + want: Result{ + StatusCode: http.StatusOK, + ActorClaims: map[string][]string{"tid": {"tid-1"}}, + SubjectClaims: map[string][]string{"tid": {"tid-2"}}, + }, + }, + { + name: "parse OK response and encoded claims", + args: args{ + response: &http.Response{ + StatusCode: http.StatusOK, + Header: http.Header{ + http.CanonicalHeaderKey("Subject-Token-Encoded-Claim-season"): []string{"ZnLDvGhsaW5n"}, + http.CanonicalHeaderKey("Actor-Token-Encoded-Claim-season"): []string{"5pil"}, + }, + }, + }, + want: Result{ + StatusCode: http.StatusOK, + ActorClaims: map[string][]string{"season": {"春"}}, + SubjectClaims: map[string][]string{"season": {"frühling"}}, + }, + }, + { + name: "parse OK response and encoded claims roles", + args: args{ + response: &http.Response{ + StatusCode: http.StatusOK, + Header: http.Header{ + http.CanonicalHeaderKey("Subject-Token-Encoded-Claim-roles"): []string{"ZnLDvGhsaW5n", "5pil"}, + }, + }, + }, + want: Result{ + StatusCode: http.StatusOK, + ActorClaims: map[string][]string{}, + SubjectClaims: map[string][]string{"roles": {"frühling", "春"}}, + }, + }, + { + name: "parse OK response and not encoded and encoded claims roles", + args: args{ + response: &http.Response{ + StatusCode: http.StatusOK, + Header: http.Header{ + http.CanonicalHeaderKey("Subject-Token-Claim-roles"): []string{"spring"}, + http.CanonicalHeaderKey("Subject-Token-Encoded-Claim-roles"): []string{"ZnLDvGhsaW5n"}, + }, + }, + }, + want: Result{ + StatusCode: http.StatusOK, + ActorClaims: map[string][]string{}, + SubjectClaims: map[string][]string{"roles": {"frühling", "spring"}}, + }, + }, + { + name: "parse OK response and encoded and not encoded claims roles", + args: args{ + response: &http.Response{ + StatusCode: http.StatusOK, + Header: http.Header{ + http.CanonicalHeaderKey("Subject-Token-Encoded-Claim-roles"): []string{"ZnLDvGhsaW5n"}, + http.CanonicalHeaderKey("Subject-Token-Claim-roles"): []string{"spring"}, + }, + }, + }, + want: Result{ + StatusCode: http.StatusOK, + ActorClaims: map[string][]string{}, + SubjectClaims: map[string][]string{"roles": {"frühling", "spring"}}, + }, + }, + { + name: "parse OK response and claims with multiple values", + args: args{ + response: &http.Response{ + StatusCode: http.StatusOK, + Header: http.Header{ + http.CanonicalHeaderKey("Subject-Token-Claim-roles"): []string{"role1", "role2"}, + }, + }, + }, + want: Result{ + StatusCode: http.StatusOK, + ActorClaims: map[string][]string{}, + SubjectClaims: map[string][]string{"roles": {"role1", "role2"}}, + }, + }, + { + name: "parse 401 response", + args: args{ + response: &http.Response{ + StatusCode: http.StatusUnauthorized, + Header: http.Header{ + http.CanonicalHeaderKey("Error-Description"): []string{"invalid issuer"}, + http.CanonicalHeaderKey("Www-Authenticate"): []string{"invalid token"}, + }, + }, + }, + want: Result{ + StatusCode: http.StatusUnauthorized, + WWWAuthenticate: []string{"invalid token"}, + ErrorDescription: []string{"invalid issuer"}, + ActorClaims: map[string][]string{}, + SubjectClaims: map[string][]string{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, gotErr := parseResponseIntoResult(tt.args.response) + + if tt.wantErr != (gotErr != nil) { + t.Errorf("wantErr: %v, gotErr: %v", tt.wantErr, gotErr) + } + + if got.SubjectClaims != nil && got.SubjectClaims["roles"] != nil { + sort.StringSlice(got.SubjectClaims["roles"]).Sort() + } + + if diff := deep.Equal(tt.want, got); diff != nil { + t.Errorf("-want/+got:\n%s", diff) + return + } + }) + } +} diff --git a/pkg/util/mocks/env/env.go b/pkg/util/mocks/env/env.go index e19883b7c85..ed0bd9f6337 100644 --- a/pkg/util/mocks/env/env.go +++ b/pkg/util/mocks/env/env.go @@ -30,6 +30,7 @@ import ( clientauthorizer "github.com/Azure/ARO-RP/pkg/util/clientauthorizer" keyvault "github.com/Azure/ARO-RP/pkg/util/keyvault" liveconfig "github.com/Azure/ARO-RP/pkg/util/liveconfig" + miseadapter "github.com/Azure/ARO-RP/pkg/util/miseadapter" ) // MockInterface is a mock of Interface interface. @@ -499,6 +500,20 @@ func (mr *MockInterfaceMockRecorder) Logger() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Logger", reflect.TypeOf((*MockInterface)(nil).Logger)) } +// MISEAuthorizer mocks base method. +func (m *MockInterface) MISEAuthorizer() miseadapter.MISEAdapter { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MISEAuthorizer") + ret0, _ := ret[0].(miseadapter.MISEAdapter) + return ret0 +} + +// MISEAuthorizer indicates an expected call of MISEAuthorizer. +func (mr *MockInterfaceMockRecorder) MISEAuthorizer() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MISEAuthorizer", reflect.TypeOf((*MockInterface)(nil).MISEAuthorizer)) +} + // MsiDataplaneClientOptions mocks base method. func (m *MockInterface) MsiDataplaneClientOptions(msiResourceId *arm.ResourceID) (*policy.ClientOptions, error) { m.ctrl.T.Helper() diff --git a/pkg/util/version/const.go b/pkg/util/version/const.go index 807e32ff7f1..1b47ca3a3b8 100644 --- a/pkg/util/version/const.go +++ b/pkg/util/version/const.go @@ -65,3 +65,12 @@ func MUOImage(acrDomain string) string { func GateKeeperImage(acrDomain string) string { return acrDomain + "/gatekeeper:v3.15.1" } + +// MiseImage contains the location of the Mise container image +func MiseImage(acrDomain string) string { + return acrDomain + "/mise:1.0.02773.115-mise-cbl-mariner2.0-distroless" +} + +func OTelImage(acrDomain string) string { + return "mcr.microsoft.com/oss/otel/opentelemetry-collector-contrib:0.95.0-linux-amd64" +}