From 828a4b6cf880a1cef12f41e889b19ae8c2b6a18c Mon Sep 17 00:00:00 2001 From: PG-Momik Date: Mon, 3 Feb 2025 10:01:09 +0545 Subject: [PATCH] - [x] Change completeness logic - [x] Update unit tests for completeness - [x] Fix completeness issues raised by QA --- .../RefreshActivityElementCompleteness.php | 16 +- .../Components/Elements/DefaultAidType.php | 5 +- .../Activity/Components/Elements/Sector.php | 95 +- .../Activity/Components/Elements/Tag.php | 69 +- app/Helpers/general.php | 46 + .../Admin/Activity/ActivityController.php | 4 +- .../Admin/Activity/TransactionController.php | 1 + .../RecipientCountryRequest.php | 4 + app/IATI/Data/elementJsonSchema.json | 66 +- .../Data/organizationElementJsonSchema.json | 66 +- .../Services/Activity/ActivityService.php | 37 +- .../Activity/CountryBudgetItemService.php | 2 +- .../Services/Activity/PolicyMarkerService.php | 6 +- .../Download/DownloadActivityService.php | 53 +- app/IATI/Services/ElementCompleteService.php | 344 +++++- .../ImportActivity/ImportCsvService.php | 19 +- .../ImportActivity/ImportXlsService.php | 66 +- .../ImportActivity/ImportXmlService.php | 18 +- .../DownloadActivitySimpleElementTrait.php | 87 +- app/Jobs/RegistryValidatorJob.php | 1 - app/Observers/ActivityObserver.php | 4 +- app/Observers/TransactionObserver.php | 37 +- .../Foundation/Mapper/XlsMapper.php | 14 +- .../Foundation/Queue/ImportXls.php | 1 + .../Foundation/Mapper/Components/Activity.php | 89 +- public/js/formbuilder.js | 130 +-- public/mix-manifest.json | 8 +- .../Element/ContactInfoCompleteTest.php | 456 ++------ .../Feature/Element/CountryBudgetItemTest.php | 263 +++-- tests/Feature/Element/ElementCompleteTest.php | 5 +- .../Feature/Element/LocationCompleteTest.php | 919 +++------------- .../Element/PlannedDisbursementTest.php | 322 +++--- .../Element/PolicyMarkerCompleteTest.php | 395 ++++++- tests/Feature/Element/SectorCompleteTest.php | 997 +++++++++++++++++- tests/Feature/Element/TagCompleteTest.php | 441 +++++++- .../Element/TransactionCompleteTest.php | 269 ++++- tests/Traits/FilterMandatoryItemsTrait.php | 25 + tests/Traits/TestDataTrait.php | 213 ++++ 38 files changed, 3761 insertions(+), 1832 deletions(-) create mode 100644 tests/Traits/FilterMandatoryItemsTrait.php create mode 100644 tests/Traits/TestDataTrait.php diff --git a/app/Console/Commands/RefreshActivityElementCompleteness.php b/app/Console/Commands/RefreshActivityElementCompleteness.php index 0c1893d37d..f9c2e681d3 100644 --- a/app/Console/Commands/RefreshActivityElementCompleteness.php +++ b/app/Console/Commands/RefreshActivityElementCompleteness.php @@ -9,6 +9,7 @@ use Exception; use Illuminate\Console\Command; use Illuminate\Contracts\Container\BindingResolutionException; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; /** @@ -45,22 +46,29 @@ public function handle(): void foreach ($activities as $activity) { $this->info("Started for activity: $activity->id"); - $activityElementNames = $activity->getAttributes(); + $activityElementNames = getActivityAttributes(); $elementStatus = []; - foreach ($activityElementNames as $element => $value) { + foreach ($activityElementNames as $element) { $methodName = dashesToCamelCase('is_' . $element . '_element_completed'); if (method_exists($elementCompleteService, $methodName)) { - $elementStatus[$element] = $elementCompleteService->$methodName($activity); + if ($element === 'reporting_org') { + $organization = $activity->organization; + $elementStatus[$element] = Arr::get($organization, 'element_status.reporting_org', false); + } else { + $elementStatus[$element] = $elementCompleteService->$methodName($activity); + } } } $elementStatus['result'] = $elementCompleteService->isResultElementCompleted($activity); $elementStatus['transactions'] = $elementCompleteService->isTransactionsElementCompleted($activity); + $complete_percentage = $elementCompleteService->calculateCompletePercentage($elementStatus); + $activity->timestamps = false; - $activity->updateQuietly(['element_status' => $elementStatus]); + $activity->updateQuietly(['element_status' => $elementStatus, 'complete_percentage' => $complete_percentage]); $this->info("Completed for activity: $activity->id"); $this->info('---------------------------------------'); diff --git a/app/CsvImporter/Entities/Activity/Components/Elements/DefaultAidType.php b/app/CsvImporter/Entities/Activity/Components/Elements/DefaultAidType.php index 6d152a2076..2ecf021eda 100644 --- a/app/CsvImporter/Entities/Activity/Components/Elements/DefaultAidType.php +++ b/app/CsvImporter/Entities/Activity/Components/Elements/DefaultAidType.php @@ -8,6 +8,7 @@ use App\CsvImporter\Entities\Activity\Components\Factory\Validation; use App\Http\Requests\Activity\DefaultAidType\DefaultAidTypeRequest; use App\IATI\Traits\DataSanitizeTrait; +use Illuminate\Support\Arr; /** * Class DefaultAidType. @@ -137,8 +138,8 @@ protected function setDefaultAidTypeCode($key, $value, $index): void } if ($key === $this->_csvHeaders[1]) { - $defaultAidTypeVocabulary = $this->data['default_aid_type'][$index]['default_aid_type_vocabulary'] ?? ''; - $defaultAidTypeVocabulary = empty($defaultAidTypeVocabulary) ?: (int) $defaultAidTypeVocabulary; + $accessKey = "default_aid_type.$index.default_aid_type_vocabulary"; + $defaultAidTypeVocabulary = Arr::get($this->data, $accessKey, '1'); $value = is_null($value) ? '' : trim($value); switch ($defaultAidTypeVocabulary) { diff --git a/app/CsvImporter/Entities/Activity/Components/Elements/Sector.php b/app/CsvImporter/Entities/Activity/Components/Elements/Sector.php index e4c2be26ab..d68a5a532a 100644 --- a/app/CsvImporter/Entities/Activity/Components/Elements/Sector.php +++ b/app/CsvImporter/Entities/Activity/Components/Elements/Sector.php @@ -112,6 +112,7 @@ public function prepare($fields): void * @param $index * * @return void + * @throws \JsonException */ public function map($key, $value, $index): void { @@ -161,45 +162,48 @@ protected function setSectorVocabulary($key, $value, $index): void /** * Set sector code for Sector. * - * @param $key - * @param $value - * @param $index + * This method handles setting the sector code based on the sector vocabulary. + * + * Extra condition: + * - Adds or unsets the 'text' key based on allowed sector vocabularies. + * - Allowed vocabularies: null, '', '3', '4', '5', '6', '9', '10', '11', '12', '98', '99'. + * - If the sector vocabulary is one of the allowed values, it makes sure 'text' key exists. + * - If the sector vocabulary is not allowed, it unsets the 'text' key. + * + * Based on the sector vocabulary, it performs different actions: + * - '1' -> Calls handleSectorVocabularyOne() to process value. + * - '2' -> Calls setSectorCategoryCode() to process value. + * - '7' -> Calls setSectorSdgGoal() to process value. + * - '8' -> Calls setSectorSdgTarget() to process value. + * - default -> Calls setSectorText() to process value. + * + * @param mixed $key The key for the sector field. + * @param mixed $value The value to be processed for the sector. + * @param int $index The index of the sector. * * @return void + * @throws \JsonException */ protected function setSectorCode($key, $value, $index): void { - if (!isset($this->data['sector'][$index]['text'])) { - $this->data['sector'][$index]['text'] = ''; + $accessKey = "sector.$index.sector_vocabulary"; + $allowedVocabularies = [null, '', '3', '4', '5', '6', '9', '10', '11', '12', '98', '99']; + $sectorVocabulary = Arr::get($this->data, $accessKey); + + if (!in_array($sectorVocabulary, $allowedVocabularies, true)) { + unset($this->data['sector'][$index]['text']); + } else { + $this->data['sector'][$index]['text'] = $this->data['sector'][$index]['text'] ?? ''; } if ($key === $this->_csvHeaders[1]) { - $sectorVocabulary = Arr::get($this->data['sector'], $index . '.sector_vocabulary', null); - - if ($sectorVocabulary === '1') { - $value = $value ? trim($value) : $value; - $this->codes[] = $value; - $validSectorCode = $this->loadCodeList('SectorCode'); - - if ($value) { - foreach ($validSectorCode as $code => $name) { - if (strcasecmp($value, $name) === 0) { - $value = (string) $code; - break; - } - } - } - - $this->data['sector'][$index]['code'] = $value; - } elseif ($sectorVocabulary === '2') { - $this->setSectorCategoryCode($value, $index); - } elseif ($sectorVocabulary === '7') { - $this->setSectorSdgGoal($value, $index); - } elseif ($sectorVocabulary === '8') { - $this->setSectorSdgTarget($value, $index); - } else { - $this->setSectorText($value, $index); - } + match ($sectorVocabulary) { + '1' => $this->handleSectorVocabularyOne($value, $index), + '2' => $this->setSectorCategoryCode($value, $index), + '7' => $this->setSectorSdgGoal($value, $index), + '8' => $this->setSectorSdgTarget($value, $index), + default => $this->setSectorText($value, $index), + }; } } @@ -219,6 +223,33 @@ protected function setVocabularyUri($key, $value, $index): void } } + /** + * Handle for sector vocab 1. + * + * @param $value + * @param $index + * + * @return void + * @throws \JsonException + */ + protected function handleSectorVocabularyOne($value, $index): void + { + $value = $value ? trim($value) : $value; + $this->codes[] = $value; + $validSectorCode = $this->loadCodeList('SectorCode'); + + if ($value) { + foreach ($validSectorCode as $code => $name) { + if (strcasecmp($value, $name) === 0) { + $value = (string) $code; + break; + } + } + } + + $this->data['sector'][$index]['code'] = $value; + } + /** * Set sector category code for Sector. * @@ -301,7 +332,7 @@ protected function setSectorSdgTarget($value, $index): void */ protected function setSectorText($value, $index): void { - ($value) ?: $value = ''; + $value = $value ?: ''; $this->codes[] = $value; $this->data['sector'][$index]['text'] = $value; } diff --git a/app/CsvImporter/Entities/Activity/Components/Elements/Tag.php b/app/CsvImporter/Entities/Activity/Components/Elements/Tag.php index ddeae156a1..c6fd380c74 100644 --- a/app/CsvImporter/Entities/Activity/Components/Elements/Tag.php +++ b/app/CsvImporter/Entities/Activity/Components/Elements/Tag.php @@ -136,44 +136,63 @@ protected function setTagVocabulary($key, $value, $index): void */ protected function setTagCode($key, $value, $index): void { - if (!isset($this->data['tag'][$index]['tag_text'])) { - $this->data['tag'][$index]['tag_text'] = ''; - } - if ($key === $this->_csvHeaders[1]) { + if (!isset($this->data['tag'][$index]['tag_text'])) { + $this->data['tag'][$index]['tag_text'] = ''; + } + $tagVocabulary = $this->data['tag'][$index]['tag_vocabulary'] ?? ''; $value = (!$value) ? '' : trim((string) $value); - if ($tagVocabulary === '2') { - $validTagCode = $this->loadCodeList('UNSDG-Goals'); + switch ($tagVocabulary) { + case '2': + $validTagCode = $this->loadCodeList('UNSDG-Goals'); - if ($value) { - foreach ($validTagCode as $code => $name) { - if (strcasecmp($value, $name) === 0) { - $value = (string) $code; - break; + if ($value) { + foreach ($validTagCode as $code => $name) { + if (strcasecmp($value, $name) === 0) { + $value = (string) $code; + break; + } } } - } - $this->data['tag'][$index]['goals_tag_code'] = $value; - } elseif ($tagVocabulary === '3') { - $validTagCode = $this->loadCodeList('UNSDG-Targets'); + $this->data['tag'][$index]['goals_tag_code'] = $value; + $fields = ['tag_vocabulary', 'goals_tag_code', 'narrative']; + + break; + case '3': + $validTagCode = $this->loadCodeList('UNSDG-Targets'); - if (!is_float($value)) { - foreach ($validTagCode as $code => $name) { - if (strcasecmp($value, $name) === 0) { - $value = is_float($code) ? (float) $code : $code; - break; + if (!is_float($value)) { + foreach ($validTagCode as $code => $name) { + if (strcasecmp($value, $name) === 0) { + $value = is_float($code) ? (float) $code : $code; + break; + } } } - } - $this->data['tag'][$index]['targets_tag_code'] = $value; - } else { - $this->data['tag'][$index]['tag_text'] = $value; - $this->data['tag'][$index]['tag_vocabulary'] = $tagVocabulary; + $this->data['tag'][$index]['targets_tag_code'] = $value; + $fields = ['tag_vocabulary', 'targets_tag_code', 'narrative']; + + break; + case '1': + case '4': + $this->data['tag'][$index]['tag_text'] = $value; + $this->data['tag'][$index]['tag_vocabulary'] = $tagVocabulary; + $fields = ['tag_vocabulary', 'tag_text', 'narrative']; + + break; + default: + $this->data['tag'][$index]['tag_text'] = $value; + $this->data['tag'][$index]['tag_vocabulary'] = $tagVocabulary; + $fields = ['tag_vocabulary', 'tag_text', 'narrative', 'vocabulary_uri']; + + break; } + + $this->data['tag'][$index] = Arr::only($this->data['tag'][$index], $fields); } } diff --git a/app/Helpers/general.php b/app/Helpers/general.php index 5d080515db..3e0bd44f74 100644 --- a/app/Helpers/general.php +++ b/app/Helpers/general.php @@ -1549,3 +1549,49 @@ function regroupResponseForAllActivity(array $response, array $uniqueIdentifiers return $groupedResponses; } + +/** + * Returns array of activity element names in snake case. + * Making this instead of using $activity->getAttributes() method that laravel has because: + * There were case where I was not getting attributes reliably. + * Need this function when using ElementCompleteService::refreshElementStatus(). + * + * @return string[] + */ +function getActivityAttributes(): array +{ + return [ + 'iati_identifier', + 'other_identifier', + 'title', + 'description', + 'activity_status', + 'activity_date', + 'contact_info', + 'activity_scope', + 'participating_org', + 'recipient_country', + 'recipient_region', + 'location', + 'sector', + 'country_budget_items', + 'humanitarian_scope', + 'policy_marker', + 'collaboration_type', + 'default_flow_type', + 'default_finance_type', + 'default_aid_type', + 'default_tied_status', + 'budget', + 'planned_disbursement', + 'capital_spend', + 'document_link', + 'related_activity', + 'legacy_data', + 'conditions', + 'tag', + 'reporting_org', + 'transactions', + 'result', + ]; +} diff --git a/app/Http/Controllers/Admin/Activity/ActivityController.php b/app/Http/Controllers/Admin/Activity/ActivityController.php index ebcf9b8ec4..ca98d47031 100644 --- a/app/Http/Controllers/Admin/Activity/ActivityController.php +++ b/app/Http/Controllers/Admin/Activity/ActivityController.php @@ -121,7 +121,7 @@ public function index(): View|JsonResponse $settingsDefaultValue = $this->settingService->getSetting()->default_values ?? []; $defaultLanguage = getDefaultValue($settingsDefaultValue, 'language', 'Activity/Language.json' ?? []); - // User onboarding part + /** User onboarding part */ $organization = Auth::user()->organization; $organizationOnboarding = $this->organizationOnboardingService->getOrganizationOnboarding($organization->id); $isFirstTime = false; @@ -203,7 +203,7 @@ public function store(ActivityCreateRequest $request): JsonResponse 'data' => $activity, ]); } catch (Exception $e) { - logger()->error($e->getMessage()); + logger()->error($e); return response()->json(['success' => false, 'message' => 'Error has occurred while saving activity.', 'data' => []]); } diff --git a/app/Http/Controllers/Admin/Activity/TransactionController.php b/app/Http/Controllers/Admin/Activity/TransactionController.php index 959c4ca7fe..c568b6144c 100644 --- a/app/Http/Controllers/Admin/Activity/TransactionController.php +++ b/app/Http/Controllers/Admin/Activity/TransactionController.php @@ -345,6 +345,7 @@ public function destroy($id, $transactionId): JsonResponse try { $this->transactionService->deleteTransaction($transactionId); + $activity = $this->activityService->getActivity($id); Session::flash('success', 'Transaction Deleted Successfully'); return response()->json([ diff --git a/app/Http/Requests/Activity/RecipientCountry/RecipientCountryRequest.php b/app/Http/Requests/Activity/RecipientCountry/RecipientCountryRequest.php index 6532ea0a48..dd9173eeeb 100644 --- a/app/Http/Requests/Activity/RecipientCountry/RecipientCountryRequest.php +++ b/app/Http/Requests/Activity/RecipientCountry/RecipientCountryRequest.php @@ -223,6 +223,10 @@ public function getGroupedCountryCode($formFields): array return []; } + $column = array_map(function ($item) { + return $item ?? ''; + }, $column); + $counted = !empty($column) ? array_count_values($column) : []; $duplicates = array_filter($counted, static function ($value) { return $value > 1; diff --git a/app/IATI/Data/elementJsonSchema.json b/app/IATI/Data/elementJsonSchema.json index 8e5399cc64..8abd6b45da 100644 --- a/app/IATI/Data/elementJsonSchema.json +++ b/app/IATI/Data/elementJsonSchema.json @@ -781,8 +781,8 @@ "type": "select", "placeholder": "Select vocabulary", "choices": "Activity/TagVocabulary.json", - "required": false, - "criteria": "", + "required": true, + "criteria": "mandatory", "hover_text": "Select the vocabulary or taxonomy used for tag classifications. You may choose to tag your activity according to an internal category list by choosing \u201899 - Reporting Organisation\u2019.", "help_text": "" }, @@ -1002,7 +1002,7 @@ "placeholder": "Select language", "choices": "Activity/Language.json", "required": false, - "criteria": "recommended", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -1263,7 +1263,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "attr": { "row": 4 @@ -1799,8 +1799,8 @@ "type": "select", "placeholder": "Select type", "choices": "Activity/ContactType.json", - "required": false, - "criteria": "", + "required": true, + "criteria": "mandatory", "hover_text": "Select the category that best describes the type of contact information that you are providing.", "help_text": "" } @@ -1823,7 +1823,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "attr": { "row": 4 @@ -1838,7 +1838,7 @@ "placeholder": "Select language", "choices": "Activity/Language.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -1864,7 +1864,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "attr": { "row": 4 @@ -1879,7 +1879,7 @@ "placeholder": "Select language", "choices": "Activity/Language.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -1946,7 +1946,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "attr": { "row": 4 @@ -1961,7 +1961,7 @@ "placeholder": "Select language", "choices": "Activity/Language.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -2057,7 +2057,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "attr": { "row": 4 @@ -2072,7 +2072,7 @@ "placeholder": "Select language", "choices": "Activity/Language.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -2124,7 +2124,7 @@ "placeholder": "Select code", "choices": "Activity/GeographicLocationReach.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" } @@ -2150,7 +2150,7 @@ "placeholder": "Select vocabulary", "choices": "Activity/GeographicVocabulary.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "Select a recognised gazetteer or administrative boundary repository from the drop-down list.", "help_text": "" }, @@ -2160,7 +2160,7 @@ "type": "text", "placeholder": "Enter a code", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "Provide a location code which corresponds to the vocabulary that you have selected.", "help_text": "" } @@ -2184,7 +2184,7 @@ "type": "textarea", "placeholder": "Type narrative here", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "attr": { "row": 4 @@ -2199,7 +2199,7 @@ "placeholder": "Select language", "choices": "Activity/Language.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -2224,7 +2224,7 @@ "type": "textarea", "placeholder": "Type narrative here", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "attr": { "row": 4 @@ -2239,7 +2239,7 @@ "placeholder": "Select language", "choices": "Activity/Language.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -2265,7 +2265,7 @@ "type": "textarea", "placeholder": "Type narrative here", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "attr": { "row": 4 @@ -2280,7 +2280,7 @@ "placeholder": "Select language", "choices": "Activity/Language.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -2307,7 +2307,7 @@ "placeholder": "Select vocabulary", "choices": "Activity/GeographicVocabulary.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "Select an administrative boundary list to use for your activity location.", "help_text": "" }, @@ -2318,7 +2318,7 @@ "placeholder": "Select code", "choices": "Activity/Country.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "Provide a code from your chosen administrative boundary list.", "help_text": "" }, @@ -2352,7 +2352,7 @@ "type": "text", "placeholder": "Type srs name", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "The name of the spatial reference system used by the coordinates.", "help_text": "" } @@ -2370,7 +2370,7 @@ "type": "text", "placeholder": "Type latitude value", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" }, @@ -2380,7 +2380,7 @@ "type": "text", "placeholder": "Type longitude value", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" } @@ -2406,7 +2406,7 @@ "placeholder": "Select code", "choices": "Activity/GeographicExactness.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "If you have provided the geo-coordinates for the activity location, then select an option from the Geographic Exactness list to specify whether the location is exact or approximate.", "help_text": "" } @@ -2430,7 +2430,7 @@ "placeholder": "Select code", "choices": "Activity/GeographicLocationClass.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" } @@ -2454,7 +2454,7 @@ "placeholder": "Select code", "choices": "Activity/LocationType.json", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "You can provide more detail on the type of activity location (e.g. beach, well or college).

Click here for more information on location types", "help_text": "" } @@ -2525,7 +2525,7 @@ "type": "date", "placeholder": "YYYY-MM-DD", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" } @@ -5602,4 +5602,4 @@ } } } -} \ No newline at end of file +} diff --git a/app/IATI/Data/organizationElementJsonSchema.json b/app/IATI/Data/organizationElementJsonSchema.json index ab9add8854..7597e94a77 100644 --- a/app/IATI/Data/organizationElementJsonSchema.json +++ b/app/IATI/Data/organizationElementJsonSchema.json @@ -325,7 +325,7 @@ "type": "text", "placeholder": "Type value here", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" }, @@ -336,7 +336,7 @@ "multiselect": false, "choices": "Activity/Currency.json", "required": true, - "criteria": "mandatory", + "criteria": "", "placeholder": "Select currency", "hover_text": "", "help_text": "If no currency is selected, your default currency is assumed." @@ -347,7 +347,7 @@ "type": "date", "placeholder": "YYYY-MM-DD", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "The date used to determine the exchange rate for currency conversions.", "help_text": "" } @@ -360,7 +360,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "form_has_borders": true, "label_has_borders": true, @@ -378,7 +378,7 @@ "choices": "Activity/Language.json", "placeholder": "Select language", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -601,7 +601,7 @@ "type": "text", "placeholder": "Type value here", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" }, @@ -613,7 +613,7 @@ "choices": "Activity/Currency.json", "placeholder": "Select currency", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no currency is selected, your default currency is assumed." }, @@ -623,7 +623,7 @@ "type": "date", "placeholder": "YYYY-MM-DD", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "The date used to determine the exchange rate for currency conversions.", "help_text": "" } @@ -636,7 +636,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "form_has_borders": true, "label_has_borders": true, @@ -654,7 +654,7 @@ "choices": "Activity/Language.json", "placeholder": "Select language", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -683,8 +683,8 @@ "multiselect": false, "choices": "Activity/BudgetStatus.json", "placeholder": "Select status", - "required": true, - "criteria": "mandatory", + "required": false, + "criteria": "", "hover_text": "Select a status that best describes this budget:

(1) indicative - a non-binding estimate for the described budget.

(2) committed - a binding agreement for the described budget.

If no status is selected, the budget is assumed to be indicative.", "help_text": "" } @@ -698,7 +698,7 @@ "form_has_borders": true, "label_has_borders": true, "is_collapsable": true, - "label_indicator": "optional_text", + "label_indicator": "required_icon", "element_criteria": "mandatory", "hover_text": "The geographic region where funds have been allocated.", "attributes": { @@ -914,7 +914,7 @@ "type": "text", "placeholder": "Type value here", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" }, @@ -926,7 +926,7 @@ "choices": "Activity/Currency.json", "placeholder": "Select currency", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no currency is selected, your default currency is assumed." }, @@ -936,7 +936,7 @@ "type": "date", "placeholder": "YYYY-MM-DD", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "The date used to determine the exchange rate for currency conversions.", "help_text": "" } @@ -949,7 +949,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "hover_text": "Provide a description for this budget line.", "help_text": "", @@ -965,7 +965,7 @@ "choices": "Activity/Language.json", "placeholder": "Select language", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -1192,7 +1192,7 @@ "type": "text", "placeholder": "Type value here", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" }, @@ -1204,7 +1204,7 @@ "choices": "Activity/Currency.json", "placeholder": "Select currency", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no currency is selected, your default currency is assumed." }, @@ -1214,7 +1214,7 @@ "type": "date", "placeholder": "YYYY-MM-DD", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "The date used to determine the exchange rate for currency conversions.", "help_text": "" } @@ -1225,9 +1225,9 @@ "name": "narrative", "label": "narrative", "type": "textarea", - "placeholder": "Select language", + "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "hover_text": "Provide a description for this budget line.", "help_text": "", @@ -1243,7 +1243,7 @@ "choices": "Activity/Language.json", "placeholder": "Select language", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -1399,7 +1399,7 @@ "type": "text", "placeholder": "Type value here", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "" }, @@ -1411,7 +1411,7 @@ "choices": "Activity/Currency.json", "placeholder": "Select currency", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no currency is selected, your default currency is assumed." }, @@ -1421,7 +1421,7 @@ "type": "date", "placeholder": "YYYY-MM-DD", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "The date used to determine the exchange rate for currency conversions.", "help_text": "" } @@ -1434,7 +1434,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "hover_text": "Provide a description for this expense line.", "help_text": "", @@ -1450,7 +1450,7 @@ "choices": "Activity/Language.json", "placeholder": "Select language", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -1679,7 +1679,7 @@ "choices": "Activity/Country.json", "placeholder": "Select code", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "Select the recipient country that is the focus for this document or webpage.", "help_text": "" } @@ -1691,7 +1691,7 @@ "type": "textarea", "placeholder": "Type narrative", "required": true, - "criteria": "mandatory", + "criteria": "", "add_more": true, "attr": { "row": 4 @@ -1707,7 +1707,7 @@ "choices": "Activity/Language.json", "placeholder": "Select language", "required": true, - "criteria": "mandatory", + "criteria": "", "hover_text": "", "help_text": "If no language is selected, your default language is assumed." } @@ -1718,4 +1718,4 @@ } } } -} \ No newline at end of file +} diff --git a/app/IATI/Services/Activity/ActivityService.php b/app/IATI/Services/Activity/ActivityService.php index e8a7a18080..5d449ed7fd 100644 --- a/app/IATI/Services/Activity/ActivityService.php +++ b/app/IATI/Services/Activity/ActivityService.php @@ -85,17 +85,14 @@ public function getPaginatedActivities(int $page, array $queryParams): Collectio $page ); + $orgReportingOrgStatus = Arr::get(\auth()->user()->organization, 'element_status.reporting_org', false); + foreach ($activities as $idx => $activity) { $activities[$idx]['default_title_narrative'] = $activity->default_title_narrative; - $activity->setAttribute( - 'coreCompleted', - isCoreElementCompleted( - array_merge( - ['reporting_org' => $activity->organization->reporting_org_element_completed], - $activity->element_status - ) - ) - ); + $elementStatus = $activity->element_status; + $elementStatus['reporting_org'] = $orgReportingOrgStatus; + + $activity->setAttribute('coreCompleted', isCoreElementCompleted($elementStatus)); } return $activities; @@ -171,18 +168,18 @@ public function store($input): Model } return $this->activityRepository->store([ - 'iati_identifier' => $activity_identifier, - 'title' => $activity_title, - 'collaboration_type' => isset($defaultValues['default_collaboration_type']) && !empty($defaultValues['default_collaboration_type']) ? (int) $defaultValues['default_collaboration_type'] : null, - 'default_flow_type' => isset($defaultValues['default_flow_type']) && !empty($defaultValues['default_flow_type']) ? (int) $defaultValues['default_flow_type'] : null, - 'default_finance_type' => isset($defaultValues['default_finance_type']) && !empty($defaultValues['default_finance_type']) ? (int) $defaultValues['default_finance_type'] : null, - 'default_aid_type' => $defaultAidType, - 'default_tied_status' => isset($defaultValues['default_tied_status']) && !empty($defaultValues['default_tied_status']) ? (int) $defaultValues['default_tied_status'] : null, - 'org_id' => $authUser->organization_id, - 'element_status' => $defaultElementStatus, + 'iati_identifier' => $activity_identifier, + 'title' => $activity_title, + 'collaboration_type' => (int) Arr::get($defaultValues, 'default_collaboration_type') ?: null, + 'default_flow_type' => (int) Arr::get($defaultValues, 'default_flow_type') ?: null, + 'default_finance_type' => (int) Arr::get($defaultValues, 'default_finance_type') ?: null, + 'default_aid_type' => $defaultAidType, + 'default_tied_status' => (int) Arr::get($defaultValues, 'default_tied_status') ?: null, + 'org_id' => $authUser->organization_id, + 'element_status' => $defaultElementStatus, 'default_field_values' => $this->getDefaultValues(), - 'reporting_org' => $authUser->organization->reporting_org, - 'other_identifier' => $activityOtherIdentifiers, + 'reporting_org' => $authUser->organization->reporting_org, + 'other_identifier' => $activityOtherIdentifiers, ]); } diff --git a/app/IATI/Services/Activity/CountryBudgetItemService.php b/app/IATI/Services/Activity/CountryBudgetItemService.php index 154a879edc..a68a500fc6 100644 --- a/app/IATI/Services/Activity/CountryBudgetItemService.php +++ b/app/IATI/Services/Activity/CountryBudgetItemService.php @@ -153,7 +153,7 @@ private function buildBudgetItem($budgetItems): array 'code', null ), - 'percentage' => Arr::get($budgetItem, 'percentage', null), + 'percentage' => Arr::get($budgetItem, 'percentage') ?? 100, ], 'description' => [ 'narrative' => $this->buildNarrative( diff --git a/app/IATI/Services/Activity/PolicyMarkerService.php b/app/IATI/Services/Activity/PolicyMarkerService.php index 28875090a8..e5cb3049e2 100644 --- a/app/IATI/Services/Activity/PolicyMarkerService.php +++ b/app/IATI/Services/Activity/PolicyMarkerService.php @@ -121,11 +121,11 @@ public function getXmlData(Activity $activity): array $vocabulary = Arr::get($policyMarker, 'policy_marker_vocabulary', null); switch ($vocabulary) { - case '99': - $code = Arr::get($policyMarker, 'policy_marker_text', null); + case '1': + $code = Arr::get($policyMarker, 'policy_marker', null); break; default: - $code = Arr::get($policyMarker, 'policy_marker', null); + $code = Arr::get($policyMarker, 'policy_marker_text', null); break; } diff --git a/app/IATI/Services/Download/DownloadActivityService.php b/app/IATI/Services/Download/DownloadActivityService.php index a38643cc5b..e594a6f39d 100644 --- a/app/IATI/Services/Download/DownloadActivityService.php +++ b/app/IATI/Services/Download/DownloadActivityService.php @@ -17,17 +17,10 @@ */ class DownloadActivityService { - use ChecksCsvHeaders, DownloadActivitySimpleElementTrait, DownloadActivityComplexElementTrait, DownloadTransactionTrait; - - /** - * @var ActivityRepository - */ - protected ActivityRepository $activityRepository; - - /** - * @var XmlGenerator - */ - protected XmlGenerator $xmlGenerator; + use ChecksCsvHeaders; + use DownloadActivityComplexElementTrait; + use DownloadActivitySimpleElementTrait; + use DownloadTransactionTrait; /** * @var array @@ -67,11 +60,9 @@ class DownloadActivityService * @param XmlGenerator $xmlGenerator */ public function __construct( - ActivityRepository $activityRepository, - XmlGenerator $xmlGenerator + protected ActivityRepository $activityRepository, + protected XmlGenerator $xmlGenerator ) { - $this->activityRepository = $activityRepository; - $this->xmlGenerator = $xmlGenerator; } /** @@ -193,6 +184,11 @@ public function getNarrativeText($narratives, $language): ?string /** * Returns activity description narrative for particular description type. * + * UNDERSTANDING THE : || $type === '1' + * That is to handle data where description narrative is present but no type is specified. + * That type of description will be default-ed to type 1 in the downloaded file. + * + * * @param $descriptions * @param $language * @param $type @@ -203,7 +199,7 @@ public function getDescriptionText($descriptions, $language, $type): ?string { if (!empty($descriptions) && is_array($descriptions) && count($descriptions)) { foreach ($descriptions as $description) { - if (Arr::get($description, 'type', $type) === $type) { + if (Arr::get($description, 'type', $type) === $type || $type === '1') { return (string) $this->getNarrativeText(Arr::get($description, 'narrative', []), $language); } } @@ -290,11 +286,11 @@ public function getSectorCodeFromVocabulary($sectorVocabulary, $sector): ?string */ public function getPolicyMarkerCodeFromVocabulary($policyMarkerVocabulary, $policyMarker): ?string { - if (!empty($policyMarkerVocabulary) && $policyMarkerVocabulary !== '1') { - return (string) Arr::get($policyMarker, 'policy_marker_text', ''); + if ($policyMarkerVocabulary === '1') { + return (string) Arr::get($policyMarker, 'policy_marker', ''); } - return (string) Arr::get($policyMarker, 'policy_marker', ''); + return Arr::get($policyMarker, 'policy_marker_text', ''); } /** @@ -453,4 +449,23 @@ public function getAllActivitiesQueryToDownload($queryParams, $authUser): object { return $this->activityRepository->getAllActivitiesQueryToDownload($authUser['organization_id'], $queryParams); } + + /** + * Returns the first narrative text of the first description that matches given description type. + * + * @param array $descriptions + * @param string $type + * + * @return string + */ + public function getFirstDescriptionTextThatMatchesType(array $descriptions, string $type = '1'): string + { + foreach ($descriptions as $description) { + if ($description['type'] === $type) { + return Arr::get($description, 'narrative.0.narrative') ?? ''; + } + } + + return ''; + } } diff --git a/app/IATI/Services/ElementCompleteService.php b/app/IATI/Services/ElementCompleteService.php index 1a08cd46ca..5e40cf84e5 100644 --- a/app/IATI/Services/ElementCompleteService.php +++ b/app/IATI/Services/ElementCompleteService.php @@ -5,12 +5,16 @@ namespace App\IATI\Services; use App\Constants\CoreElements; +use App\IATI\Models\Activity\Activity; use App\IATI\Services\Activity\RecipientRegionService; use App\IATI\Traits\ElementCompleteServiceTrait; use App\IATI\Traits\ElementDeprecationService; use Illuminate\Contracts\Container\BindingResolutionException; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\Arr; use JsonException; +use ReflectionMethod; /** * Class ElementCompleteService. @@ -210,7 +214,10 @@ public function isTitleElementCompleted($activity): bool $this->element = 'title'; $elementSchema = getElementSchema($this->element); - return $this->isSubElementDataCompleted($this->mandatorySubElements($elementSchema['sub_elements']), ['narrative' => $activity->title]); + return $this->isSubElementDataCompleted( + $this->mandatorySubElements($elementSchema['sub_elements']), + ['narrative' => $activity->title] + ); } /** @@ -356,7 +363,67 @@ public function isSectorElementCompleted($activity): bool { $this->element = 'sector'; - return $this->isLevelOneMultiDimensionElementCompleted($activity->sector); + if ($this->activityHasTransactionSector($activity) && $this->isSectorElementCompletedInTransaction($activity)) { + return true; + } + + if ((!$activity->sector) || (is_variable_null($activity->sector)) || (is_array_value_empty($activity->sector))) { + return false; + } + + $shouldConsiderPercentage = count(Arr::get($activity, 'sector', [])) > 1; + + foreach ($activity->sector as $sector) { + $sectorVocab = Arr::get($sector, 'sector_vocabulary') ?? null; + $codeKey = $this->getSectorCodeKeyBasedOnVocab((string) $sectorVocab); + + if ($this->isEmptyValue(Arr::get($sector, $codeKey))) { + return false; + } + + if ($shouldConsiderPercentage && $this->isEmptyValue(Arr::get($sector, 'percentage'))) { + return false; + } + } + + return true; + } + + public function isSectorElementCompletedInTransaction(Activity $activity): bool + { + $transactions = $activity->transactions; + + foreach ($transactions as $transaction) { + foreach (Arr::get($transaction, 'transaction.sector', []) as $sector) { + if (!is_array_value_empty($sector)) { + $sectorVocab = Arr::get($sector, 'sector_vocabulary') ?? null; + $codeKey = $this->getSectorCodeKeyBasedOnVocab((string) $sectorVocab); + + if ($this->isEmptyValue(Arr::get($sector, $codeKey))) { + return false; + } + } + } + } + + return true; + } + + public function activityHasTransactionSector(Activity $activity): bool + { + $transactions = $activity->transactions; + + if (!empty($transactions)) { + foreach ($transactions as $transaction) { + $transactionSector = Arr::get($transaction, 'transaction.sector', []); + + if (!is_array_value_empty($transactionSector)) { + return true; + } + } + } + + return false; } /** @@ -420,7 +487,21 @@ public function isPolicyMarkerElementCompleted($activity): bool { $this->element = 'policy_marker'; - return $this->isLevelOneMultiDimensionElementCompleted($activity->policy_marker); + if (!$activity->policy_marker) { + return false; + } + + foreach ($activity->policy_marker as $policyMarker) { + $isIncomplete = $this->policyMarkerVocabIsCustom($policyMarker) + ? $this->customPolicyMarkerIsIncomplete($policyMarker) + : $this->policyMarkerIsIncomplete($policyMarker); + + if ($isIncomplete) { + return false; + } + } + + return true; } /** @@ -443,7 +524,7 @@ public function isParticipatingOrgElementCompleted($activity): bool $participatingOrgData = $activity->participating_org; - if (is_variable_null($participatingOrgData)) { + if (is_variable_null($participatingOrgData) || is_array_value_empty($participatingOrgData)) { return false; } @@ -635,7 +716,21 @@ public function isContactInfoElementCompleted($activity): bool { $this->element = 'contact_info'; - return $this->isLevelTwoMultiDimensionElementCompleted($activity->contact_info); + if (!$activity->contact_info) { + return false; + } + + foreach ($activity->contact_info as $contactInfo) { + $contactInfoTypeIsEmpty = empty(Arr::get($contactInfo, 'type')); + $allOtherFields = Arr::except($contactInfo, 'type'); + $allOtherFieldsAreEmpty = is_variable_null($allOtherFields) || is_array_value_empty($allOtherFields); + + if ($contactInfoTypeIsEmpty || $allOtherFieldsAreEmpty) { + return false; + } + } + + return true; } /** @@ -651,7 +746,17 @@ public function isLocationElementCompleted($activity): bool { $this->element = 'location'; - return !is_variable_null($activity->location); + if (!$activity->location) { + return false; + } + + foreach ($activity->location as $location) { + if (is_variable_null($location) || is_array_value_empty($location)) { + return false; + } + } + + return true; } /** @@ -702,7 +807,10 @@ public function isPeriodElementCompleted($data): bool foreach ($data as $datum) { foreach (['period_start', 'period_end'] as $item) { - if (!$this->isLevelOneMultiDimensionDataCompleted($elementSchema['sub_elements'][$item], getArr($datum, $item))) { + if (!$this->isLevelOneMultiDimensionDataCompleted( + $elementSchema['sub_elements'][$item], + getArr($datum, $item) + )) { return false; } } @@ -736,8 +844,14 @@ public function isBaselineCompleted($data, $subElement): bool { foreach ($data as $baselineDatum) { if ( - !$this->isLevelOneMultiDimensionDataCompleted($subElement['sub_elements']['comment'], getArr($baselineDatum, 'comment')) - || !$this->isLevelTwoMultiDimensionDataCompleted($subElement['sub_elements']['document_link'], getArr($baselineDatum, 'document_link')) + !$this->isLevelOneMultiDimensionDataCompleted( + $subElement['sub_elements']['comment'], + getArr($baselineDatum, 'comment') + ) + || !$this->isLevelTwoMultiDimensionDataCompleted( + $subElement['sub_elements']['document_link'], + getArr($baselineDatum, 'document_link') + ) ) { return false; } @@ -760,13 +874,19 @@ public function isResultAndIndicatorElementCompleted($elementSchema, $data): boo { if ( !$this->isSingleDimensionAttributeCompleted($elementSchema, $data) - || !$this->isLevelTwoMultiDimensionDataCompleted($elementSchema['sub_elements']['document_link'], getArr($data, 'document_link')) + || !$this->isLevelTwoMultiDimensionDataCompleted( + $elementSchema['sub_elements']['document_link'], + getArr($data, 'document_link') + ) ) { return false; } foreach (['title', 'description', 'reference'] as $item) { - if (!$this->isLevelOneMultiDimensionDataCompleted($elementSchema['sub_elements'][$item], getArr($data, $item))) { + if (!$this->isLevelOneMultiDimensionDataCompleted( + $elementSchema['sub_elements'][$item], + getArr($data, $item) + )) { return false; } } @@ -901,11 +1021,15 @@ public function isResultElementCompleted($activity): bool $indicatorExists = is_array($indicatorData) && count($indicatorData) > 0; if ($periodExists) { - return $this->isPeriodElementCompleted($periodData) && $this->isIndicatorElementCompleted($indicatorData) && $this->isResultElementDataCompleted($resultData); + return $this->isPeriodElementCompleted($periodData) && $this->isIndicatorElementCompleted( + $indicatorData + ) && $this->isResultElementDataCompleted($resultData); } if ($indicatorExists) { - return $this->isIndicatorElementCompleted($indicatorData) && $this->isResultElementDataCompleted($resultData); + return $this->isIndicatorElementCompleted($indicatorData) && $this->isResultElementDataCompleted( + $resultData + ); } return false; @@ -973,6 +1097,14 @@ public function isTransactionsElementCompleted($activity): bool */ public function checkIfRecipientRegionElementCompleted($activity): bool { + if ($this->recipientRegionIsSetInTransaction($activity)) { + return $this->isRecipientRegionCompleteInTransaction($activity); + } + + if ($this->recipientCountryIsSetInTransaction($activity)) { + return $this->isRecipientCompleteCompleteInTransaction($activity); + } + $regionStatus = $this->isLevelOneMultiDimensionElementCompleted($activity->recipient_region); if (empty($activity->recipient_region) && !empty($activity->recipient_country)) { @@ -998,7 +1130,7 @@ public function checkIfRecipientRegionElementCompleted($activity): bool * Comparing with ( 100 - % of RecipientCountry ) is the same as comparing with 100.0 if Recipient Country is empty. */ if (empty($activity->recipient_country) && $firstGroupTotalPercentage !== 100.0) { - return false; + return false; } if (!empty($activity->recipient_country)) { @@ -1024,6 +1156,14 @@ public function checkIfRecipientRegionElementCompleted($activity): bool */ public function checkIfRecipientCountryElementCompleted($activity): bool { + if ($this->recipientRegionIsSetInTransaction($activity)) { + return $this->isRecipientRegionCompleteInTransaction($activity); + } + + if ($this->recipientCountryIsSetInTransaction($activity)) { + return $this->isRecipientCompleteCompleteInTransaction($activity); + } + $countryStatus = $this->isLevelOneMultiDimensionElementCompleted($activity->recipient_country); if (empty($activity->recipient_country) && !empty($activity->recipient_region)) { @@ -1034,7 +1174,7 @@ public function checkIfRecipientCountryElementCompleted($activity): bool })['total']; if ($firstGroupTotalPercentage === 100.0) { - return $countryStatus; + return true; } return false; @@ -1062,43 +1202,60 @@ public function checkIfRecipientCountryElementCompleted($activity): bool * * @return void * - * @throws BindingResolutionException + * @throws JsonException + * @throws \ReflectionException */ public function refreshElementStatus($activity): void { - $skippables = [ - 'id', - 'org_id', - 'status', - 'created_at', - 'updated_at', - 'created_by', - 'updated_by', - 'upload_medium', - 'linked_to_iati', - 'element_status', - 'default_field_values', - 'migrated_from_aidstream', - 'complete_percentage', - ]; - $elementStatus = []; - $attributes = $activity->getAttributes(); + $attributes = getActivityAttributes(); - foreach ($attributes as $attribute => $value) { - $attributeMethod = dashesToCamelCase('is_' . $attribute . '_element_completed'); + foreach ($attributes as $attribute) { + $methodName = dashesToCamelCase('is_' . $attribute . '_element_completed'); - if (!in_array($attribute, $skippables) && is_callable([$this, $attributeMethod])) { - $elementStatus[$attribute] = call_user_func([$this, $attributeMethod], $activity); + if (is_callable([$this, $methodName])) { + if ($attribute === 'reporting_org') { + $elementStatus[$attribute] = Arr::get(auth()->user()->organization, 'element_status.reporting_org', false); + } else { + $elementStatus[$attribute] = call_user_func([$this, $methodName], $activity); + } } } $activity->element_status = $elementStatus; $activity->complete_percentage = $this->calculateCompletePercentage($activity->element_status); $activity->timestamps = false; + $activity->updateQuietly(['touch' => false]); } + /** + * Returns an array of relation names loaded in the model. + * + * @param Model $model + * + * @return array + * @throws \ReflectionException + */ + public function getRelationNames(Model $model): array + { + $relations = []; + + foreach (get_class_methods($model) as $method) { + $reflection = new ReflectionMethod($model, $method); + + if ($reflection->isPublic() && !$reflection->isStatic() && $reflection->getNumberOfParameters() === 0) { + $returnType = $reflection->getReturnType(); + + if ($returnType && is_subclass_of($returnType->getName(), Relation::class)) { + $relations[] = $method; + } + } + } + + return $relations; + } + /** * Calculate element complete percentage for an activity. * @@ -1145,12 +1302,12 @@ public function refreshDeprecationStatusMap($activity): void 'complete_percentage', ]; $deprecationMap = []; - $attributes = $activity->getAttributes(); + $attributes = getActivityAttributes(); - foreach ($attributes as $attribute => $value) { + foreach ($attributes as $attribute) { $attributeMethod = dashesToCamelCase('does_' . $attribute . '_have_deprecated_code'); - if (!in_array($attribute, $skippables) && is_callable([$this, $attributeMethod])) { + if (is_callable([$this, $attributeMethod])) { $deprecationMap[$attribute] = call_user_func([$this, $attributeMethod], $activity); } } @@ -1160,8 +1317,113 @@ public function refreshDeprecationStatusMap($activity): void $activity->updateQuietly(['touch' => false]); } + /** + * @param $value + * + * @return bool + */ public function isEmptyValue($value): bool { - return trim($value ?? '') === ''; + return $value === null || (is_string($value) && trim($value) === ''); + } + + /** + * @param $policy_marker + * + * @return bool + */ + private function policyMarkerVocabIsCustom($policy_marker): bool + { + return Arr::get($policy_marker, 'policy_marker_vocabulary') !== '1'; + } + + /** + * @param $policyMarker + * + * @return bool + */ + private function customPolicyMarkerIsIncomplete($policyMarker): bool + { + return $this->isEmptyValue(Arr::get($policyMarker, 'policy_marker_text')); + } + + /** + * @param $policyMarker + * + * @return bool + */ + private function policyMarkerIsIncomplete($policyMarker): bool + { + return $this->isEmptyValue(Arr::get($policyMarker, 'policy_marker')); + } + + private function getSectorCodeKeyBasedOnVocab(?string $sectorVocab): string + { + return match ($sectorVocab) { + '1' => 'code', + '2' => 'category_code', + '7' => 'sdg_goal', + '8' => 'sdg_target', + default => 'text', + }; + } + + private function recipientCountryIsSetInTransaction($activity): bool + { + $transactions = $activity->transactions; + + foreach ($transactions as $transaction) { + if (!is_array_value_empty(Arr::get($transaction, 'transaction.recipient_country', []))) { + return true; + } + } + + return false; + } + + private function recipientRegionIsSetInTransaction($activity): bool + { + $transactions = $activity->transactions; + + foreach ($transactions as $transaction) { + if (!is_array_value_empty(Arr::get($transaction, 'transaction.recipient_region', []))) { + return true; + } + } + + return false; + } + + public function isRecipientRegionCompleteInTransaction($activity): bool + { + $transactions = $activity->transactions; + + foreach ($transactions as $transaction) { + $recipientRegion = Arr::get($transaction, 'transaction.recipient_region.0', []); + + if (isset($recipientRegion['region_code']) && empty($recipientRegion['region_code'])) { + return false; + } elseif (isset($recipientRegion['custom_code']) && empty($recipientRegion['custom_code'])) { + return false; + } + } + + return true; + } + + public function isRecipientCompleteCompleteInTransaction($activity): bool + { + $transactions = $activity->transactions; + + foreach ($transactions as $transaction) { + $recipientCountry = Arr::get($transaction, 'transaction.recipient_country.0', []); + $countryCode = Arr::get($recipientCountry, 'country_code'); + + if (empty($countryCode)) { + return false; + } + } + + return true; } } diff --git a/app/IATI/Services/ImportActivity/ImportCsvService.php b/app/IATI/Services/ImportActivity/ImportCsvService.php index 89f28d8a88..f6733cbafe 100644 --- a/app/IATI/Services/ImportActivity/ImportCsvService.php +++ b/app/IATI/Services/ImportActivity/ImportCsvService.php @@ -10,6 +10,7 @@ use App\IATI\Repositories\Activity\TransactionRepository; use App\IATI\Repositories\Import\ImportActivityErrorRepository; use App\IATI\Repositories\Organization\OrganizationRepository; +use App\IATI\Services\ElementCompleteService; use App\IATI\Traits\FillDefaultValuesTrait; use App\Imports\CsvToArray; use Exception; @@ -98,6 +99,11 @@ class ImportCsvService */ protected Filesystem $filesystem; + /** + * @var ElementCompleteService + */ + private ElementCompleteService $elementCompleteService; + /** * ImportManager constructor. * @@ -120,7 +126,8 @@ public function __construct( OrganizationRepository $organizationRepo, TransactionRepository $transactionRepo, ImportActivityErrorRepository $importActivityErrorRepo, - Filesystem $filesystem + Filesystem $filesystem, + ElementCompleteService $elementCompleteService ) { $this->excel = $excel; $this->processor = $processor; @@ -131,6 +138,7 @@ public function __construct( $this->transactionRepo = $transactionRepo; $this->importActivityErrorRepo = $importActivityErrorRepo; $this->filesystem = $filesystem; + $this->elementCompleteService = $elementCompleteService; $this->csv_data_storage_path = env('CSV_DATA_STORAGE_PATH', 'CsvImporter/tmp'); $this->csv_file_storage_path = env('CSV_FILE_STORAGE_PATH', 'CsvImporter/file'); } @@ -189,6 +197,7 @@ public function localStorageFile($file, $filename): File * * @throws BindingResolutionException * @throws \JsonException + * @throws \ReflectionException */ public function create($activities): void { @@ -228,6 +237,10 @@ public function create($activities): void } else { $this->importActivityErrorRepo->deleteImportError($oldActivity->id); } + + $this->elementCompleteService->refreshElementStatus( + $this->activityRepo->getActivitityWithRelationsById($oldActivity->id) + ); } else { $createdActivity = $this->activityRepo->createActivity(Arr::get($activity, 'data')); @@ -238,6 +251,10 @@ public function create($activities): void if (!empty($activity['errors'])) { $this->importActivityErrorRepo->updateOrCreateError($createdActivity->id, $activity['errors']); } + + $this->elementCompleteService->refreshElementStatus( + $this->activityRepo->getActivitityWithRelationsById($createdActivity->id) + ); } } } diff --git a/app/IATI/Services/ImportActivity/ImportXlsService.php b/app/IATI/Services/ImportActivity/ImportXlsService.php index fb8673723c..38c8348b2c 100644 --- a/app/IATI/Services/ImportActivity/ImportXlsService.php +++ b/app/IATI/Services/ImportActivity/ImportXlsService.php @@ -12,6 +12,7 @@ use App\IATI\Repositories\Import\ImportActivityErrorRepository; use App\IATI\Repositories\Import\ImportStatusRepository; use App\IATI\Services\Activity\ActivityService; +use App\IATI\Services\ElementCompleteService; use App\XlsImporter\Events\XlsWasUploaded; use Exception; use Illuminate\Contracts\Container\BindingResolutionException; @@ -70,6 +71,8 @@ class ImportXlsService */ protected ImportStatusRepository $importStatusRepo; + private ElementCompleteService $elementCompleteService; + /** * XmlImportManager constructor. * @@ -89,7 +92,8 @@ public function __construct( PeriodRepository $periodRepository, IndicatorRepository $indicatorRepository, ImportActivityErrorRepository $importActivityErrorRepo, - ImportStatusRepository $importStatusRepo + ImportStatusRepository $importStatusRepo, + ElementCompleteService $elementCompleteService, ) { $this->transactionRepository = $transactionRepository; $this->activityRepository = $activityRepository; @@ -98,6 +102,7 @@ public function __construct( $this->importActivityErrorRepo = $importActivityErrorRepo; $this->importStatusRepo = $importStatusRepo; $this->periodRepository = $periodRepository; + $this->elementCompleteService = $elementCompleteService; $this->xls_file_storage_path = env('XLS_FILE_STORAGE_PATH', 'XlsImporter/file'); $this->xls_data_storage_path = env('XLS_DATA_STORAGE_PATH', 'XlsImporter/tmp'); } @@ -167,6 +172,8 @@ public function create($activities, $xlsType = 'activity'): bool * @param $activityId * * @return $this + * @throws \JsonException + * @throws \ReflectionException */ protected function saveTransactions($transactions, $activityId): static { @@ -196,6 +203,7 @@ protected function saveTransactions($transactions, $activityId): static * * @throws BindingResolutionException * @throws \JsonException + * @throws \ReflectionException */ protected function saveActivities($activities): void { @@ -204,6 +212,7 @@ protected function saveActivities($activities): void $contents = json_decode(awsGetFile(sprintf('%s/%s/%s/%s', $this->xls_data_storage_path, $organizationId, $userId, 'valid.json')), false, 512, JSON_THROW_ON_ERROR | 0); foreach ($activities as $value) { + $storeActivity = null; $activity = unsetErrorFields($contents[$value]); $activity['data'] = unsetDeprecatedFieldValues(Arr::get($activity, 'data', [])); @@ -227,22 +236,46 @@ protected function saveActivities($activities): void $this->transactionRepository->deleteTransaction($existingId); $this->saveTransactions(Arr::get($activityData, 'transactions', []), $existingId); + $storeActivity = $this->activityRepository->find($existingId); + if (!empty($activity['errors'])) { $this->importActivityErrorRepo->updateOrCreateError($existingId, $activity['errors']); } else { $this->importActivityErrorRepo->deleteImportError($existingId); } } else { - $activityService = app()->make(ActivityService::class); + /** @var $activityService ActivityService */ + $activityService = app(ActivityService::class); $organizationIdentifier = Auth::user()->organization->identifier; $defaultValues = $activityService->getDefaultValues(); $activityData['org_id'] = $organizationId; $activityData['upload_medium'] = 'xls'; - $activityData['collaboration_type'] = isset($defaultValues['default_collaboration_type']) && !empty($defaultValues['default_collaboration_type']) ? (int) $defaultValues['default_collaboration_type'] : null; - $activityData['default_flow_type'] = isset($defaultValues['default_flow_type']) && !empty($defaultValues['default_flow_type']) ? (int) $defaultValues['default_flow_type'] : null; - $activityData['default_finance_type'] = isset($defaultValues['default_finance_type']) && !empty($defaultValues['default_finance_type']) ? (int) $defaultValues['default_finance_type'] : null; - $activityData['default_tied_status'] = isset($defaultValues['default_tied_status']) && !empty($defaultValues['default_tied_status']) ? (int) $defaultValues['default_tied_status'] : null; + + $activityData['collaboration_type'] = $this->getIntOrNullFromActivityDataOrDefaultValues( + activityData : $activityData, + activityDataAccessKey: 'collaboration_type', + defaultValues : $defaultValues, + defaultDataKey : 'default_collaboration_type' + ); + $activityData['flow_type'] = $this->getIntOrNullFromActivityDataOrDefaultValues( + activityData : $activityData, + activityDataAccessKey: 'flow_type', + defaultValues : $defaultValues, + defaultDataKey : 'default_flow_type' + ); + $activityData['finance_type'] = $this->getIntOrNullFromActivityDataOrDefaultValues( + activityData : $activityData, + activityDataAccessKey: 'finance_type', + defaultValues : $defaultValues, + defaultDataKey : 'default_finance_type' + ); + $activityData['tied_status'] = $this->getIntOrNullFromActivityDataOrDefaultValues( + activityData : $activityData, + activityDataAccessKey: 'tied_status', + defaultValues : $defaultValues, + defaultDataKey : 'default_tied_status' + ); $activityData['iati_identifier']['iati_identifier_text'] = $organizationIdentifier . '-' . $activityData['iati_identifier']['activity_identifier']; $activityData['iati_identifier']['present_organization_identifier'] = $organizationIdentifier; @@ -264,9 +297,30 @@ protected function saveActivities($activities): void $this->importActivityErrorRepo->updateOrCreateError($storeActivity->id, $activity['errors']); } } + + $this->elementCompleteService->refreshElementStatus( + $this->activityRepository->getActivitityWithRelationsById($storeActivity->id) + ); } } + public function getIntOrNullFromActivityDataOrDefaultValues( + array $activityData, + string $activityDataAccessKey, + array $defaultValues, + string $defaultDataKey + ): ?int { + $value = Arr::get($activityData, $activityDataAccessKey); + + if (!empty($value)) { + return (int) $value; + } + + $defaultValue = Arr::get($defaultValues, $defaultDataKey); + + return !empty($defaultValue) ? (int) $defaultValue : null; + } + /** * Fill elements for activity for update. * diff --git a/app/IATI/Services/ImportActivity/ImportXmlService.php b/app/IATI/Services/ImportActivity/ImportXmlService.php index d107bee320..f7f09e0a31 100644 --- a/app/IATI/Services/ImportActivity/ImportXmlService.php +++ b/app/IATI/Services/ImportActivity/ImportXmlService.php @@ -186,6 +186,7 @@ public function store(UploadedFile $file): bool * * @return bool * @throws \JsonException + * @throws \ReflectionException */ public function create($activities): bool { @@ -213,13 +214,16 @@ public function create($activities): bool $this->resultRepository->deleteResult($oldActivity->id); $this->saveTransactions(Arr::get($activityData, 'transactions'), $oldActivity->id, $defaultFieldValues); $this->saveResults(Arr::get($activityData, 'result'), $oldActivity->id, $defaultFieldValues); - $this->refreshActivityElementStatusForResult($oldActivity); if (!empty($activity['errors'])) { $this->importActivityErrorRepo->updateOrCreateError($oldActivity->id, $activity['errors']); } else { $this->importActivityErrorRepo->deleteImportError($oldActivity->id); } + + $this->elementCompleteService->refreshElementStatus( + $this->activityRepository->getActivitityWithRelationsById($oldActivity->id) + ); } else { $organizationIdentifier = Auth::user()->organization->identifier; $activityData['iati_identifier']['iati_identifier_text'] = $organizationIdentifier . '-' . $activityData['iati_identifier']['activity_identifier']; @@ -229,11 +233,14 @@ public function create($activities): bool $this->saveTransactions(Arr::get($activityData, 'transactions'), $storeActivity->id, $defaultFieldValues); $this->saveResults(Arr::get($activityData, 'result'), $storeActivity->id, $defaultFieldValues); - $this->refreshActivityElementStatusForResult($storeActivity); if (!empty($activity['errors'])) { $this->importActivityErrorRepo->updateOrCreateError($storeActivity->id, $activity['errors']); } + + $this->elementCompleteService->refreshElementStatus( + $this->activityRepository->getActivitityWithRelationsById($storeActivity->id) + ); } } @@ -413,15 +420,18 @@ protected function dbIatiIdentifiers($org_id): array } /** - * Since we are doing upsert on results for both creation and update, need to manually check if result is complete. + * Since we are doing upsert on results and transaction for both creation and update, + * We need to manually check if result and transaction is complete. * * @throws \JsonException */ - private function refreshActivityElementStatusForResult(Activity $activity): void + private function refreshActivityElementStatusForResultAndTransaction(Activity $activity): void { $elementStatus = $activity->element_status; $resultStatus = $this->elementCompleteService->isResultElementCompleted($activity); + $transactionsStatus = $this->elementCompleteService->isTransactionsElementCompleted($activity); $elementStatus['result'] = $resultStatus; + $elementStatus['transactions'] = $transactionsStatus; $this->activityRepository->update($activity->id, ['element_status' => $elementStatus]); } diff --git a/app/IATI/Traits/DownloadActivitySimpleElementTrait.php b/app/IATI/Traits/DownloadActivitySimpleElementTrait.php index 5af28f700e..402bcccaf6 100644 --- a/app/IATI/Traits/DownloadActivitySimpleElementTrait.php +++ b/app/IATI/Traits/DownloadActivitySimpleElementTrait.php @@ -130,6 +130,9 @@ public function getActivityTitle($activityArray, $rowIndex): ?string /** * Get activity general description. + * Get order: + * - Try to get description text where description language matches activity default language. + * - Try to get first description text where description type matches general description (1). * * @param $activityArray * @param $rowIndex @@ -138,11 +141,23 @@ public function getActivityTitle($activityArray, $rowIndex): ?string */ public function getActivityDescriptionGeneral($activityArray, $rowIndex): ?string { - return ($rowIndex === 0) ? $this->getDescriptionText(Arr::get($activityArray, 'description', []), Arr::get($activityArray, 'default_field_values.default_language', ''), '1') : ''; + $type = '1'; + $activityDescription = Arr::get($activityArray, 'description', []); + $defaultLanguage = Arr::get($activityArray, 'default_field_values.default_language', ''); + $generalDescription = $this->getDescriptionText($activityDescription, $defaultLanguage, $type); + + $generalDescription = empty($generalDescription) + ? $this->getFirstDescriptionTextThatMatchesType($activityDescription, $type) + : $generalDescription; + + return ($rowIndex === 0) ? $generalDescription : ''; } /** * Get activity objectives description. + * Get order: + * - Try to get description text where description language matches activity default language. + * - Try to get first description text where description type matches objective description (2). * * @param $activityArray * @param $rowIndex @@ -151,11 +166,23 @@ public function getActivityDescriptionGeneral($activityArray, $rowIndex): ?strin */ public function getActivityDescriptionObjectives($activityArray, $rowIndex): ?string { - return ($rowIndex === 0) ? $this->getDescriptionText(Arr::get($activityArray, 'description', []), Arr::get($activityArray, 'default_field_values.default_language', ''), '2') : ''; + $type = '2'; + $activityDescription = Arr::get($activityArray, 'description', []); + $defaultLanguage = Arr::get($activityArray, 'default_field_values.default_language', ''); + $objectiveDescription = $this->getDescriptionText($activityDescription, $defaultLanguage, $type); + + $objectiveDescription = empty($objectiveDescription) + ? $this->getFirstDescriptionTextThatMatchesType($activityDescription, $type) + : $objectiveDescription; + + return ($rowIndex === 0) ? $objectiveDescription : ''; } /** * Get activity target groups description. + * Get order: + * - Try to get description text where description language matches activity default language. + * - Try to get first description text where description type matches target groups description (3). * * @param $activityArray * @param $rowIndex @@ -164,11 +191,23 @@ public function getActivityDescriptionObjectives($activityArray, $rowIndex): ?st */ public function getActivityDescriptionTargetGroups($activityArray, $rowIndex): ?string { - return ($rowIndex === 0) ? $this->getDescriptionText(Arr::get($activityArray, 'description', []), Arr::get($activityArray, 'default_field_values.default_language', ''), '3') : ''; + $type = '3'; + $activityDescription = Arr::get($activityArray, 'description', []); + $defaultLanguage = Arr::get($activityArray, 'default_field_values.default_language', ''); + $targetGroupDescription = $this->getDescriptionText($activityDescription, $defaultLanguage, $type); + + $targetGroupDescription = empty($targetGroupDescription) + ? $this->getFirstDescriptionTextThatMatchesType($activityDescription, $type) + : $targetGroupDescription; + + return ($rowIndex === 0) ? $targetGroupDescription : ''; } /** * Get activity others description. + * Get order: + * - Try to get description text where description language matches activity default language. + * - Try to get first description text where description type matches other description (4). * * @param $activityArray * @param $rowIndex @@ -177,7 +216,16 @@ public function getActivityDescriptionTargetGroups($activityArray, $rowIndex): ? */ public function getActivityDescriptionOthers($activityArray, $rowIndex): ?string { - return ($rowIndex === 0) ? $this->getDescriptionText(Arr::get($activityArray, 'description', []), Arr::get($activityArray, 'default_field_values.default_language', ''), '4') : ''; + $type = '4'; + $activityDescription = Arr::get($activityArray, 'description', []); + $defaultLanguage = Arr::get($activityArray, 'default_field_values.default_language', ''); + $otherDescription = $this->getDescriptionText($activityDescription, $defaultLanguage, $type); + + $otherDescription = empty($otherDescription) + ? $this->getFirstDescriptionTextThatMatchesType($activityDescription, $type) + : $otherDescription; + + return ($rowIndex === 0) ? $otherDescription : ''; } /** @@ -482,6 +530,10 @@ public function getSectorNarrative($activityArray, $rowIndex): ?string /** * Get activity policy marker vocabulary. * + * UNDERSTANDING THE RETURN STATEMENTS: + * Since vocabulary is an optional field in the forms, there can be data where there is no vocab but has code. + * So we need to check if code exists, if exists then set vocab = 99 in the downloaded file. + * * @param $activityArray * @param $rowIndex * @@ -489,7 +541,20 @@ public function getSectorNarrative($activityArray, $rowIndex): ?string */ public function getPolicyMarkerVocabulary($activityArray, $rowIndex): ?string { - return (string) (Arr::get($activityArray, 'policy_marker.' . $rowIndex . '.policy_marker_vocabulary', '')); + $policyMarkerVocabulary = Arr::get($activityArray, 'policy_marker.' . $rowIndex . '.policy_marker_vocabulary'); + $hasCode = Arr::get($activityArray, 'policy_marker.' . $rowIndex . '.policy_marker', false) + || Arr::get($activityArray, 'policy_marker.' . $rowIndex . '.policy_marker_text', false); + $hasVocab = !empty($policyMarkerVocabulary); + + if ($hasVocab) { + return $policyMarkerVocabulary; + } + + if ($hasCode) { + return '99'; + } + + return null; } /** @@ -502,7 +567,12 @@ public function getPolicyMarkerVocabulary($activityArray, $rowIndex): ?string */ public function getPolicyMarkerCode($activityArray, $rowIndex): ?string { - return (string) ($this->getPolicyMarkerCodeFromVocabulary(Arr::get($activityArray, 'policy_marker.' . $rowIndex . '.policy_marker_vocabulary', ''), Arr::get($activityArray, 'policy_marker.' . $rowIndex, []))); + return (string) ( + $this->getPolicyMarkerCodeFromVocabulary( + Arr::get($activityArray, 'policy_marker.' . $rowIndex . '.policy_marker_vocabulary', ''), + Arr::get($activityArray, 'policy_marker.' . $rowIndex, []) + ) + ); } /** @@ -541,7 +611,10 @@ public function getPolicyMarkerVocabularyUri($activityArray, $rowIndex): ?string */ public function getPolicyMarkerNarrative($activityArray, $rowIndex): ?string { - return $this->getNarrativeText(Arr::get($activityArray, 'policy_marker.' . $rowIndex . '.narrative', []), Arr::get($activityArray, 'default_field_values.default_language', '')); + return $this->getNarrativeText( + Arr::get($activityArray, 'policy_marker.' . $rowIndex . '.narrative', []), + Arr::get($activityArray, 'default_field_values.default_language', '') + ); } /** diff --git a/app/Jobs/RegistryValidatorJob.php b/app/Jobs/RegistryValidatorJob.php index 4a61ce4f16..e604037d1a 100644 --- a/app/Jobs/RegistryValidatorJob.php +++ b/app/Jobs/RegistryValidatorJob.php @@ -79,7 +79,6 @@ public function handle(ActivityWorkflowService $activityWorkflowService): void { try { if (!Cache::get('activity-validation-delete')) { - logger($this->activity->id); /** @var $validationStatusRepository ValidationStatusRepository */ $validationStatusRepository = app()->make(ValidationStatusRepository::class); $validationStatusRepository->storeValidationStatus((int) $this->activity->id, (int) $this->user->id, status: 'processing'); diff --git a/app/Observers/ActivityObserver.php b/app/Observers/ActivityObserver.php index ce081f5765..b4939d1fdb 100644 --- a/app/Observers/ActivityObserver.php +++ b/app/Observers/ActivityObserver.php @@ -60,8 +60,10 @@ public function setElementStatus($model, bool $isNew = false): void { $elementStatus = $model->element_status; $updatedElements = ($isNew) ? $this->getUpdatedElement($model->getAttributes()) : $this->getUpdatedElement($model->getChanges()); + foreach ($updatedElements as $attribute => $value) { - $elementStatus[$attribute] = call_user_func([$this->elementCompleteService, dashesToCamelCase('is_' . $attribute . '_element_completed')], $model); + $callableFunction = dashesToCamelCase('is_' . $attribute . '_element_completed'); + $elementStatus[$attribute] = call_user_func([$this->elementCompleteService, $callableFunction], $model); } $model->setAttribute('element_status', $elementStatus); diff --git a/app/Observers/TransactionObserver.php b/app/Observers/TransactionObserver.php index 9a74cd3ed9..03402fbdba 100644 --- a/app/Observers/TransactionObserver.php +++ b/app/Observers/TransactionObserver.php @@ -45,35 +45,32 @@ public function updateActivityElementStatus($transaction, bool $changeUpdatedAt { $activityObj = $transaction->activity; $elementStatus = $activityObj->element_status; + $elementStatus['transactions'] = $this->elementCompleteService->isTransactionsElementCompleted($transaction->activity); + $isSectorFilledInActivityLevel = !is_array_value_empty($activityObj->sector); - $isSectorCompletedInActivityLevel = Arr::get($elementStatus, 'sector', false); - $transactionService = app()->make(TransactionService::class); + $isSectorCompletedInActivityLevel = $this->elementCompleteService->isSectorElementCompleted($activityObj); + + /** @var $transactionService TransactionService */ + $transactionService = app(TransactionService::class); + $isSectorFilledInTransactionLevel = $transactionService->checkIfTransactionHasElementDefined($activityObj, 'sector'); - $isSectorCompleteInTransactionLevel = $this->elementCompleteService->isSectorElementCompleted(new Activity(['sector' => $transaction->transaction['sector']])); - - switch([ - $isSectorFilledInActivityLevel, - $isSectorCompletedInActivityLevel, - $isSectorFilledInTransactionLevel, - $isSectorCompleteInTransactionLevel, - ]) { - case [0, 0, 1, 1]: - case [0, 1, 1, 1]: - case [1, 1, 0, 0]: - $elementStatus['sector'] = true; - break; - default: - $elementStatus['sector'] = false; - break; + $isSectorCompleteInTransactionLevel = $this->elementCompleteService->isSectorElementCompletedInTransaction($transaction->activity); + + $elementStatus['sector'] = false; + + if (($isSectorFilledInActivityLevel && $isSectorCompletedInActivityLevel) || ($isSectorFilledInTransactionLevel && $isSectorCompleteInTransactionLevel)) { + $elementStatus['sector'] = true; } - $recipientRegionOrCountryIsCompleteInTransaction = $this->recipientRegionIsEmptyInTransaction($transaction->transaction['recipient_region']) || $this->recipientCountryIsEmptyInTransaction($transaction->transaction['recipient_country']); $recipientRegionOrCountryIsCompleteInActivity = $this->elementCompleteService->isRecipientCountryElementCompleted($activityObj) || $this->elementCompleteService->isRecipientRegionElementCompleted($activityObj); - if ($recipientRegionOrCountryIsCompleteInTransaction || $recipientRegionOrCountryIsCompleteInActivity) { + if ($recipientRegionOrCountryIsCompleteInActivity) { $elementStatus['recipient_region'] = true; $elementStatus['recipient_country'] = true; + } else { + $elementStatus['recipient_region'] = false; + $elementStatus['recipient_country'] = false; } $activityObj->element_status = $elementStatus; diff --git a/app/XlsImporter/Foundation/Mapper/XlsMapper.php b/app/XlsImporter/Foundation/Mapper/XlsMapper.php index a638742930..ca042f9deb 100644 --- a/app/XlsImporter/Foundation/Mapper/XlsMapper.php +++ b/app/XlsImporter/Foundation/Mapper/XlsMapper.php @@ -42,9 +42,9 @@ class XlsMapper public function process(array $xlsData, string $xlsType, $userId, $orgId, $reportingOrg, $dbIatiIdentifiers): static { $xlsMapperTypes = [ - 'activity' => Activity::class, - 'result' => Result::class, - 'period' => Period::class, + 'activity' => Activity::class, + 'result' => Result::class, + 'period' => Period::class, 'indicator' => Indicator::class, ]; $mapper = $xlsMapperTypes[$xlsType]; @@ -56,10 +56,14 @@ public function process(array $xlsData, string $xlsType, $userId, $orgId, $repor /** * $mapper will be an instance of either one of these: + * * \App\XlsImporter\Foundation\Mapper\Activity + * * \App\XlsImporter\Foundation\Mapper\Result - * \App\XlsImporter\Foundation\Mapper\Period - * \App\XlsImporter\Foundation\Mapper\Indicator + * + * \App\XlsImporter\Foundation\Mapper\Period + * + * \App\XlsImporter\Foundation\Mapper\Indicator */ $xlsMapper = new $mapper(); $xlsMapper->initMapper($validatedDataFilePath, $statusFilePath, $globalErrorFilePath, $dbIatiIdentifiers); diff --git a/app/XlsImporter/Foundation/Queue/ImportXls.php b/app/XlsImporter/Foundation/Queue/ImportXls.php index 408fa28165..3a8a33ffa7 100644 --- a/app/XlsImporter/Foundation/Queue/ImportXls.php +++ b/app/XlsImporter/Foundation/Queue/ImportXls.php @@ -100,6 +100,7 @@ public function __construct($organizationId, $reportingOrg, $userId, $filename, public function handle(): void { try { + /** @var XlsQueueProcessor $xlsImportQueue */ $xlsImportQueue = app()->make(XlsQueueProcessor::class); $xlsImportQueue->import($this->filename, $this->organizationId, $this->reportingOrg, $this->userId, $this->iatiIdentifiers, $this->xlsType); diff --git a/app/XmlImporter/Foundation/Mapper/Components/Activity.php b/app/XmlImporter/Foundation/Mapper/Components/Activity.php index 63ef980791..16e4ec1797 100644 --- a/app/XmlImporter/Foundation/Mapper/Components/Activity.php +++ b/app/XmlImporter/Foundation/Mapper/Components/Activity.php @@ -320,19 +320,12 @@ public function getSingleValuedField($element): int|string|null public function description($element): array { $type = $this->attributes($element, 'type'); - $descType = $type; - $this->description[$descType]['type'] = $descType; - if (array_key_exists('narrative', Arr::get($this->description, $descType, []))) { - $narrativeIndex = count($this->description[$descType]['narrative']); + $descriptionNumber = count($this->description); - foreach ($this->narrative($element) as $narrative) { - $this->description[$descType]['narrative'][$narrativeIndex] = $narrative; - $narrativeIndex++; - } - } else { - $this->description[$descType]['narrative'] = $this->narrative($element); - } + $this->description[$descriptionNumber]['type'] = $type; + + $this->description[$descriptionNumber]['narrative'] = $this->narrative($element); return $this->description; } @@ -865,6 +858,13 @@ public function map(array $elementData, $template, $orgRef): array /** * Read default aid type from xml. * + * UNDERSTANDING THE SWITCH STATEMENT: + * - In the form level we can select code without having to select vocabulary. + * - But the code that can be selected without vocabulary belongs to AidType.json. + * - So moving case '1' as default case will handle that scenarios where xml contains code but not vocab. + * - But we still need to verify that the code actually belongs to AidType.json, so im filtering it. + * + * * @param mixed $element * @param mixed $template * @@ -877,27 +877,61 @@ public function defaultAidType(mixed $element, mixed $template): array $vocabulary = $this->attributes($element, 'vocabulary'); $code = $this->attributes($element, 'code'); + $currentDefaultAidType = $this->defaultAidType[$this->index]; + $currentDefaultAidType['default_aid_type_vocabulary'] = $vocabulary; + switch ($vocabulary) { - case '1': - $this->defaultAidType[$this->index]['default_aid_type'] = strtoupper($code); - break; case '2': - $this->defaultAidType[$this->index]['earmarking_category'] = $code; + $currentDefaultAidType['earmarking_category'] = $code; + $fields = ['default_aid_type_vocabulary', 'earmarking_category']; break; + case '3': - $this->defaultAidType[$this->index]['earmarking_modality'] = strtoupper($code); + $currentDefaultAidType['earmarking_modality'] = strtoupper($code); + $fields = ['default_aid_type_vocabulary', 'earmarking_modality']; break; + case '4': - $this->defaultAidType[$this->index]['cash_and_voucher_modalities'] = $code; + $currentDefaultAidType['cash_and_voucher_modalities'] = $code; + $fields = ['default_aid_type_vocabulary', 'cash_and_voucher_modalities']; + break; + + default: + $code = strtoupper($code); + $currentDefaultAidType['default_aid_type'] = ''; + + if ($this->isValidAidTypeCode($code)) { + $currentDefaultAidType['default_aid_type'] = $code; + } + + $fields = ['default_aid_type_vocabulary', 'default_aid_type']; break; } - $this->defaultAidType[$this->index]['default_aid_type_vocabulary'] = $vocabulary; + $currentDefaultAidType = Arr::only($currentDefaultAidType, $fields); + $this->defaultAidType[$this->index] = $currentDefaultAidType; + $this->index++; return $this->defaultAidType; } + /** + * Check if code is valid by comparing against AidType.json. + * + * @param string $code + * + * @return bool + */ + private function isValidAidTypeCode(string $code): bool + { + $filePath = 'AppData/Data/Activity/AidType.json'; + $aidTypes = Arr::get(json_decode(getJsonFromSource($filePath), true), 'AidType', []); + $validCodes = array_map(fn ($item) => $item['code'], $aidTypes); + + return in_array($code, $validCodes, true); + } + /** * Read tag from xml. * @@ -910,27 +944,36 @@ public function tag($element, $template): array { $this->tagVariable[$this->index] = $template['tag']; $tagVocabulary = $this->attributes($element, 'vocabulary'); - $tagVocabulary = $tagVocabulary; $this->tagVariable[$this->index]['tag_vocabulary'] = $this->attributes($element, 'vocabulary'); $this->tagVariable[$this->index]['vocabulary_uri'] = $this->attributes($element, 'vocabulary-uri'); $this->tagVariable[$this->index]['narrative'] = $this->narrative($element); switch ($tagVocabulary) { - case '1': - $this->tagVariable[$this->index]['tag_text'] = $this->attributes($element, 'code'); - break; case '2': $this->tagVariable[$this->index]['goals_tag_code'] = $this->attributes($element, 'code'); + $fields = ['tag_vocabulary', 'goals_tag_code', 'narrative']; + break; case '3': $this->tagVariable[$this->index]['targets_tag_code'] = strtolower($this->attributes($element, 'code')); + $fields = ['tag_vocabulary', 'targets_tag_code', 'narrative']; + break; - case '99': + case '1': + case '4': $this->tagVariable[$this->index]['tag_text'] = $this->attributes($element, 'code'); + $fields = ['tag_vocabulary', 'tag_text', 'narrative']; + + break; + default: + $this->tagVariable[$this->index]['tag_text'] = $this->attributes($element, 'code'); + $fields = ['tag_vocabulary', 'tag_text', 'narrative', 'vocabulary_uri']; + break; } + $this->tagVariable[$this->index] = Arr::only($this->tagVariable[$this->index], $fields); $this->index++; return $this->tagVariable; diff --git a/public/js/formbuilder.js b/public/js/formbuilder.js index a0dfcc6e33..253c914df0 100644 --- a/public/js/formbuilder.js +++ b/public/js/formbuilder.js @@ -9,12 +9,6 @@ -function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } -function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } -function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } -function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } @@ -564,10 +558,8 @@ exports.DynamicField = DynamicField; } }); (0, jquery_1["default"])(document).on('click', '.help', function (event) { - var _console; event.stopPropagation(); - /* eslint-disable */ - (_console = console).log.apply(_console, _toConsumableArray(oo_oo("796322843_989_2_989_22_4", 'Hello'))); + console.log('Hello'); (0, jquery_1["default"])('.help__text').removeAttr('style'); var helpText = (0, jquery_1["default"])(this).find('.help__text'); if (helpText.length > 0) { @@ -608,63 +600,6 @@ function closeHelpText(helpText) { * Help Text Open Close Handlers End * */ -/* istanbul ignore next */ /* c8 ignore start */ /* eslint-disable */ -; -function oo_cm() { - try { - return (0, eval)("globalThis._console_ninja") || (0, eval)("/* https://github.com/wallabyjs/console-ninja#how-does-it-work */'use strict';var _0x31e486=_0x33b2;function _0x33b2(_0x2d1615,_0x29ccb4){var _0x34e9f3=_0x34e9();return _0x33b2=function(_0x33b23b,_0x393a74){_0x33b23b=_0x33b23b-0x145;var _0x41272d=_0x34e9f3[_0x33b23b];return _0x41272d;},_0x33b2(_0x2d1615,_0x29ccb4);}function _0x34e9(){var _0x1704f2=['expId','setter','nodeModules','index','_addObjectProperty','trace','HTMLAllCollection','sortProps','date','_isUndefined','replace','1','versions','_propertyName','_addProperty','_disposeWebsocket','autoExpandPropertyCount','_inNextEdge','logger\\x20failed\\x20to\\x20connect\\x20to\\x20host','slice','location','defineProperty','_keyStrRegExp','symbol','[object\\x20Set]','_p_','[object\\x20Array]','process','props','_sendErrorMessage','string','null','object','_getOwnPropertyDescriptor','log','_additionalMetadata','bind','performance','2910NyVCQD','level','includes','elapsed','_connectToHostNow','call','push','function','totalStrLength','hrtime','_console_ninja_session','timeStamp','fromCharCode','autoExpandMaxDepth','ws://','_numberRegExp','POSITIVE_INFINITY','_setNodeExpressionPath','number','join','cappedProps','onmessage','bigint','_isPrimitiveWrapperType','then','_sortProps','env','noFunctions','_quotedRegExp','logger\\x20failed\\x20to\\x20connect\\x20to\\x20host,\\x20see\\x20','concat','endsWith','perf_hooks','allStrLength','_ninjaIgnoreNextError','hits','isExpressionToEvaluate','_addLoadNode','astro','_socket','_treeNodePropertiesBeforeFullValue','prototype','_objectToString','_ws','8374478Ptcajj','capped','time','81460gnMsaC','Console\\x20Ninja\\x20failed\\x20to\\x20send\\x20logs,\\x20refreshing\\x20the\\x20page\\x20may\\x20help;\\x20also\\x20see\\x20','test','_webSocketErrorDocsLink','disabledLog','substr','message','NEGATIVE_INFINITY','constructor','current','strLength','autoExpandPreviousObjects','2695880zzbxhX','url','rootExpression','value','method','type','onerror','_setNodePermissions','toString','__es'+'Module','path','33453','_maxConnectAttemptCount','_WebSocketClass','1296EpmMlu','elements','','Error','_p_length','count','reduceLimits','length','[object\\x20Map]','_isNegativeZero','_getOwnPropertyNames','_treeNodePropertiesAfterFullValue','_property','default','_isPrimitiveType','_blacklistedProperty','Set','valueOf','get','pathToFileURL','name','Console\\x20Ninja\\x20failed\\x20to\\x20send\\x20logs,\\x20restarting\\x20the\\x20process\\x20may\\x20help;\\x20also\\x20see\\x20','negativeInfinity','enumerable','cappedElements','\\x20server','Symbol','origin','onclose','readyState','warn','_setNodeExpandableState','catch','close','webpack','host','positiveInfinity','_connectAttemptCount','Map','_dateToString','forEach','onopen','console','_addFunctionsNode','ws/index.js','getWebSocketClass','root_exp_id','stack','_p_name','array','_attemptToReconnectShortly','11622umfwXy','boolean','42656kjgZJZ','undefined','_type','toUpperCase','set','autoExpand','_setNodeLabel','getter','_allowedToConnectOnSend','map','_inBrowser','_processTreeNodeResult','_connected','parent','parse','args','stringify','data','_getOwnPropertySymbols','unref','_Symbol','NEXT_RUNTIME','hostname','_undefined','toLowerCase',\"/home/fluffy/.vscode/extensions/wallabyjs.console-ninja-1.0.382/node_modules\",'String','RegExp','_WebSocket','1.0.0','match','_connecting','getOwnPropertySymbols','global','error','_isMap','1981581WOiCXu','_isArray','expressionsToEvaluate','depth','eventReceivedCallback','_allowedToSend','node','dockerizedApp','unshift','autoExpandLimit','getOwnPropertyNames','_cleanNode','_reconnectTimeout','_regExpToString','stackTraceLimit','unknown','serialize','edge','port','_HTMLAllCollection',[\"localhost\",\"127.0.0.1\",\"example.cypress.io\",\"fluffy\",\"192.168.10.176\"],'_console_ninja','_isSet','remix','_hasMapOnItsPath','see\\x20https://tinyurl.com/2vt8jxzw\\x20for\\x20more\\x20info.','\\x20browser','failed\\x20to\\x20find\\x20and\\x20load\\x20WebSocket','some','now','next.js','_consoleNinjaAllowedToStart','574600opaWqz','send','_capIfString'];_0x34e9=function(){return _0x1704f2;};return _0x34e9();}(function(_0x49e719,_0x2b4bc8){var _0xec630c=_0x33b2,_0x51f3c2=_0x49e719();while(!![]){try{var _0x3bc92c=parseInt(_0xec630c(0x19b))/0x1+-parseInt(_0xec630c(0x22e))/0x2+parseInt(_0xec630c(0x20e))/0x3+-parseInt(_0xec630c(0x1a7))/0x4+-parseInt(_0xec630c(0x16c))/0x5*(parseInt(_0xec630c(0x1e8))/0x6)+parseInt(_0xec630c(0x198))/0x7+parseInt(_0xec630c(0x1ea))/0x8*(parseInt(_0xec630c(0x1b5))/0x9);if(_0x3bc92c===_0x2b4bc8)break;else _0x51f3c2['push'](_0x51f3c2['shift']());}catch(_0x22869e){_0x51f3c2['push'](_0x51f3c2['shift']());}}}(_0x34e9,0x96c49));var K=Object['create'],Q=Object[_0x31e486(0x15b)],G=Object['getOwnPropertyDescriptor'],ee=Object[_0x31e486(0x218)],te=Object['getPrototypeOf'],ne=Object['prototype']['hasOwnProperty'],re=(_0x289cf0,_0x17323c,_0x12d63c,_0x1e9b6d)=>{var _0x3742da=_0x31e486;if(_0x17323c&&typeof _0x17323c==_0x3742da(0x166)||typeof _0x17323c==_0x3742da(0x173)){for(let _0x30c8e9 of ee(_0x17323c))!ne[_0x3742da(0x171)](_0x289cf0,_0x30c8e9)&&_0x30c8e9!==_0x12d63c&&Q(_0x289cf0,_0x30c8e9,{'get':()=>_0x17323c[_0x30c8e9],'enumerable':!(_0x1e9b6d=G(_0x17323c,_0x30c8e9))||_0x1e9b6d[_0x3742da(0x1cc)]});}return _0x289cf0;},V=(_0x4d43b3,_0x28c699,_0x3e4ebc)=>(_0x3e4ebc=_0x4d43b3!=null?K(te(_0x4d43b3)):{},re(_0x28c699||!_0x4d43b3||!_0x4d43b3[_0x31e486(0x1b0)]?Q(_0x3e4ebc,_0x31e486(0x1c2),{'value':_0x4d43b3,'enumerable':!0x0}):_0x3e4ebc,_0x4d43b3)),Z=class{constructor(_0x190aa8,_0x48b519,_0x1f1ddd,_0x2a49f8,_0xdd448a,_0x26baee){var _0xcd3931=_0x31e486,_0x2911c5,_0x19538c,_0x3e7b24,_0x170571;this['global']=_0x190aa8,this['host']=_0x48b519,this[_0xcd3931(0x220)]=_0x1f1ddd,this[_0xcd3931(0x148)]=_0x2a49f8,this['dockerizedApp']=_0xdd448a,this['eventReceivedCallback']=_0x26baee,this['_allowedToSend']=!0x0,this['_allowedToConnectOnSend']=!0x0,this['_connected']=!0x1,this[_0xcd3931(0x209)]=!0x1,this[_0xcd3931(0x157)]=((_0x19538c=(_0x2911c5=_0x190aa8['process'])==null?void 0x0:_0x2911c5['env'])==null?void 0x0:_0x19538c['NEXT_RUNTIME'])==='edge',this[_0xcd3931(0x1f4)]=!((_0x170571=(_0x3e7b24=this[_0xcd3931(0x20b)][_0xcd3931(0x161)])==null?void 0x0:_0x3e7b24[_0xcd3931(0x152)])!=null&&_0x170571[_0xcd3931(0x214)])&&!this[_0xcd3931(0x157)],this[_0xcd3931(0x1b4)]=null,this[_0xcd3931(0x1da)]=0x0,this[_0xcd3931(0x1b3)]=0x14,this['_webSocketErrorDocsLink']='https://tinyurl.com/37x8b79t',this[_0xcd3931(0x163)]=(this[_0xcd3931(0x1f4)]?_0xcd3931(0x19c):_0xcd3931(0x1ca))+this[_0xcd3931(0x19e)];}async[_0x31e486(0x1e2)](){var _0x3409a9=_0x31e486,_0x2b3f86,_0x448030;if(this[_0x3409a9(0x1b4)])return this[_0x3409a9(0x1b4)];let _0x528636;if(this['_inBrowser']||this[_0x3409a9(0x157)])_0x528636=this[_0x3409a9(0x20b)]['WebSocket'];else{if((_0x2b3f86=this[_0x3409a9(0x20b)]['process'])!=null&&_0x2b3f86[_0x3409a9(0x206)])_0x528636=(_0x448030=this['global']['process'])==null?void 0x0:_0x448030[_0x3409a9(0x206)];else try{let _0x1088b4=await import(_0x3409a9(0x1b1));_0x528636=(await import((await import(_0x3409a9(0x1a8)))[_0x3409a9(0x1c8)](_0x1088b4[_0x3409a9(0x17f)](this[_0x3409a9(0x148)],_0x3409a9(0x1e1)))[_0x3409a9(0x1af)]()))['default'];}catch{try{_0x528636=require(require('path')[_0x3409a9(0x17f)](this['nodeModules'],'ws'));}catch{throw new Error(_0x3409a9(0x229));}}}return this[_0x3409a9(0x1b4)]=_0x528636,_0x528636;}[_0x31e486(0x170)](){var _0x29a825=_0x31e486;this['_connecting']||this['_connected']||this[_0x29a825(0x1da)]>=this[_0x29a825(0x1b3)]||(this[_0x29a825(0x1f2)]=!0x1,this[_0x29a825(0x209)]=!0x0,this[_0x29a825(0x1da)]++,this[_0x29a825(0x197)]=new Promise((_0x1f2c48,_0x5b02f8)=>{var _0x413ca9=_0x29a825;this[_0x413ca9(0x1e2)]()[_0x413ca9(0x184)](_0x4e9fb8=>{var _0x231fd9=_0x413ca9;let _0x15ba8a=new _0x4e9fb8(_0x231fd9(0x17a)+(!this['_inBrowser']&&this[_0x231fd9(0x215)]?'gateway.docker.internal':this[_0x231fd9(0x1d8)])+':'+this[_0x231fd9(0x220)]);_0x15ba8a['onerror']=()=>{var _0x48d418=_0x231fd9;this[_0x48d418(0x213)]=!0x1,this[_0x48d418(0x155)](_0x15ba8a),this[_0x48d418(0x1e7)](),_0x5b02f8(new Error('logger\\x20websocket\\x20error'));},_0x15ba8a['onopen']=()=>{var _0x3ed611=_0x231fd9;this[_0x3ed611(0x1f4)]||_0x15ba8a[_0x3ed611(0x193)]&&_0x15ba8a['_socket'][_0x3ed611(0x1fd)]&&_0x15ba8a[_0x3ed611(0x193)][_0x3ed611(0x1fd)](),_0x1f2c48(_0x15ba8a);},_0x15ba8a[_0x231fd9(0x1d1)]=()=>{var _0x869626=_0x231fd9;this[_0x869626(0x1f2)]=!0x0,this[_0x869626(0x155)](_0x15ba8a),this[_0x869626(0x1e7)]();},_0x15ba8a[_0x231fd9(0x181)]=_0x3d8ace=>{var _0x1223ba=_0x231fd9;try{if(!(_0x3d8ace!=null&&_0x3d8ace['data'])||!this[_0x1223ba(0x212)])return;let _0x52f38=JSON[_0x1223ba(0x1f8)](_0x3d8ace[_0x1223ba(0x1fb)]);this['eventReceivedCallback'](_0x52f38[_0x1223ba(0x1ab)],_0x52f38[_0x1223ba(0x1f9)],this[_0x1223ba(0x20b)],this[_0x1223ba(0x1f4)]);}catch{}};})['then'](_0x213740=>(this[_0x413ca9(0x1f6)]=!0x0,this[_0x413ca9(0x209)]=!0x1,this[_0x413ca9(0x1f2)]=!0x1,this['_allowedToSend']=!0x0,this[_0x413ca9(0x1da)]=0x0,_0x213740))[_0x413ca9(0x1d5)](_0x244876=>(this[_0x413ca9(0x1f6)]=!0x1,this[_0x413ca9(0x209)]=!0x1,console[_0x413ca9(0x1d3)](_0x413ca9(0x189)+this[_0x413ca9(0x19e)]),_0x5b02f8(new Error('failed\\x20to\\x20connect\\x20to\\x20host:\\x20'+(_0x244876&&_0x244876['message'])))));}));}[_0x31e486(0x155)](_0x38cd1f){var _0x226baf=_0x31e486;this[_0x226baf(0x1f6)]=!0x1,this[_0x226baf(0x209)]=!0x1;try{_0x38cd1f[_0x226baf(0x1d1)]=null,_0x38cd1f[_0x226baf(0x1ad)]=null,_0x38cd1f[_0x226baf(0x1de)]=null;}catch{}try{_0x38cd1f[_0x226baf(0x1d2)]<0x2&&_0x38cd1f[_0x226baf(0x1d6)]();}catch{}}[_0x31e486(0x1e7)](){var _0x535e73=_0x31e486;clearTimeout(this[_0x535e73(0x21a)]),!(this['_connectAttemptCount']>=this['_maxConnectAttemptCount'])&&(this['_reconnectTimeout']=setTimeout(()=>{var _0x465142=_0x535e73,_0x14cd5a;this[_0x465142(0x1f6)]||this[_0x465142(0x209)]||(this['_connectToHostNow'](),(_0x14cd5a=this[_0x465142(0x197)])==null||_0x14cd5a['catch'](()=>this[_0x465142(0x1e7)]()));},0x1f4),this[_0x535e73(0x21a)][_0x535e73(0x1fd)]&&this[_0x535e73(0x21a)]['unref']());}async[_0x31e486(0x22f)](_0x5f27a2){var _0x3429a4=_0x31e486;try{if(!this[_0x3429a4(0x213)])return;this[_0x3429a4(0x1f2)]&&this[_0x3429a4(0x170)](),(await this['_ws'])[_0x3429a4(0x22f)](JSON[_0x3429a4(0x1fa)](_0x5f27a2));}catch(_0x5afec6){console[_0x3429a4(0x1d3)](this[_0x3429a4(0x163)]+':\\x20'+(_0x5afec6&&_0x5afec6[_0x3429a4(0x1a1)])),this['_allowedToSend']=!0x1,this[_0x3429a4(0x1e7)]();}}};function q(_0x42986d,_0x203a38,_0x30927a,_0x1b9594,_0x250bbe,_0x2e256f,_0x301b22,_0x3f7c26=ie){var _0x373131=_0x31e486;let _0x3d094e=_0x30927a['split'](',')[_0x373131(0x1f3)](_0x534546=>{var _0x53f651=_0x373131,_0x469434,_0x195f23,_0x4bea5f,_0x1442e8;try{if(!_0x42986d[_0x53f651(0x176)]){let _0x2303eb=((_0x195f23=(_0x469434=_0x42986d[_0x53f651(0x161)])==null?void 0x0:_0x469434[_0x53f651(0x152)])==null?void 0x0:_0x195f23[_0x53f651(0x214)])||((_0x1442e8=(_0x4bea5f=_0x42986d[_0x53f651(0x161)])==null?void 0x0:_0x4bea5f[_0x53f651(0x186)])==null?void 0x0:_0x1442e8[_0x53f651(0x1ff)])===_0x53f651(0x21f);(_0x250bbe===_0x53f651(0x22c)||_0x250bbe===_0x53f651(0x225)||_0x250bbe===_0x53f651(0x192)||_0x250bbe==='angular')&&(_0x250bbe+=_0x2303eb?_0x53f651(0x1ce):_0x53f651(0x228)),_0x42986d['_console_ninja_session']={'id':+new Date(),'tool':_0x250bbe},_0x301b22&&_0x250bbe&&!_0x2303eb&&console[_0x53f651(0x168)]('%c\\x20Console\\x20Ninja\\x20extension\\x20is\\x20connected\\x20to\\x20'+(_0x250bbe['charAt'](0x0)[_0x53f651(0x1ed)]()+_0x250bbe[_0x53f651(0x1a0)](0x1))+',','background:\\x20rgb(30,30,30);\\x20color:\\x20rgb(255,213,92)',_0x53f651(0x227));}let _0x273b64=new Z(_0x42986d,_0x203a38,_0x534546,_0x1b9594,_0x2e256f,_0x3f7c26);return _0x273b64[_0x53f651(0x22f)][_0x53f651(0x16a)](_0x273b64);}catch(_0x2034d6){return console[_0x53f651(0x1d3)](_0x53f651(0x158),_0x2034d6&&_0x2034d6[_0x53f651(0x1a1)]),()=>{};}});return _0x4eefa5=>_0x3d094e[_0x373131(0x1dd)](_0x3da91a=>_0x3da91a(_0x4eefa5));}function ie(_0x1c7751,_0x222cd0,_0x1ee3e2,_0x52f6a9){var _0x486680=_0x31e486;_0x52f6a9&&_0x1c7751==='reload'&&_0x1ee3e2[_0x486680(0x15a)]['reload']();}function B(_0xf6208d){var _0x5201ef=_0x31e486,_0x4c8cf9,_0x3c74de;let _0x3a81a3=function(_0x4f56d7,_0x47aa48){return _0x47aa48-_0x4f56d7;},_0x4e3665;if(_0xf6208d['performance'])_0x4e3665=function(){var _0x12052f=_0x33b2;return _0xf6208d[_0x12052f(0x16b)][_0x12052f(0x22b)]();};else{if(_0xf6208d[_0x5201ef(0x161)]&&_0xf6208d['process'][_0x5201ef(0x175)]&&((_0x3c74de=(_0x4c8cf9=_0xf6208d[_0x5201ef(0x161)])==null?void 0x0:_0x4c8cf9[_0x5201ef(0x186)])==null?void 0x0:_0x3c74de[_0x5201ef(0x1ff)])!=='edge')_0x4e3665=function(){var _0x54c5a0=_0x5201ef;return _0xf6208d[_0x54c5a0(0x161)][_0x54c5a0(0x175)]();},_0x3a81a3=function(_0x469bab,_0x19b5b4){return 0x3e8*(_0x19b5b4[0x0]-_0x469bab[0x0])+(_0x19b5b4[0x1]-_0x469bab[0x1])/0xf4240;};else try{let {performance:_0x420be7}=require(_0x5201ef(0x18c));_0x4e3665=function(){return _0x420be7['now']();};}catch{_0x4e3665=function(){return+new Date();};}}return{'elapsed':_0x3a81a3,'timeStamp':_0x4e3665,'now':()=>Date['now']()};}function H(_0x1601f6,_0x459cd1,_0x47b2b0){var _0x43a750=_0x31e486,_0x2008dc,_0x40416f,_0x190def,_0x5bbf24,_0x55aa85;if(_0x1601f6[_0x43a750(0x22d)]!==void 0x0)return _0x1601f6[_0x43a750(0x22d)];let _0x20dc94=((_0x40416f=(_0x2008dc=_0x1601f6[_0x43a750(0x161)])==null?void 0x0:_0x2008dc[_0x43a750(0x152)])==null?void 0x0:_0x40416f['node'])||((_0x5bbf24=(_0x190def=_0x1601f6[_0x43a750(0x161)])==null?void 0x0:_0x190def[_0x43a750(0x186)])==null?void 0x0:_0x5bbf24[_0x43a750(0x1ff)])==='edge';function _0xf314cc(_0x3a1e98){var _0x2be344=_0x43a750;if(_0x3a1e98['startsWith']('/')&&_0x3a1e98[_0x2be344(0x18b)]('/')){let _0x14c90c=new RegExp(_0x3a1e98[_0x2be344(0x159)](0x1,-0x1));return _0x5028b2=>_0x14c90c[_0x2be344(0x19d)](_0x5028b2);}else{if(_0x3a1e98[_0x2be344(0x16e)]('*')||_0x3a1e98[_0x2be344(0x16e)]('?')){let _0x2867ee=new RegExp('^'+_0x3a1e98[_0x2be344(0x150)](/\\./g,String[_0x2be344(0x178)](0x5c)+'.')['replace'](/\\*/g,'.*')[_0x2be344(0x150)](/\\?/g,'.')+String[_0x2be344(0x178)](0x24));return _0xa0716c=>_0x2867ee['test'](_0xa0716c);}else return _0x4ba06a=>_0x4ba06a===_0x3a1e98;}}let _0x53c890=_0x459cd1['map'](_0xf314cc);return _0x1601f6[_0x43a750(0x22d)]=_0x20dc94||!_0x459cd1,!_0x1601f6['_consoleNinjaAllowedToStart']&&((_0x55aa85=_0x1601f6['location'])==null?void 0x0:_0x55aa85[_0x43a750(0x200)])&&(_0x1601f6[_0x43a750(0x22d)]=_0x53c890[_0x43a750(0x22a)](_0x416625=>_0x416625(_0x1601f6['location']['hostname']))),_0x1601f6[_0x43a750(0x22d)];}function X(_0x426d5f,_0x58bd93,_0x2dbbb7,_0x2efb32){var _0x127735=_0x31e486;_0x426d5f=_0x426d5f,_0x58bd93=_0x58bd93,_0x2dbbb7=_0x2dbbb7,_0x2efb32=_0x2efb32;let _0xbbf52f=B(_0x426d5f),_0x232d0d=_0xbbf52f[_0x127735(0x16f)],_0x5b689d=_0xbbf52f[_0x127735(0x177)];class _0x2e0d3c{constructor(){var _0x5421b9=_0x127735;this[_0x5421b9(0x15c)]=/^(?!(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$)[_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*$/,this[_0x5421b9(0x17b)]=/^(0|[1-9][0-9]*)$/,this[_0x5421b9(0x188)]=/'([^\\\\']|\\\\')*'/,this['_undefined']=_0x426d5f[_0x5421b9(0x1eb)],this[_0x5421b9(0x221)]=_0x426d5f[_0x5421b9(0x14c)],this[_0x5421b9(0x167)]=Object['getOwnPropertyDescriptor'],this[_0x5421b9(0x1bf)]=Object[_0x5421b9(0x218)],this['_Symbol']=_0x426d5f[_0x5421b9(0x1cf)],this[_0x5421b9(0x21b)]=RegExp[_0x5421b9(0x195)]['toString'],this[_0x5421b9(0x1dc)]=Date[_0x5421b9(0x195)]['toString'];}['serialize'](_0x5150b2,_0xd40a4b,_0x1c7900,_0x4196d7){var _0x2c7d04=_0x127735,_0x38e94a=this,_0x879d98=_0x1c7900[_0x2c7d04(0x1ef)];function _0x801e45(_0x4bf643,_0x406e93,_0x303f2d){var _0x457809=_0x2c7d04;_0x406e93['type']='unknown',_0x406e93[_0x457809(0x20c)]=_0x4bf643[_0x457809(0x1a1)],_0x1229b2=_0x303f2d[_0x457809(0x214)][_0x457809(0x1a4)],_0x303f2d[_0x457809(0x214)][_0x457809(0x1a4)]=_0x406e93,_0x38e94a['_treeNodePropertiesBeforeFullValue'](_0x406e93,_0x303f2d);}try{_0x1c7900['level']++,_0x1c7900[_0x2c7d04(0x1ef)]&&_0x1c7900[_0x2c7d04(0x1a6)][_0x2c7d04(0x172)](_0xd40a4b);var _0x5d8a16,_0x516b20,_0x25b902,_0x218f55,_0x5d1e4b=[],_0x735244=[],_0x4f15fe,_0x2ea7ae=this[_0x2c7d04(0x1ec)](_0xd40a4b),_0x397c7e=_0x2ea7ae===_0x2c7d04(0x1e6),_0x223e77=!0x1,_0x2ef34b=_0x2ea7ae===_0x2c7d04(0x173),_0x1b18bc=this['_isPrimitiveType'](_0x2ea7ae),_0x5c4fdd=this[_0x2c7d04(0x183)](_0x2ea7ae),_0x11a15d=_0x1b18bc||_0x5c4fdd,_0x503a2d={},_0x539ed3=0x0,_0x412eda=!0x1,_0x1229b2,_0x129776=/^(([1-9]{1}[0-9]*)|0)$/;if(_0x1c7900[_0x2c7d04(0x211)]){if(_0x397c7e){if(_0x516b20=_0xd40a4b['length'],_0x516b20>_0x1c7900[_0x2c7d04(0x1b6)]){for(_0x25b902=0x0,_0x218f55=_0x1c7900[_0x2c7d04(0x1b6)],_0x5d8a16=_0x25b902;_0x5d8a16<_0x218f55;_0x5d8a16++)_0x735244['push'](_0x38e94a[_0x2c7d04(0x154)](_0x5d1e4b,_0xd40a4b,_0x2ea7ae,_0x5d8a16,_0x1c7900));_0x5150b2[_0x2c7d04(0x1cd)]=!0x0;}else{for(_0x25b902=0x0,_0x218f55=_0x516b20,_0x5d8a16=_0x25b902;_0x5d8a16<_0x218f55;_0x5d8a16++)_0x735244[_0x2c7d04(0x172)](_0x38e94a[_0x2c7d04(0x154)](_0x5d1e4b,_0xd40a4b,_0x2ea7ae,_0x5d8a16,_0x1c7900));}_0x1c7900['autoExpandPropertyCount']+=_0x735244[_0x2c7d04(0x1bc)];}if(!(_0x2ea7ae===_0x2c7d04(0x165)||_0x2ea7ae==='undefined')&&!_0x1b18bc&&_0x2ea7ae!==_0x2c7d04(0x204)&&_0x2ea7ae!=='Buffer'&&_0x2ea7ae!==_0x2c7d04(0x182)){var _0x3efa2d=_0x4196d7[_0x2c7d04(0x162)]||_0x1c7900['props'];if(this[_0x2c7d04(0x224)](_0xd40a4b)?(_0x5d8a16=0x0,_0xd40a4b['forEach'](function(_0x20cf5e){var _0x3010a4=_0x2c7d04;if(_0x539ed3++,_0x1c7900[_0x3010a4(0x156)]++,_0x539ed3>_0x3efa2d){_0x412eda=!0x0;return;}if(!_0x1c7900[_0x3010a4(0x190)]&&_0x1c7900[_0x3010a4(0x1ef)]&&_0x1c7900[_0x3010a4(0x156)]>_0x1c7900['autoExpandLimit']){_0x412eda=!0x0;return;}_0x735244[_0x3010a4(0x172)](_0x38e94a[_0x3010a4(0x154)](_0x5d1e4b,_0xd40a4b,_0x3010a4(0x1c5),_0x5d8a16++,_0x1c7900,function(_0x511f78){return function(){return _0x511f78;};}(_0x20cf5e)));})):this[_0x2c7d04(0x20d)](_0xd40a4b)&&_0xd40a4b[_0x2c7d04(0x1dd)](function(_0x18c390,_0x4004f5){var _0x436a43=_0x2c7d04;if(_0x539ed3++,_0x1c7900[_0x436a43(0x156)]++,_0x539ed3>_0x3efa2d){_0x412eda=!0x0;return;}if(!_0x1c7900['isExpressionToEvaluate']&&_0x1c7900[_0x436a43(0x1ef)]&&_0x1c7900[_0x436a43(0x156)]>_0x1c7900[_0x436a43(0x217)]){_0x412eda=!0x0;return;}var _0x4a8f1c=_0x4004f5[_0x436a43(0x1af)]();_0x4a8f1c[_0x436a43(0x1bc)]>0x64&&(_0x4a8f1c=_0x4a8f1c[_0x436a43(0x159)](0x0,0x64)+'...'),_0x735244[_0x436a43(0x172)](_0x38e94a['_addProperty'](_0x5d1e4b,_0xd40a4b,_0x436a43(0x1db),_0x4a8f1c,_0x1c7900,function(_0x1bda3c){return function(){return _0x1bda3c;};}(_0x18c390)));}),!_0x223e77){try{for(_0x4f15fe in _0xd40a4b)if(!(_0x397c7e&&_0x129776[_0x2c7d04(0x19d)](_0x4f15fe))&&!this['_blacklistedProperty'](_0xd40a4b,_0x4f15fe,_0x1c7900)){if(_0x539ed3++,_0x1c7900[_0x2c7d04(0x156)]++,_0x539ed3>_0x3efa2d){_0x412eda=!0x0;break;}if(!_0x1c7900[_0x2c7d04(0x190)]&&_0x1c7900['autoExpand']&&_0x1c7900[_0x2c7d04(0x156)]>_0x1c7900[_0x2c7d04(0x217)]){_0x412eda=!0x0;break;}_0x735244[_0x2c7d04(0x172)](_0x38e94a[_0x2c7d04(0x14a)](_0x5d1e4b,_0x503a2d,_0xd40a4b,_0x2ea7ae,_0x4f15fe,_0x1c7900));}}catch{}if(_0x503a2d[_0x2c7d04(0x1b9)]=!0x0,_0x2ef34b&&(_0x503a2d[_0x2c7d04(0x1e5)]=!0x0),!_0x412eda){var _0x3eabb9=[][_0x2c7d04(0x18a)](this['_getOwnPropertyNames'](_0xd40a4b))[_0x2c7d04(0x18a)](this[_0x2c7d04(0x1fc)](_0xd40a4b));for(_0x5d8a16=0x0,_0x516b20=_0x3eabb9[_0x2c7d04(0x1bc)];_0x5d8a16<_0x516b20;_0x5d8a16++)if(_0x4f15fe=_0x3eabb9[_0x5d8a16],!(_0x397c7e&&_0x129776[_0x2c7d04(0x19d)](_0x4f15fe['toString']()))&&!this['_blacklistedProperty'](_0xd40a4b,_0x4f15fe,_0x1c7900)&&!_0x503a2d['_p_'+_0x4f15fe[_0x2c7d04(0x1af)]()]){if(_0x539ed3++,_0x1c7900[_0x2c7d04(0x156)]++,_0x539ed3>_0x3efa2d){_0x412eda=!0x0;break;}if(!_0x1c7900[_0x2c7d04(0x190)]&&_0x1c7900[_0x2c7d04(0x1ef)]&&_0x1c7900[_0x2c7d04(0x156)]>_0x1c7900[_0x2c7d04(0x217)]){_0x412eda=!0x0;break;}_0x735244[_0x2c7d04(0x172)](_0x38e94a[_0x2c7d04(0x14a)](_0x5d1e4b,_0x503a2d,_0xd40a4b,_0x2ea7ae,_0x4f15fe,_0x1c7900));}}}}}if(_0x5150b2[_0x2c7d04(0x1ac)]=_0x2ea7ae,_0x11a15d?(_0x5150b2['value']=_0xd40a4b[_0x2c7d04(0x1c6)](),this[_0x2c7d04(0x145)](_0x2ea7ae,_0x5150b2,_0x1c7900,_0x4196d7)):_0x2ea7ae===_0x2c7d04(0x14e)?_0x5150b2['value']=this[_0x2c7d04(0x1dc)]['call'](_0xd40a4b):_0x2ea7ae===_0x2c7d04(0x182)?_0x5150b2[_0x2c7d04(0x1aa)]=_0xd40a4b[_0x2c7d04(0x1af)]():_0x2ea7ae===_0x2c7d04(0x205)?_0x5150b2['value']=this[_0x2c7d04(0x21b)][_0x2c7d04(0x171)](_0xd40a4b):_0x2ea7ae===_0x2c7d04(0x15d)&&this[_0x2c7d04(0x1fe)]?_0x5150b2[_0x2c7d04(0x1aa)]=this[_0x2c7d04(0x1fe)][_0x2c7d04(0x195)]['toString'][_0x2c7d04(0x171)](_0xd40a4b):!_0x1c7900[_0x2c7d04(0x211)]&&!(_0x2ea7ae===_0x2c7d04(0x165)||_0x2ea7ae===_0x2c7d04(0x1eb))&&(delete _0x5150b2['value'],_0x5150b2[_0x2c7d04(0x199)]=!0x0),_0x412eda&&(_0x5150b2[_0x2c7d04(0x180)]=!0x0),_0x1229b2=_0x1c7900[_0x2c7d04(0x214)][_0x2c7d04(0x1a4)],_0x1c7900[_0x2c7d04(0x214)][_0x2c7d04(0x1a4)]=_0x5150b2,this[_0x2c7d04(0x194)](_0x5150b2,_0x1c7900),_0x735244['length']){for(_0x5d8a16=0x0,_0x516b20=_0x735244[_0x2c7d04(0x1bc)];_0x5d8a16<_0x516b20;_0x5d8a16++)_0x735244[_0x5d8a16](_0x5d8a16);}_0x5d1e4b[_0x2c7d04(0x1bc)]&&(_0x5150b2[_0x2c7d04(0x162)]=_0x5d1e4b);}catch(_0x8c9894){_0x801e45(_0x8c9894,_0x5150b2,_0x1c7900);}return this[_0x2c7d04(0x169)](_0xd40a4b,_0x5150b2),this[_0x2c7d04(0x1c0)](_0x5150b2,_0x1c7900),_0x1c7900[_0x2c7d04(0x214)][_0x2c7d04(0x1a4)]=_0x1229b2,_0x1c7900[_0x2c7d04(0x16d)]--,_0x1c7900['autoExpand']=_0x879d98,_0x1c7900[_0x2c7d04(0x1ef)]&&_0x1c7900[_0x2c7d04(0x1a6)]['pop'](),_0x5150b2;}[_0x127735(0x1fc)](_0x2c57e2){var _0x507d77=_0x127735;return Object[_0x507d77(0x20a)]?Object[_0x507d77(0x20a)](_0x2c57e2):[];}[_0x127735(0x224)](_0x1ad1f2){var _0x3b3379=_0x127735;return!!(_0x1ad1f2&&_0x426d5f[_0x3b3379(0x1c5)]&&this[_0x3b3379(0x196)](_0x1ad1f2)===_0x3b3379(0x15e)&&_0x1ad1f2['forEach']);}[_0x127735(0x1c4)](_0x1a0a0f,_0x4a80b8,_0x4f64fe){var _0x5b8975=_0x127735;return _0x4f64fe['noFunctions']?typeof _0x1a0a0f[_0x4a80b8]==_0x5b8975(0x173):!0x1;}[_0x127735(0x1ec)](_0x5293e3){var _0x11728a=_0x127735,_0x161237='';return _0x161237=typeof _0x5293e3,_0x161237===_0x11728a(0x166)?this[_0x11728a(0x196)](_0x5293e3)===_0x11728a(0x160)?_0x161237=_0x11728a(0x1e6):this[_0x11728a(0x196)](_0x5293e3)==='[object\\x20Date]'?_0x161237='date':this[_0x11728a(0x196)](_0x5293e3)==='[object\\x20BigInt]'?_0x161237=_0x11728a(0x182):_0x5293e3===null?_0x161237=_0x11728a(0x165):_0x5293e3[_0x11728a(0x1a3)]&&(_0x161237=_0x5293e3[_0x11728a(0x1a3)][_0x11728a(0x1c9)]||_0x161237):_0x161237===_0x11728a(0x1eb)&&this[_0x11728a(0x221)]&&_0x5293e3 instanceof this[_0x11728a(0x221)]&&(_0x161237=_0x11728a(0x14c)),_0x161237;}[_0x127735(0x196)](_0x3d1064){var _0x413d1f=_0x127735;return Object[_0x413d1f(0x195)][_0x413d1f(0x1af)]['call'](_0x3d1064);}[_0x127735(0x1c3)](_0xafb5c4){var _0x10550d=_0x127735;return _0xafb5c4===_0x10550d(0x1e9)||_0xafb5c4==='string'||_0xafb5c4===_0x10550d(0x17e);}['_isPrimitiveWrapperType'](_0x429062){var _0x4b1258=_0x127735;return _0x429062==='Boolean'||_0x429062===_0x4b1258(0x204)||_0x429062==='Number';}[_0x127735(0x154)](_0x29134e,_0x42ac35,_0x39d890,_0x17251c,_0x46dbca,_0x983f3){var _0x5dd65a=this;return function(_0x44eb69){var _0x2ba888=_0x33b2,_0x2f66ac=_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x1a4)],_0x419caf=_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x149)],_0x327987=_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x1f7)];_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x1f7)]=_0x2f66ac,_0x46dbca['node'][_0x2ba888(0x149)]=typeof _0x17251c=='number'?_0x17251c:_0x44eb69,_0x29134e['push'](_0x5dd65a['_property'](_0x42ac35,_0x39d890,_0x17251c,_0x46dbca,_0x983f3)),_0x46dbca['node']['parent']=_0x327987,_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x149)]=_0x419caf;};}[_0x127735(0x14a)](_0x1079f0,_0x42ff3c,_0x28dcfc,_0x16872f,_0x459e0f,_0x3fca62,_0x350643){var _0x728dbf=_0x127735,_0x41f1a7=this;return _0x42ff3c['_p_'+_0x459e0f[_0x728dbf(0x1af)]()]=!0x0,function(_0x3677ae){var _0xecfed8=_0x728dbf,_0x4e9bfa=_0x3fca62[_0xecfed8(0x214)][_0xecfed8(0x1a4)],_0x29c59e=_0x3fca62[_0xecfed8(0x214)][_0xecfed8(0x149)],_0x1a70ed=_0x3fca62['node'][_0xecfed8(0x1f7)];_0x3fca62['node'][_0xecfed8(0x1f7)]=_0x4e9bfa,_0x3fca62['node'][_0xecfed8(0x149)]=_0x3677ae,_0x1079f0[_0xecfed8(0x172)](_0x41f1a7[_0xecfed8(0x1c1)](_0x28dcfc,_0x16872f,_0x459e0f,_0x3fca62,_0x350643)),_0x3fca62[_0xecfed8(0x214)][_0xecfed8(0x1f7)]=_0x1a70ed,_0x3fca62[_0xecfed8(0x214)]['index']=_0x29c59e;};}[_0x127735(0x1c1)](_0x4b6b39,_0x454239,_0x420ca1,_0x1d6dd6,_0xfdc1f2){var _0x49f5a4=_0x127735,_0x201907=this;_0xfdc1f2||(_0xfdc1f2=function(_0x2eda18,_0x3fd888){return _0x2eda18[_0x3fd888];});var _0x1994ac=_0x420ca1['toString'](),_0x3115be=_0x1d6dd6[_0x49f5a4(0x210)]||{},_0x576f77=_0x1d6dd6[_0x49f5a4(0x211)],_0x2806ba=_0x1d6dd6[_0x49f5a4(0x190)];try{var _0x4b28f8=this[_0x49f5a4(0x20d)](_0x4b6b39),_0x3b2384=_0x1994ac;_0x4b28f8&&_0x3b2384[0x0]==='\\x27'&&(_0x3b2384=_0x3b2384['substr'](0x1,_0x3b2384[_0x49f5a4(0x1bc)]-0x2));var _0x33cb5b=_0x1d6dd6[_0x49f5a4(0x210)]=_0x3115be[_0x49f5a4(0x15f)+_0x3b2384];_0x33cb5b&&(_0x1d6dd6[_0x49f5a4(0x211)]=_0x1d6dd6['depth']+0x1),_0x1d6dd6[_0x49f5a4(0x190)]=!!_0x33cb5b;var _0x5c26b9=typeof _0x420ca1==_0x49f5a4(0x15d),_0x37f8f1={'name':_0x5c26b9||_0x4b28f8?_0x1994ac:this[_0x49f5a4(0x153)](_0x1994ac)};if(_0x5c26b9&&(_0x37f8f1['symbol']=!0x0),!(_0x454239==='array'||_0x454239===_0x49f5a4(0x1b8))){var _0x8f25d1=this[_0x49f5a4(0x167)](_0x4b6b39,_0x420ca1);if(_0x8f25d1&&(_0x8f25d1[_0x49f5a4(0x1ee)]&&(_0x37f8f1[_0x49f5a4(0x147)]=!0x0),_0x8f25d1[_0x49f5a4(0x1c7)]&&!_0x33cb5b&&!_0x1d6dd6['resolveGetters']))return _0x37f8f1[_0x49f5a4(0x1f1)]=!0x0,this[_0x49f5a4(0x1f5)](_0x37f8f1,_0x1d6dd6),_0x37f8f1;}var _0x2cd47d;try{_0x2cd47d=_0xfdc1f2(_0x4b6b39,_0x420ca1);}catch(_0x12a02c){return _0x37f8f1={'name':_0x1994ac,'type':_0x49f5a4(0x21d),'error':_0x12a02c[_0x49f5a4(0x1a1)]},this[_0x49f5a4(0x1f5)](_0x37f8f1,_0x1d6dd6),_0x37f8f1;}var _0x592b34=this[_0x49f5a4(0x1ec)](_0x2cd47d),_0x3cc690=this['_isPrimitiveType'](_0x592b34);if(_0x37f8f1[_0x49f5a4(0x1ac)]=_0x592b34,_0x3cc690)this[_0x49f5a4(0x1f5)](_0x37f8f1,_0x1d6dd6,_0x2cd47d,function(){var _0x56f47a=_0x49f5a4;_0x37f8f1[_0x56f47a(0x1aa)]=_0x2cd47d[_0x56f47a(0x1c6)](),!_0x33cb5b&&_0x201907[_0x56f47a(0x145)](_0x592b34,_0x37f8f1,_0x1d6dd6,{});});else{var _0x4fc792=_0x1d6dd6[_0x49f5a4(0x1ef)]&&_0x1d6dd6[_0x49f5a4(0x16d)]<_0x1d6dd6[_0x49f5a4(0x179)]&&_0x1d6dd6[_0x49f5a4(0x1a6)]['indexOf'](_0x2cd47d)<0x0&&_0x592b34!==_0x49f5a4(0x173)&&_0x1d6dd6[_0x49f5a4(0x156)]<_0x1d6dd6['autoExpandLimit'];_0x4fc792||_0x1d6dd6[_0x49f5a4(0x16d)]<_0x576f77||_0x33cb5b?(this[_0x49f5a4(0x21e)](_0x37f8f1,_0x2cd47d,_0x1d6dd6,_0x33cb5b||{}),this['_additionalMetadata'](_0x2cd47d,_0x37f8f1)):this[_0x49f5a4(0x1f5)](_0x37f8f1,_0x1d6dd6,_0x2cd47d,function(){var _0x1b0be1=_0x49f5a4;_0x592b34===_0x1b0be1(0x165)||_0x592b34===_0x1b0be1(0x1eb)||(delete _0x37f8f1['value'],_0x37f8f1[_0x1b0be1(0x199)]=!0x0);});}return _0x37f8f1;}finally{_0x1d6dd6[_0x49f5a4(0x210)]=_0x3115be,_0x1d6dd6[_0x49f5a4(0x211)]=_0x576f77,_0x1d6dd6[_0x49f5a4(0x190)]=_0x2806ba;}}[_0x127735(0x145)](_0x46f5d8,_0x989294,_0x2e316b,_0x232707){var _0x211045=_0x127735,_0x448778=_0x232707[_0x211045(0x1a5)]||_0x2e316b['strLength'];if((_0x46f5d8===_0x211045(0x164)||_0x46f5d8===_0x211045(0x204))&&_0x989294[_0x211045(0x1aa)]){let _0xeb3bb5=_0x989294[_0x211045(0x1aa)]['length'];_0x2e316b[_0x211045(0x18d)]+=_0xeb3bb5,_0x2e316b[_0x211045(0x18d)]>_0x2e316b[_0x211045(0x174)]?(_0x989294[_0x211045(0x199)]='',delete _0x989294['value']):_0xeb3bb5>_0x448778&&(_0x989294[_0x211045(0x199)]=_0x989294[_0x211045(0x1aa)]['substr'](0x0,_0x448778),delete _0x989294['value']);}}[_0x127735(0x20d)](_0x28b7d0){var _0x8a1886=_0x127735;return!!(_0x28b7d0&&_0x426d5f['Map']&&this[_0x8a1886(0x196)](_0x28b7d0)===_0x8a1886(0x1bd)&&_0x28b7d0[_0x8a1886(0x1dd)]);}[_0x127735(0x153)](_0x1e10cc){var _0x4a2d80=_0x127735;if(_0x1e10cc[_0x4a2d80(0x208)](/^\\d+$/))return _0x1e10cc;var _0x342eca;try{_0x342eca=JSON[_0x4a2d80(0x1fa)](''+_0x1e10cc);}catch{_0x342eca='\\x22'+this[_0x4a2d80(0x196)](_0x1e10cc)+'\\x22';}return _0x342eca[_0x4a2d80(0x208)](/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)?_0x342eca=_0x342eca[_0x4a2d80(0x1a0)](0x1,_0x342eca[_0x4a2d80(0x1bc)]-0x2):_0x342eca=_0x342eca[_0x4a2d80(0x150)](/'/g,'\\x5c\\x27')[_0x4a2d80(0x150)](/\\\\\"/g,'\\x22')[_0x4a2d80(0x150)](/(^\"|\"$)/g,'\\x27'),_0x342eca;}[_0x127735(0x1f5)](_0x311141,_0x4fe874,_0x4b456e,_0x2a1f80){var _0x3c1657=_0x127735;this[_0x3c1657(0x194)](_0x311141,_0x4fe874),_0x2a1f80&&_0x2a1f80(),this[_0x3c1657(0x169)](_0x4b456e,_0x311141),this['_treeNodePropertiesAfterFullValue'](_0x311141,_0x4fe874);}[_0x127735(0x194)](_0x3fd70b,_0x2d8af9){var _0x36dcf4=_0x127735;this['_setNodeId'](_0x3fd70b,_0x2d8af9),this['_setNodeQueryPath'](_0x3fd70b,_0x2d8af9),this[_0x36dcf4(0x17d)](_0x3fd70b,_0x2d8af9),this[_0x36dcf4(0x1ae)](_0x3fd70b,_0x2d8af9);}['_setNodeId'](_0x4e3852,_0x5907e8){}['_setNodeQueryPath'](_0x1cc8b4,_0x26819b){}['_setNodeLabel'](_0x565ccf,_0x199a64){}[_0x127735(0x14f)](_0x120c63){var _0x2708e2=_0x127735;return _0x120c63===this[_0x2708e2(0x201)];}[_0x127735(0x1c0)](_0x2653c7,_0x2fe267){var _0x2e41b4=_0x127735;this[_0x2e41b4(0x1f0)](_0x2653c7,_0x2fe267),this[_0x2e41b4(0x1d4)](_0x2653c7),_0x2fe267[_0x2e41b4(0x14d)]&&this[_0x2e41b4(0x185)](_0x2653c7),this[_0x2e41b4(0x1e0)](_0x2653c7,_0x2fe267),this[_0x2e41b4(0x191)](_0x2653c7,_0x2fe267),this[_0x2e41b4(0x219)](_0x2653c7);}['_additionalMetadata'](_0xaa1402,_0x1d0e69){var _0x2b6da8=_0x127735;let _0x5790d5;try{_0x426d5f[_0x2b6da8(0x1df)]&&(_0x5790d5=_0x426d5f[_0x2b6da8(0x1df)]['error'],_0x426d5f['console'][_0x2b6da8(0x20c)]=function(){}),_0xaa1402&&typeof _0xaa1402[_0x2b6da8(0x1bc)]==_0x2b6da8(0x17e)&&(_0x1d0e69[_0x2b6da8(0x1bc)]=_0xaa1402['length']);}catch{}finally{_0x5790d5&&(_0x426d5f[_0x2b6da8(0x1df)][_0x2b6da8(0x20c)]=_0x5790d5);}if(_0x1d0e69['type']===_0x2b6da8(0x17e)||_0x1d0e69[_0x2b6da8(0x1ac)]==='Number'){if(isNaN(_0x1d0e69[_0x2b6da8(0x1aa)]))_0x1d0e69['nan']=!0x0,delete _0x1d0e69[_0x2b6da8(0x1aa)];else switch(_0x1d0e69[_0x2b6da8(0x1aa)]){case Number[_0x2b6da8(0x17c)]:_0x1d0e69[_0x2b6da8(0x1d9)]=!0x0,delete _0x1d0e69[_0x2b6da8(0x1aa)];break;case Number[_0x2b6da8(0x1a2)]:_0x1d0e69[_0x2b6da8(0x1cb)]=!0x0,delete _0x1d0e69['value'];break;case 0x0:this['_isNegativeZero'](_0x1d0e69['value'])&&(_0x1d0e69['negativeZero']=!0x0);break;}}else _0x1d0e69[_0x2b6da8(0x1ac)]===_0x2b6da8(0x173)&&typeof _0xaa1402[_0x2b6da8(0x1c9)]=='string'&&_0xaa1402[_0x2b6da8(0x1c9)]&&_0x1d0e69['name']&&_0xaa1402[_0x2b6da8(0x1c9)]!==_0x1d0e69[_0x2b6da8(0x1c9)]&&(_0x1d0e69['funcName']=_0xaa1402[_0x2b6da8(0x1c9)]);}[_0x127735(0x1be)](_0x5bf79f){var _0x1e0bf2=_0x127735;return 0x1/_0x5bf79f===Number[_0x1e0bf2(0x1a2)];}[_0x127735(0x185)](_0x9ec463){var _0x244642=_0x127735;!_0x9ec463['props']||!_0x9ec463[_0x244642(0x162)][_0x244642(0x1bc)]||_0x9ec463[_0x244642(0x1ac)]===_0x244642(0x1e6)||_0x9ec463[_0x244642(0x1ac)]===_0x244642(0x1db)||_0x9ec463['type']===_0x244642(0x1c5)||_0x9ec463[_0x244642(0x162)]['sort'](function(_0x4ea9e0,_0x35c323){var _0x4b5cb2=_0x244642,_0x2036f3=_0x4ea9e0[_0x4b5cb2(0x1c9)][_0x4b5cb2(0x202)](),_0xbf0e75=_0x35c323[_0x4b5cb2(0x1c9)][_0x4b5cb2(0x202)]();return _0x2036f3<_0xbf0e75?-0x1:_0x2036f3>_0xbf0e75?0x1:0x0;});}['_addFunctionsNode'](_0x571411,_0x51166f){var _0x144384=_0x127735;if(!(_0x51166f[_0x144384(0x187)]||!_0x571411[_0x144384(0x162)]||!_0x571411[_0x144384(0x162)]['length'])){for(var _0x15f381=[],_0x4b7e4c=[],_0x1ee8d9=0x0,_0x157d1f=_0x571411[_0x144384(0x162)]['length'];_0x1ee8d9<_0x157d1f;_0x1ee8d9++){var _0x5d11be=_0x571411[_0x144384(0x162)][_0x1ee8d9];_0x5d11be[_0x144384(0x1ac)]===_0x144384(0x173)?_0x15f381[_0x144384(0x172)](_0x5d11be):_0x4b7e4c[_0x144384(0x172)](_0x5d11be);}if(!(!_0x4b7e4c[_0x144384(0x1bc)]||_0x15f381['length']<=0x1)){_0x571411[_0x144384(0x162)]=_0x4b7e4c;var _0x43d31c={'functionsNode':!0x0,'props':_0x15f381};this['_setNodeId'](_0x43d31c,_0x51166f),this['_setNodeLabel'](_0x43d31c,_0x51166f),this[_0x144384(0x1d4)](_0x43d31c),this['_setNodePermissions'](_0x43d31c,_0x51166f),_0x43d31c['id']+='\\x20f',_0x571411['props'][_0x144384(0x216)](_0x43d31c);}}}[_0x127735(0x191)](_0x496a9a,_0xbeea77){}[_0x127735(0x1d4)](_0x22b022){}[_0x127735(0x20f)](_0x357473){var _0xe4a9d0=_0x127735;return Array['isArray'](_0x357473)||typeof _0x357473==_0xe4a9d0(0x166)&&this['_objectToString'](_0x357473)==='[object\\x20Array]';}[_0x127735(0x1ae)](_0x2f40e6,_0x40541c){}[_0x127735(0x219)](_0x45fcae){var _0x5eb338=_0x127735;delete _0x45fcae['_hasSymbolPropertyOnItsPath'],delete _0x45fcae['_hasSetOnItsPath'],delete _0x45fcae[_0x5eb338(0x226)];}[_0x127735(0x17d)](_0x2c8e98,_0x5d16e9){}}let _0x38fd35=new _0x2e0d3c(),_0x3ae2cc={'props':0x64,'elements':0x64,'strLength':0x400*0x32,'totalStrLength':0x400*0x32,'autoExpandLimit':0x1388,'autoExpandMaxDepth':0xa},_0x4e441={'props':0x5,'elements':0x5,'strLength':0x100,'totalStrLength':0x100*0x3,'autoExpandLimit':0x1e,'autoExpandMaxDepth':0x2};function _0xa713d7(_0x1d4bd9,_0x56700c,_0x5e35a2,_0xca5fba,_0x5cb9b2,_0x46ecb3){var _0xc9442c=_0x127735;let _0x1ad82b,_0x568f00;try{_0x568f00=_0x5b689d(),_0x1ad82b=_0x2dbbb7[_0x56700c],!_0x1ad82b||_0x568f00-_0x1ad82b['ts']>0x1f4&&_0x1ad82b[_0xc9442c(0x1ba)]&&_0x1ad82b[_0xc9442c(0x19a)]/_0x1ad82b[_0xc9442c(0x1ba)]<0x64?(_0x2dbbb7[_0x56700c]=_0x1ad82b={'count':0x0,'time':0x0,'ts':_0x568f00},_0x2dbbb7[_0xc9442c(0x18f)]={}):_0x568f00-_0x2dbbb7[_0xc9442c(0x18f)]['ts']>0x32&&_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x1ba)]&&_0x2dbbb7[_0xc9442c(0x18f)]['time']/_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x1ba)]<0x64&&(_0x2dbbb7[_0xc9442c(0x18f)]={});let _0x55cfc9=[],_0x841e56=_0x1ad82b[_0xc9442c(0x1bb)]||_0x2dbbb7['hits'][_0xc9442c(0x1bb)]?_0x4e441:_0x3ae2cc,_0x97e270=_0x3d4a42=>{var _0x974ae0=_0xc9442c;let _0x533cf8={};return _0x533cf8[_0x974ae0(0x162)]=_0x3d4a42[_0x974ae0(0x162)],_0x533cf8[_0x974ae0(0x1b6)]=_0x3d4a42['elements'],_0x533cf8['strLength']=_0x3d4a42[_0x974ae0(0x1a5)],_0x533cf8['totalStrLength']=_0x3d4a42[_0x974ae0(0x174)],_0x533cf8[_0x974ae0(0x217)]=_0x3d4a42[_0x974ae0(0x217)],_0x533cf8[_0x974ae0(0x179)]=_0x3d4a42[_0x974ae0(0x179)],_0x533cf8[_0x974ae0(0x14d)]=!0x1,_0x533cf8[_0x974ae0(0x187)]=!_0x58bd93,_0x533cf8[_0x974ae0(0x211)]=0x1,_0x533cf8[_0x974ae0(0x16d)]=0x0,_0x533cf8[_0x974ae0(0x146)]=_0x974ae0(0x1e3),_0x533cf8[_0x974ae0(0x1a9)]='root_exp',_0x533cf8[_0x974ae0(0x1ef)]=!0x0,_0x533cf8[_0x974ae0(0x1a6)]=[],_0x533cf8[_0x974ae0(0x156)]=0x0,_0x533cf8['resolveGetters']=!0x0,_0x533cf8[_0x974ae0(0x18d)]=0x0,_0x533cf8[_0x974ae0(0x214)]={'current':void 0x0,'parent':void 0x0,'index':0x0},_0x533cf8;};for(var _0x46b7b6=0x0;_0x46b7b6<_0x5cb9b2[_0xc9442c(0x1bc)];_0x46b7b6++)_0x55cfc9[_0xc9442c(0x172)](_0x38fd35[_0xc9442c(0x21e)]({'timeNode':_0x1d4bd9===_0xc9442c(0x19a)||void 0x0},_0x5cb9b2[_0x46b7b6],_0x97e270(_0x841e56),{}));if(_0x1d4bd9===_0xc9442c(0x14b)||_0x1d4bd9===_0xc9442c(0x20c)){let _0x15fdf3=Error[_0xc9442c(0x21c)];try{Error['stackTraceLimit']=0x1/0x0,_0x55cfc9[_0xc9442c(0x172)](_0x38fd35[_0xc9442c(0x21e)]({'stackNode':!0x0},new Error()[_0xc9442c(0x1e4)],_0x97e270(_0x841e56),{'strLength':0x1/0x0}));}finally{Error[_0xc9442c(0x21c)]=_0x15fdf3;}}return{'method':'log','version':_0x2efb32,'args':[{'ts':_0x5e35a2,'session':_0xca5fba,'args':_0x55cfc9,'id':_0x56700c,'context':_0x46ecb3}]};}catch(_0x9d3ef5){return{'method':_0xc9442c(0x168),'version':_0x2efb32,'args':[{'ts':_0x5e35a2,'session':_0xca5fba,'args':[{'type':_0xc9442c(0x21d),'error':_0x9d3ef5&&_0x9d3ef5[_0xc9442c(0x1a1)]}],'id':_0x56700c,'context':_0x46ecb3}]};}finally{try{if(_0x1ad82b&&_0x568f00){let _0x38338e=_0x5b689d();_0x1ad82b['count']++,_0x1ad82b['time']+=_0x232d0d(_0x568f00,_0x38338e),_0x1ad82b['ts']=_0x38338e,_0x2dbbb7['hits']['count']++,_0x2dbbb7['hits'][_0xc9442c(0x19a)]+=_0x232d0d(_0x568f00,_0x38338e),_0x2dbbb7[_0xc9442c(0x18f)]['ts']=_0x38338e,(_0x1ad82b['count']>0x32||_0x1ad82b[_0xc9442c(0x19a)]>0x64)&&(_0x1ad82b[_0xc9442c(0x1bb)]=!0x0),(_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x1ba)]>0x3e8||_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x19a)]>0x12c)&&(_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x1bb)]=!0x0);}}catch{}}}return _0xa713d7;}((_0x90c37a,_0x1d748d,_0x27f184,_0x1c3e41,_0x1752b9,_0x15c4be,_0x43ab6c,_0x5e0357,_0x38586c,_0x13e9ae,_0x8982c1)=>{var _0x593112=_0x31e486;if(_0x90c37a['_console_ninja'])return _0x90c37a[_0x593112(0x223)];if(!H(_0x90c37a,_0x5e0357,_0x1752b9))return _0x90c37a[_0x593112(0x223)]={'consoleLog':()=>{},'consoleTrace':()=>{},'consoleTime':()=>{},'consoleTimeEnd':()=>{},'autoLog':()=>{},'autoLogMany':()=>{},'autoTraceMany':()=>{},'coverage':()=>{},'autoTrace':()=>{},'autoTime':()=>{},'autoTimeEnd':()=>{}},_0x90c37a[_0x593112(0x223)];let _0x4097e6=B(_0x90c37a),_0x185aba=_0x4097e6['elapsed'],_0x28ef1c=_0x4097e6[_0x593112(0x177)],_0x34e4c3=_0x4097e6[_0x593112(0x22b)],_0x443c59={'hits':{},'ts':{}},_0x55abcc=X(_0x90c37a,_0x38586c,_0x443c59,_0x15c4be),_0xa8e15=_0x4cf894=>{_0x443c59['ts'][_0x4cf894]=_0x28ef1c();},_0x1fb3f6=(_0x5264c3,_0x5bc1dc)=>{var _0x303a3d=_0x593112;let _0x2b5f42=_0x443c59['ts'][_0x5bc1dc];if(delete _0x443c59['ts'][_0x5bc1dc],_0x2b5f42){let _0x227a4=_0x185aba(_0x2b5f42,_0x28ef1c());_0x4e158e(_0x55abcc(_0x303a3d(0x19a),_0x5264c3,_0x34e4c3(),_0x184b48,[_0x227a4],_0x5bc1dc));}},_0x3d7fa1=_0x3c5a62=>{var _0x47af33=_0x593112,_0x3ee072;return _0x1752b9===_0x47af33(0x22c)&&_0x90c37a['origin']&&((_0x3ee072=_0x3c5a62==null?void 0x0:_0x3c5a62['args'])==null?void 0x0:_0x3ee072[_0x47af33(0x1bc)])&&(_0x3c5a62['args'][0x0][_0x47af33(0x1d0)]=_0x90c37a[_0x47af33(0x1d0)]),_0x3c5a62;};_0x90c37a['_console_ninja']={'consoleLog':(_0x5a352e,_0x4835da)=>{var _0x454c01=_0x593112;_0x90c37a[_0x454c01(0x1df)][_0x454c01(0x168)][_0x454c01(0x1c9)]!==_0x454c01(0x19f)&&_0x4e158e(_0x55abcc(_0x454c01(0x168),_0x5a352e,_0x34e4c3(),_0x184b48,_0x4835da));},'consoleTrace':(_0x2d4513,_0x4e7919)=>{var _0x1df99f=_0x593112,_0x1c0c58,_0x151e7a;_0x90c37a[_0x1df99f(0x1df)][_0x1df99f(0x168)][_0x1df99f(0x1c9)]!=='disabledTrace'&&((_0x151e7a=(_0x1c0c58=_0x90c37a['process'])==null?void 0x0:_0x1c0c58[_0x1df99f(0x152)])!=null&&_0x151e7a[_0x1df99f(0x214)]&&(_0x90c37a[_0x1df99f(0x18e)]=!0x0),_0x4e158e(_0x3d7fa1(_0x55abcc(_0x1df99f(0x14b),_0x2d4513,_0x34e4c3(),_0x184b48,_0x4e7919))));},'consoleError':(_0x210567,_0x30a025)=>{var _0x3d6cfc=_0x593112;_0x90c37a[_0x3d6cfc(0x18e)]=!0x0,_0x4e158e(_0x3d7fa1(_0x55abcc('error',_0x210567,_0x34e4c3(),_0x184b48,_0x30a025)));},'consoleTime':_0x18b8d9=>{_0xa8e15(_0x18b8d9);},'consoleTimeEnd':(_0x3cf778,_0x592776)=>{_0x1fb3f6(_0x592776,_0x3cf778);},'autoLog':(_0x2ef76f,_0x399160)=>{var _0x49b3a5=_0x593112;_0x4e158e(_0x55abcc(_0x49b3a5(0x168),_0x399160,_0x34e4c3(),_0x184b48,[_0x2ef76f]));},'autoLogMany':(_0x4b08cb,_0x4e7de4)=>{var _0x18584b=_0x593112;_0x4e158e(_0x55abcc(_0x18584b(0x168),_0x4b08cb,_0x34e4c3(),_0x184b48,_0x4e7de4));},'autoTrace':(_0x3b69f0,_0x1d7a19)=>{var _0x37ed25=_0x593112;_0x4e158e(_0x3d7fa1(_0x55abcc(_0x37ed25(0x14b),_0x1d7a19,_0x34e4c3(),_0x184b48,[_0x3b69f0])));},'autoTraceMany':(_0x479c34,_0x19a2ab)=>{_0x4e158e(_0x3d7fa1(_0x55abcc('trace',_0x479c34,_0x34e4c3(),_0x184b48,_0x19a2ab)));},'autoTime':(_0x37f803,_0x171c24,_0x427588)=>{_0xa8e15(_0x427588);},'autoTimeEnd':(_0xae47fc,_0x2a9042,_0x3be603)=>{_0x1fb3f6(_0x2a9042,_0x3be603);},'coverage':_0x39e775=>{_0x4e158e({'method':'coverage','version':_0x15c4be,'args':[{'id':_0x39e775}]});}};let _0x4e158e=q(_0x90c37a,_0x1d748d,_0x27f184,_0x1c3e41,_0x1752b9,_0x13e9ae,_0x8982c1),_0x184b48=_0x90c37a[_0x593112(0x176)];return _0x90c37a[_0x593112(0x223)];})(globalThis,'127.0.0.1',_0x31e486(0x1b2),_0x31e486(0x203),_0x31e486(0x1d7),_0x31e486(0x207),'1737718497303',_0x31e486(0x222),_0x31e486(0x1b7),'',_0x31e486(0x151));"); - } catch (e) {} -} -; /* istanbul ignore next */ -function oo_oo(i) { - for (var _len = arguments.length, v = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - v[_key - 1] = arguments[_key]; - } - try { - oo_cm().consoleLog(i, v); - } catch (e) {} - return v; -} -; -oo_oo; /* istanbul ignore next */ -function oo_tr(i) { - for (var _len2 = arguments.length, v = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { - v[_key2 - 1] = arguments[_key2]; - } - try { - oo_cm().consoleTrace(i, v); - } catch (e) {} - return v; -} -; -oo_tr; /* istanbul ignore next */ -function oo_tx(i) { - for (var _len3 = arguments.length, v = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { - v[_key3 - 1] = arguments[_key3]; - } - try { - oo_cm().consoleError(i, v); - } catch (e) {} - return v; -} -; -oo_tx; /* istanbul ignore next */ -function oo_ts(v) { - try { - oo_cm().consoleTime(v); - } catch (e) {} - return v; -} -; -oo_ts; /* istanbul ignore next */ -function oo_te(v, i) { - try { - oo_cm().consoleTimeEnd(v, i); - } catch (e) {} - return v; -} -; -oo_te; /*eslint unicorn/no-abusive-eslint-disable:,eslint-comments/disable-enable-pair:,eslint-comments/no-unlimited-disable:,eslint-comments/no-aggregating-enable:,eslint-comments/no-duplicate-disable:,eslint-comments/no-unused-disable:,eslint-comments/no-unused-enable:,*/ /***/ }), @@ -1293,10 +1228,8 @@ function escapeHtml(unsafe) { } }); (0, jquery_1["default"])(document).on('click', '.help', function (event) { - var _console; event.stopPropagation(); - /* eslint-disable */ - (_console = console).log.apply(_console, _toConsumableArray(oo_oo("1685920010_844_2_844_22_4", 'Hello'))); + console.log('Hello'); (0, jquery_1["default"])('.help__text').removeAttr('style'); var helpText = (0, jquery_1["default"])(this).find('.help__text'); if (helpText.length > 0) { @@ -1337,63 +1270,6 @@ function closeHelpText(helpText) { * Help Text Open Close Handlers End * */ -/* istanbul ignore next */ /* c8 ignore start */ /* eslint-disable */ -; -function oo_cm() { - try { - return (0, eval)("globalThis._console_ninja") || (0, eval)("/* https://github.com/wallabyjs/console-ninja#how-does-it-work */'use strict';var _0x31e486=_0x33b2;function _0x33b2(_0x2d1615,_0x29ccb4){var _0x34e9f3=_0x34e9();return _0x33b2=function(_0x33b23b,_0x393a74){_0x33b23b=_0x33b23b-0x145;var _0x41272d=_0x34e9f3[_0x33b23b];return _0x41272d;},_0x33b2(_0x2d1615,_0x29ccb4);}function _0x34e9(){var _0x1704f2=['expId','setter','nodeModules','index','_addObjectProperty','trace','HTMLAllCollection','sortProps','date','_isUndefined','replace','1','versions','_propertyName','_addProperty','_disposeWebsocket','autoExpandPropertyCount','_inNextEdge','logger\\x20failed\\x20to\\x20connect\\x20to\\x20host','slice','location','defineProperty','_keyStrRegExp','symbol','[object\\x20Set]','_p_','[object\\x20Array]','process','props','_sendErrorMessage','string','null','object','_getOwnPropertyDescriptor','log','_additionalMetadata','bind','performance','2910NyVCQD','level','includes','elapsed','_connectToHostNow','call','push','function','totalStrLength','hrtime','_console_ninja_session','timeStamp','fromCharCode','autoExpandMaxDepth','ws://','_numberRegExp','POSITIVE_INFINITY','_setNodeExpressionPath','number','join','cappedProps','onmessage','bigint','_isPrimitiveWrapperType','then','_sortProps','env','noFunctions','_quotedRegExp','logger\\x20failed\\x20to\\x20connect\\x20to\\x20host,\\x20see\\x20','concat','endsWith','perf_hooks','allStrLength','_ninjaIgnoreNextError','hits','isExpressionToEvaluate','_addLoadNode','astro','_socket','_treeNodePropertiesBeforeFullValue','prototype','_objectToString','_ws','8374478Ptcajj','capped','time','81460gnMsaC','Console\\x20Ninja\\x20failed\\x20to\\x20send\\x20logs,\\x20refreshing\\x20the\\x20page\\x20may\\x20help;\\x20also\\x20see\\x20','test','_webSocketErrorDocsLink','disabledLog','substr','message','NEGATIVE_INFINITY','constructor','current','strLength','autoExpandPreviousObjects','2695880zzbxhX','url','rootExpression','value','method','type','onerror','_setNodePermissions','toString','__es'+'Module','path','33453','_maxConnectAttemptCount','_WebSocketClass','1296EpmMlu','elements','','Error','_p_length','count','reduceLimits','length','[object\\x20Map]','_isNegativeZero','_getOwnPropertyNames','_treeNodePropertiesAfterFullValue','_property','default','_isPrimitiveType','_blacklistedProperty','Set','valueOf','get','pathToFileURL','name','Console\\x20Ninja\\x20failed\\x20to\\x20send\\x20logs,\\x20restarting\\x20the\\x20process\\x20may\\x20help;\\x20also\\x20see\\x20','negativeInfinity','enumerable','cappedElements','\\x20server','Symbol','origin','onclose','readyState','warn','_setNodeExpandableState','catch','close','webpack','host','positiveInfinity','_connectAttemptCount','Map','_dateToString','forEach','onopen','console','_addFunctionsNode','ws/index.js','getWebSocketClass','root_exp_id','stack','_p_name','array','_attemptToReconnectShortly','11622umfwXy','boolean','42656kjgZJZ','undefined','_type','toUpperCase','set','autoExpand','_setNodeLabel','getter','_allowedToConnectOnSend','map','_inBrowser','_processTreeNodeResult','_connected','parent','parse','args','stringify','data','_getOwnPropertySymbols','unref','_Symbol','NEXT_RUNTIME','hostname','_undefined','toLowerCase',\"/home/fluffy/.vscode/extensions/wallabyjs.console-ninja-1.0.382/node_modules\",'String','RegExp','_WebSocket','1.0.0','match','_connecting','getOwnPropertySymbols','global','error','_isMap','1981581WOiCXu','_isArray','expressionsToEvaluate','depth','eventReceivedCallback','_allowedToSend','node','dockerizedApp','unshift','autoExpandLimit','getOwnPropertyNames','_cleanNode','_reconnectTimeout','_regExpToString','stackTraceLimit','unknown','serialize','edge','port','_HTMLAllCollection',[\"localhost\",\"127.0.0.1\",\"example.cypress.io\",\"fluffy\",\"192.168.10.176\"],'_console_ninja','_isSet','remix','_hasMapOnItsPath','see\\x20https://tinyurl.com/2vt8jxzw\\x20for\\x20more\\x20info.','\\x20browser','failed\\x20to\\x20find\\x20and\\x20load\\x20WebSocket','some','now','next.js','_consoleNinjaAllowedToStart','574600opaWqz','send','_capIfString'];_0x34e9=function(){return _0x1704f2;};return _0x34e9();}(function(_0x49e719,_0x2b4bc8){var _0xec630c=_0x33b2,_0x51f3c2=_0x49e719();while(!![]){try{var _0x3bc92c=parseInt(_0xec630c(0x19b))/0x1+-parseInt(_0xec630c(0x22e))/0x2+parseInt(_0xec630c(0x20e))/0x3+-parseInt(_0xec630c(0x1a7))/0x4+-parseInt(_0xec630c(0x16c))/0x5*(parseInt(_0xec630c(0x1e8))/0x6)+parseInt(_0xec630c(0x198))/0x7+parseInt(_0xec630c(0x1ea))/0x8*(parseInt(_0xec630c(0x1b5))/0x9);if(_0x3bc92c===_0x2b4bc8)break;else _0x51f3c2['push'](_0x51f3c2['shift']());}catch(_0x22869e){_0x51f3c2['push'](_0x51f3c2['shift']());}}}(_0x34e9,0x96c49));var K=Object['create'],Q=Object[_0x31e486(0x15b)],G=Object['getOwnPropertyDescriptor'],ee=Object[_0x31e486(0x218)],te=Object['getPrototypeOf'],ne=Object['prototype']['hasOwnProperty'],re=(_0x289cf0,_0x17323c,_0x12d63c,_0x1e9b6d)=>{var _0x3742da=_0x31e486;if(_0x17323c&&typeof _0x17323c==_0x3742da(0x166)||typeof _0x17323c==_0x3742da(0x173)){for(let _0x30c8e9 of ee(_0x17323c))!ne[_0x3742da(0x171)](_0x289cf0,_0x30c8e9)&&_0x30c8e9!==_0x12d63c&&Q(_0x289cf0,_0x30c8e9,{'get':()=>_0x17323c[_0x30c8e9],'enumerable':!(_0x1e9b6d=G(_0x17323c,_0x30c8e9))||_0x1e9b6d[_0x3742da(0x1cc)]});}return _0x289cf0;},V=(_0x4d43b3,_0x28c699,_0x3e4ebc)=>(_0x3e4ebc=_0x4d43b3!=null?K(te(_0x4d43b3)):{},re(_0x28c699||!_0x4d43b3||!_0x4d43b3[_0x31e486(0x1b0)]?Q(_0x3e4ebc,_0x31e486(0x1c2),{'value':_0x4d43b3,'enumerable':!0x0}):_0x3e4ebc,_0x4d43b3)),Z=class{constructor(_0x190aa8,_0x48b519,_0x1f1ddd,_0x2a49f8,_0xdd448a,_0x26baee){var _0xcd3931=_0x31e486,_0x2911c5,_0x19538c,_0x3e7b24,_0x170571;this['global']=_0x190aa8,this['host']=_0x48b519,this[_0xcd3931(0x220)]=_0x1f1ddd,this[_0xcd3931(0x148)]=_0x2a49f8,this['dockerizedApp']=_0xdd448a,this['eventReceivedCallback']=_0x26baee,this['_allowedToSend']=!0x0,this['_allowedToConnectOnSend']=!0x0,this['_connected']=!0x1,this[_0xcd3931(0x209)]=!0x1,this[_0xcd3931(0x157)]=((_0x19538c=(_0x2911c5=_0x190aa8['process'])==null?void 0x0:_0x2911c5['env'])==null?void 0x0:_0x19538c['NEXT_RUNTIME'])==='edge',this[_0xcd3931(0x1f4)]=!((_0x170571=(_0x3e7b24=this[_0xcd3931(0x20b)][_0xcd3931(0x161)])==null?void 0x0:_0x3e7b24[_0xcd3931(0x152)])!=null&&_0x170571[_0xcd3931(0x214)])&&!this[_0xcd3931(0x157)],this[_0xcd3931(0x1b4)]=null,this[_0xcd3931(0x1da)]=0x0,this[_0xcd3931(0x1b3)]=0x14,this['_webSocketErrorDocsLink']='https://tinyurl.com/37x8b79t',this[_0xcd3931(0x163)]=(this[_0xcd3931(0x1f4)]?_0xcd3931(0x19c):_0xcd3931(0x1ca))+this[_0xcd3931(0x19e)];}async[_0x31e486(0x1e2)](){var _0x3409a9=_0x31e486,_0x2b3f86,_0x448030;if(this[_0x3409a9(0x1b4)])return this[_0x3409a9(0x1b4)];let _0x528636;if(this['_inBrowser']||this[_0x3409a9(0x157)])_0x528636=this[_0x3409a9(0x20b)]['WebSocket'];else{if((_0x2b3f86=this[_0x3409a9(0x20b)]['process'])!=null&&_0x2b3f86[_0x3409a9(0x206)])_0x528636=(_0x448030=this['global']['process'])==null?void 0x0:_0x448030[_0x3409a9(0x206)];else try{let _0x1088b4=await import(_0x3409a9(0x1b1));_0x528636=(await import((await import(_0x3409a9(0x1a8)))[_0x3409a9(0x1c8)](_0x1088b4[_0x3409a9(0x17f)](this[_0x3409a9(0x148)],_0x3409a9(0x1e1)))[_0x3409a9(0x1af)]()))['default'];}catch{try{_0x528636=require(require('path')[_0x3409a9(0x17f)](this['nodeModules'],'ws'));}catch{throw new Error(_0x3409a9(0x229));}}}return this[_0x3409a9(0x1b4)]=_0x528636,_0x528636;}[_0x31e486(0x170)](){var _0x29a825=_0x31e486;this['_connecting']||this['_connected']||this[_0x29a825(0x1da)]>=this[_0x29a825(0x1b3)]||(this[_0x29a825(0x1f2)]=!0x1,this[_0x29a825(0x209)]=!0x0,this[_0x29a825(0x1da)]++,this[_0x29a825(0x197)]=new Promise((_0x1f2c48,_0x5b02f8)=>{var _0x413ca9=_0x29a825;this[_0x413ca9(0x1e2)]()[_0x413ca9(0x184)](_0x4e9fb8=>{var _0x231fd9=_0x413ca9;let _0x15ba8a=new _0x4e9fb8(_0x231fd9(0x17a)+(!this['_inBrowser']&&this[_0x231fd9(0x215)]?'gateway.docker.internal':this[_0x231fd9(0x1d8)])+':'+this[_0x231fd9(0x220)]);_0x15ba8a['onerror']=()=>{var _0x48d418=_0x231fd9;this[_0x48d418(0x213)]=!0x1,this[_0x48d418(0x155)](_0x15ba8a),this[_0x48d418(0x1e7)](),_0x5b02f8(new Error('logger\\x20websocket\\x20error'));},_0x15ba8a['onopen']=()=>{var _0x3ed611=_0x231fd9;this[_0x3ed611(0x1f4)]||_0x15ba8a[_0x3ed611(0x193)]&&_0x15ba8a['_socket'][_0x3ed611(0x1fd)]&&_0x15ba8a[_0x3ed611(0x193)][_0x3ed611(0x1fd)](),_0x1f2c48(_0x15ba8a);},_0x15ba8a[_0x231fd9(0x1d1)]=()=>{var _0x869626=_0x231fd9;this[_0x869626(0x1f2)]=!0x0,this[_0x869626(0x155)](_0x15ba8a),this[_0x869626(0x1e7)]();},_0x15ba8a[_0x231fd9(0x181)]=_0x3d8ace=>{var _0x1223ba=_0x231fd9;try{if(!(_0x3d8ace!=null&&_0x3d8ace['data'])||!this[_0x1223ba(0x212)])return;let _0x52f38=JSON[_0x1223ba(0x1f8)](_0x3d8ace[_0x1223ba(0x1fb)]);this['eventReceivedCallback'](_0x52f38[_0x1223ba(0x1ab)],_0x52f38[_0x1223ba(0x1f9)],this[_0x1223ba(0x20b)],this[_0x1223ba(0x1f4)]);}catch{}};})['then'](_0x213740=>(this[_0x413ca9(0x1f6)]=!0x0,this[_0x413ca9(0x209)]=!0x1,this[_0x413ca9(0x1f2)]=!0x1,this['_allowedToSend']=!0x0,this[_0x413ca9(0x1da)]=0x0,_0x213740))[_0x413ca9(0x1d5)](_0x244876=>(this[_0x413ca9(0x1f6)]=!0x1,this[_0x413ca9(0x209)]=!0x1,console[_0x413ca9(0x1d3)](_0x413ca9(0x189)+this[_0x413ca9(0x19e)]),_0x5b02f8(new Error('failed\\x20to\\x20connect\\x20to\\x20host:\\x20'+(_0x244876&&_0x244876['message'])))));}));}[_0x31e486(0x155)](_0x38cd1f){var _0x226baf=_0x31e486;this[_0x226baf(0x1f6)]=!0x1,this[_0x226baf(0x209)]=!0x1;try{_0x38cd1f[_0x226baf(0x1d1)]=null,_0x38cd1f[_0x226baf(0x1ad)]=null,_0x38cd1f[_0x226baf(0x1de)]=null;}catch{}try{_0x38cd1f[_0x226baf(0x1d2)]<0x2&&_0x38cd1f[_0x226baf(0x1d6)]();}catch{}}[_0x31e486(0x1e7)](){var _0x535e73=_0x31e486;clearTimeout(this[_0x535e73(0x21a)]),!(this['_connectAttemptCount']>=this['_maxConnectAttemptCount'])&&(this['_reconnectTimeout']=setTimeout(()=>{var _0x465142=_0x535e73,_0x14cd5a;this[_0x465142(0x1f6)]||this[_0x465142(0x209)]||(this['_connectToHostNow'](),(_0x14cd5a=this[_0x465142(0x197)])==null||_0x14cd5a['catch'](()=>this[_0x465142(0x1e7)]()));},0x1f4),this[_0x535e73(0x21a)][_0x535e73(0x1fd)]&&this[_0x535e73(0x21a)]['unref']());}async[_0x31e486(0x22f)](_0x5f27a2){var _0x3429a4=_0x31e486;try{if(!this[_0x3429a4(0x213)])return;this[_0x3429a4(0x1f2)]&&this[_0x3429a4(0x170)](),(await this['_ws'])[_0x3429a4(0x22f)](JSON[_0x3429a4(0x1fa)](_0x5f27a2));}catch(_0x5afec6){console[_0x3429a4(0x1d3)](this[_0x3429a4(0x163)]+':\\x20'+(_0x5afec6&&_0x5afec6[_0x3429a4(0x1a1)])),this['_allowedToSend']=!0x1,this[_0x3429a4(0x1e7)]();}}};function q(_0x42986d,_0x203a38,_0x30927a,_0x1b9594,_0x250bbe,_0x2e256f,_0x301b22,_0x3f7c26=ie){var _0x373131=_0x31e486;let _0x3d094e=_0x30927a['split'](',')[_0x373131(0x1f3)](_0x534546=>{var _0x53f651=_0x373131,_0x469434,_0x195f23,_0x4bea5f,_0x1442e8;try{if(!_0x42986d[_0x53f651(0x176)]){let _0x2303eb=((_0x195f23=(_0x469434=_0x42986d[_0x53f651(0x161)])==null?void 0x0:_0x469434[_0x53f651(0x152)])==null?void 0x0:_0x195f23[_0x53f651(0x214)])||((_0x1442e8=(_0x4bea5f=_0x42986d[_0x53f651(0x161)])==null?void 0x0:_0x4bea5f[_0x53f651(0x186)])==null?void 0x0:_0x1442e8[_0x53f651(0x1ff)])===_0x53f651(0x21f);(_0x250bbe===_0x53f651(0x22c)||_0x250bbe===_0x53f651(0x225)||_0x250bbe===_0x53f651(0x192)||_0x250bbe==='angular')&&(_0x250bbe+=_0x2303eb?_0x53f651(0x1ce):_0x53f651(0x228)),_0x42986d['_console_ninja_session']={'id':+new Date(),'tool':_0x250bbe},_0x301b22&&_0x250bbe&&!_0x2303eb&&console[_0x53f651(0x168)]('%c\\x20Console\\x20Ninja\\x20extension\\x20is\\x20connected\\x20to\\x20'+(_0x250bbe['charAt'](0x0)[_0x53f651(0x1ed)]()+_0x250bbe[_0x53f651(0x1a0)](0x1))+',','background:\\x20rgb(30,30,30);\\x20color:\\x20rgb(255,213,92)',_0x53f651(0x227));}let _0x273b64=new Z(_0x42986d,_0x203a38,_0x534546,_0x1b9594,_0x2e256f,_0x3f7c26);return _0x273b64[_0x53f651(0x22f)][_0x53f651(0x16a)](_0x273b64);}catch(_0x2034d6){return console[_0x53f651(0x1d3)](_0x53f651(0x158),_0x2034d6&&_0x2034d6[_0x53f651(0x1a1)]),()=>{};}});return _0x4eefa5=>_0x3d094e[_0x373131(0x1dd)](_0x3da91a=>_0x3da91a(_0x4eefa5));}function ie(_0x1c7751,_0x222cd0,_0x1ee3e2,_0x52f6a9){var _0x486680=_0x31e486;_0x52f6a9&&_0x1c7751==='reload'&&_0x1ee3e2[_0x486680(0x15a)]['reload']();}function B(_0xf6208d){var _0x5201ef=_0x31e486,_0x4c8cf9,_0x3c74de;let _0x3a81a3=function(_0x4f56d7,_0x47aa48){return _0x47aa48-_0x4f56d7;},_0x4e3665;if(_0xf6208d['performance'])_0x4e3665=function(){var _0x12052f=_0x33b2;return _0xf6208d[_0x12052f(0x16b)][_0x12052f(0x22b)]();};else{if(_0xf6208d[_0x5201ef(0x161)]&&_0xf6208d['process'][_0x5201ef(0x175)]&&((_0x3c74de=(_0x4c8cf9=_0xf6208d[_0x5201ef(0x161)])==null?void 0x0:_0x4c8cf9[_0x5201ef(0x186)])==null?void 0x0:_0x3c74de[_0x5201ef(0x1ff)])!=='edge')_0x4e3665=function(){var _0x54c5a0=_0x5201ef;return _0xf6208d[_0x54c5a0(0x161)][_0x54c5a0(0x175)]();},_0x3a81a3=function(_0x469bab,_0x19b5b4){return 0x3e8*(_0x19b5b4[0x0]-_0x469bab[0x0])+(_0x19b5b4[0x1]-_0x469bab[0x1])/0xf4240;};else try{let {performance:_0x420be7}=require(_0x5201ef(0x18c));_0x4e3665=function(){return _0x420be7['now']();};}catch{_0x4e3665=function(){return+new Date();};}}return{'elapsed':_0x3a81a3,'timeStamp':_0x4e3665,'now':()=>Date['now']()};}function H(_0x1601f6,_0x459cd1,_0x47b2b0){var _0x43a750=_0x31e486,_0x2008dc,_0x40416f,_0x190def,_0x5bbf24,_0x55aa85;if(_0x1601f6[_0x43a750(0x22d)]!==void 0x0)return _0x1601f6[_0x43a750(0x22d)];let _0x20dc94=((_0x40416f=(_0x2008dc=_0x1601f6[_0x43a750(0x161)])==null?void 0x0:_0x2008dc[_0x43a750(0x152)])==null?void 0x0:_0x40416f['node'])||((_0x5bbf24=(_0x190def=_0x1601f6[_0x43a750(0x161)])==null?void 0x0:_0x190def[_0x43a750(0x186)])==null?void 0x0:_0x5bbf24[_0x43a750(0x1ff)])==='edge';function _0xf314cc(_0x3a1e98){var _0x2be344=_0x43a750;if(_0x3a1e98['startsWith']('/')&&_0x3a1e98[_0x2be344(0x18b)]('/')){let _0x14c90c=new RegExp(_0x3a1e98[_0x2be344(0x159)](0x1,-0x1));return _0x5028b2=>_0x14c90c[_0x2be344(0x19d)](_0x5028b2);}else{if(_0x3a1e98[_0x2be344(0x16e)]('*')||_0x3a1e98[_0x2be344(0x16e)]('?')){let _0x2867ee=new RegExp('^'+_0x3a1e98[_0x2be344(0x150)](/\\./g,String[_0x2be344(0x178)](0x5c)+'.')['replace'](/\\*/g,'.*')[_0x2be344(0x150)](/\\?/g,'.')+String[_0x2be344(0x178)](0x24));return _0xa0716c=>_0x2867ee['test'](_0xa0716c);}else return _0x4ba06a=>_0x4ba06a===_0x3a1e98;}}let _0x53c890=_0x459cd1['map'](_0xf314cc);return _0x1601f6[_0x43a750(0x22d)]=_0x20dc94||!_0x459cd1,!_0x1601f6['_consoleNinjaAllowedToStart']&&((_0x55aa85=_0x1601f6['location'])==null?void 0x0:_0x55aa85[_0x43a750(0x200)])&&(_0x1601f6[_0x43a750(0x22d)]=_0x53c890[_0x43a750(0x22a)](_0x416625=>_0x416625(_0x1601f6['location']['hostname']))),_0x1601f6[_0x43a750(0x22d)];}function X(_0x426d5f,_0x58bd93,_0x2dbbb7,_0x2efb32){var _0x127735=_0x31e486;_0x426d5f=_0x426d5f,_0x58bd93=_0x58bd93,_0x2dbbb7=_0x2dbbb7,_0x2efb32=_0x2efb32;let _0xbbf52f=B(_0x426d5f),_0x232d0d=_0xbbf52f[_0x127735(0x16f)],_0x5b689d=_0xbbf52f[_0x127735(0x177)];class _0x2e0d3c{constructor(){var _0x5421b9=_0x127735;this[_0x5421b9(0x15c)]=/^(?!(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$)[_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*$/,this[_0x5421b9(0x17b)]=/^(0|[1-9][0-9]*)$/,this[_0x5421b9(0x188)]=/'([^\\\\']|\\\\')*'/,this['_undefined']=_0x426d5f[_0x5421b9(0x1eb)],this[_0x5421b9(0x221)]=_0x426d5f[_0x5421b9(0x14c)],this[_0x5421b9(0x167)]=Object['getOwnPropertyDescriptor'],this[_0x5421b9(0x1bf)]=Object[_0x5421b9(0x218)],this['_Symbol']=_0x426d5f[_0x5421b9(0x1cf)],this[_0x5421b9(0x21b)]=RegExp[_0x5421b9(0x195)]['toString'],this[_0x5421b9(0x1dc)]=Date[_0x5421b9(0x195)]['toString'];}['serialize'](_0x5150b2,_0xd40a4b,_0x1c7900,_0x4196d7){var _0x2c7d04=_0x127735,_0x38e94a=this,_0x879d98=_0x1c7900[_0x2c7d04(0x1ef)];function _0x801e45(_0x4bf643,_0x406e93,_0x303f2d){var _0x457809=_0x2c7d04;_0x406e93['type']='unknown',_0x406e93[_0x457809(0x20c)]=_0x4bf643[_0x457809(0x1a1)],_0x1229b2=_0x303f2d[_0x457809(0x214)][_0x457809(0x1a4)],_0x303f2d[_0x457809(0x214)][_0x457809(0x1a4)]=_0x406e93,_0x38e94a['_treeNodePropertiesBeforeFullValue'](_0x406e93,_0x303f2d);}try{_0x1c7900['level']++,_0x1c7900[_0x2c7d04(0x1ef)]&&_0x1c7900[_0x2c7d04(0x1a6)][_0x2c7d04(0x172)](_0xd40a4b);var _0x5d8a16,_0x516b20,_0x25b902,_0x218f55,_0x5d1e4b=[],_0x735244=[],_0x4f15fe,_0x2ea7ae=this[_0x2c7d04(0x1ec)](_0xd40a4b),_0x397c7e=_0x2ea7ae===_0x2c7d04(0x1e6),_0x223e77=!0x1,_0x2ef34b=_0x2ea7ae===_0x2c7d04(0x173),_0x1b18bc=this['_isPrimitiveType'](_0x2ea7ae),_0x5c4fdd=this[_0x2c7d04(0x183)](_0x2ea7ae),_0x11a15d=_0x1b18bc||_0x5c4fdd,_0x503a2d={},_0x539ed3=0x0,_0x412eda=!0x1,_0x1229b2,_0x129776=/^(([1-9]{1}[0-9]*)|0)$/;if(_0x1c7900[_0x2c7d04(0x211)]){if(_0x397c7e){if(_0x516b20=_0xd40a4b['length'],_0x516b20>_0x1c7900[_0x2c7d04(0x1b6)]){for(_0x25b902=0x0,_0x218f55=_0x1c7900[_0x2c7d04(0x1b6)],_0x5d8a16=_0x25b902;_0x5d8a16<_0x218f55;_0x5d8a16++)_0x735244['push'](_0x38e94a[_0x2c7d04(0x154)](_0x5d1e4b,_0xd40a4b,_0x2ea7ae,_0x5d8a16,_0x1c7900));_0x5150b2[_0x2c7d04(0x1cd)]=!0x0;}else{for(_0x25b902=0x0,_0x218f55=_0x516b20,_0x5d8a16=_0x25b902;_0x5d8a16<_0x218f55;_0x5d8a16++)_0x735244[_0x2c7d04(0x172)](_0x38e94a[_0x2c7d04(0x154)](_0x5d1e4b,_0xd40a4b,_0x2ea7ae,_0x5d8a16,_0x1c7900));}_0x1c7900['autoExpandPropertyCount']+=_0x735244[_0x2c7d04(0x1bc)];}if(!(_0x2ea7ae===_0x2c7d04(0x165)||_0x2ea7ae==='undefined')&&!_0x1b18bc&&_0x2ea7ae!==_0x2c7d04(0x204)&&_0x2ea7ae!=='Buffer'&&_0x2ea7ae!==_0x2c7d04(0x182)){var _0x3efa2d=_0x4196d7[_0x2c7d04(0x162)]||_0x1c7900['props'];if(this[_0x2c7d04(0x224)](_0xd40a4b)?(_0x5d8a16=0x0,_0xd40a4b['forEach'](function(_0x20cf5e){var _0x3010a4=_0x2c7d04;if(_0x539ed3++,_0x1c7900[_0x3010a4(0x156)]++,_0x539ed3>_0x3efa2d){_0x412eda=!0x0;return;}if(!_0x1c7900[_0x3010a4(0x190)]&&_0x1c7900[_0x3010a4(0x1ef)]&&_0x1c7900[_0x3010a4(0x156)]>_0x1c7900['autoExpandLimit']){_0x412eda=!0x0;return;}_0x735244[_0x3010a4(0x172)](_0x38e94a[_0x3010a4(0x154)](_0x5d1e4b,_0xd40a4b,_0x3010a4(0x1c5),_0x5d8a16++,_0x1c7900,function(_0x511f78){return function(){return _0x511f78;};}(_0x20cf5e)));})):this[_0x2c7d04(0x20d)](_0xd40a4b)&&_0xd40a4b[_0x2c7d04(0x1dd)](function(_0x18c390,_0x4004f5){var _0x436a43=_0x2c7d04;if(_0x539ed3++,_0x1c7900[_0x436a43(0x156)]++,_0x539ed3>_0x3efa2d){_0x412eda=!0x0;return;}if(!_0x1c7900['isExpressionToEvaluate']&&_0x1c7900[_0x436a43(0x1ef)]&&_0x1c7900[_0x436a43(0x156)]>_0x1c7900[_0x436a43(0x217)]){_0x412eda=!0x0;return;}var _0x4a8f1c=_0x4004f5[_0x436a43(0x1af)]();_0x4a8f1c[_0x436a43(0x1bc)]>0x64&&(_0x4a8f1c=_0x4a8f1c[_0x436a43(0x159)](0x0,0x64)+'...'),_0x735244[_0x436a43(0x172)](_0x38e94a['_addProperty'](_0x5d1e4b,_0xd40a4b,_0x436a43(0x1db),_0x4a8f1c,_0x1c7900,function(_0x1bda3c){return function(){return _0x1bda3c;};}(_0x18c390)));}),!_0x223e77){try{for(_0x4f15fe in _0xd40a4b)if(!(_0x397c7e&&_0x129776[_0x2c7d04(0x19d)](_0x4f15fe))&&!this['_blacklistedProperty'](_0xd40a4b,_0x4f15fe,_0x1c7900)){if(_0x539ed3++,_0x1c7900[_0x2c7d04(0x156)]++,_0x539ed3>_0x3efa2d){_0x412eda=!0x0;break;}if(!_0x1c7900[_0x2c7d04(0x190)]&&_0x1c7900['autoExpand']&&_0x1c7900[_0x2c7d04(0x156)]>_0x1c7900[_0x2c7d04(0x217)]){_0x412eda=!0x0;break;}_0x735244[_0x2c7d04(0x172)](_0x38e94a[_0x2c7d04(0x14a)](_0x5d1e4b,_0x503a2d,_0xd40a4b,_0x2ea7ae,_0x4f15fe,_0x1c7900));}}catch{}if(_0x503a2d[_0x2c7d04(0x1b9)]=!0x0,_0x2ef34b&&(_0x503a2d[_0x2c7d04(0x1e5)]=!0x0),!_0x412eda){var _0x3eabb9=[][_0x2c7d04(0x18a)](this['_getOwnPropertyNames'](_0xd40a4b))[_0x2c7d04(0x18a)](this[_0x2c7d04(0x1fc)](_0xd40a4b));for(_0x5d8a16=0x0,_0x516b20=_0x3eabb9[_0x2c7d04(0x1bc)];_0x5d8a16<_0x516b20;_0x5d8a16++)if(_0x4f15fe=_0x3eabb9[_0x5d8a16],!(_0x397c7e&&_0x129776[_0x2c7d04(0x19d)](_0x4f15fe['toString']()))&&!this['_blacklistedProperty'](_0xd40a4b,_0x4f15fe,_0x1c7900)&&!_0x503a2d['_p_'+_0x4f15fe[_0x2c7d04(0x1af)]()]){if(_0x539ed3++,_0x1c7900[_0x2c7d04(0x156)]++,_0x539ed3>_0x3efa2d){_0x412eda=!0x0;break;}if(!_0x1c7900[_0x2c7d04(0x190)]&&_0x1c7900[_0x2c7d04(0x1ef)]&&_0x1c7900[_0x2c7d04(0x156)]>_0x1c7900[_0x2c7d04(0x217)]){_0x412eda=!0x0;break;}_0x735244[_0x2c7d04(0x172)](_0x38e94a[_0x2c7d04(0x14a)](_0x5d1e4b,_0x503a2d,_0xd40a4b,_0x2ea7ae,_0x4f15fe,_0x1c7900));}}}}}if(_0x5150b2[_0x2c7d04(0x1ac)]=_0x2ea7ae,_0x11a15d?(_0x5150b2['value']=_0xd40a4b[_0x2c7d04(0x1c6)](),this[_0x2c7d04(0x145)](_0x2ea7ae,_0x5150b2,_0x1c7900,_0x4196d7)):_0x2ea7ae===_0x2c7d04(0x14e)?_0x5150b2['value']=this[_0x2c7d04(0x1dc)]['call'](_0xd40a4b):_0x2ea7ae===_0x2c7d04(0x182)?_0x5150b2[_0x2c7d04(0x1aa)]=_0xd40a4b[_0x2c7d04(0x1af)]():_0x2ea7ae===_0x2c7d04(0x205)?_0x5150b2['value']=this[_0x2c7d04(0x21b)][_0x2c7d04(0x171)](_0xd40a4b):_0x2ea7ae===_0x2c7d04(0x15d)&&this[_0x2c7d04(0x1fe)]?_0x5150b2[_0x2c7d04(0x1aa)]=this[_0x2c7d04(0x1fe)][_0x2c7d04(0x195)]['toString'][_0x2c7d04(0x171)](_0xd40a4b):!_0x1c7900[_0x2c7d04(0x211)]&&!(_0x2ea7ae===_0x2c7d04(0x165)||_0x2ea7ae===_0x2c7d04(0x1eb))&&(delete _0x5150b2['value'],_0x5150b2[_0x2c7d04(0x199)]=!0x0),_0x412eda&&(_0x5150b2[_0x2c7d04(0x180)]=!0x0),_0x1229b2=_0x1c7900[_0x2c7d04(0x214)][_0x2c7d04(0x1a4)],_0x1c7900[_0x2c7d04(0x214)][_0x2c7d04(0x1a4)]=_0x5150b2,this[_0x2c7d04(0x194)](_0x5150b2,_0x1c7900),_0x735244['length']){for(_0x5d8a16=0x0,_0x516b20=_0x735244[_0x2c7d04(0x1bc)];_0x5d8a16<_0x516b20;_0x5d8a16++)_0x735244[_0x5d8a16](_0x5d8a16);}_0x5d1e4b[_0x2c7d04(0x1bc)]&&(_0x5150b2[_0x2c7d04(0x162)]=_0x5d1e4b);}catch(_0x8c9894){_0x801e45(_0x8c9894,_0x5150b2,_0x1c7900);}return this[_0x2c7d04(0x169)](_0xd40a4b,_0x5150b2),this[_0x2c7d04(0x1c0)](_0x5150b2,_0x1c7900),_0x1c7900[_0x2c7d04(0x214)][_0x2c7d04(0x1a4)]=_0x1229b2,_0x1c7900[_0x2c7d04(0x16d)]--,_0x1c7900['autoExpand']=_0x879d98,_0x1c7900[_0x2c7d04(0x1ef)]&&_0x1c7900[_0x2c7d04(0x1a6)]['pop'](),_0x5150b2;}[_0x127735(0x1fc)](_0x2c57e2){var _0x507d77=_0x127735;return Object[_0x507d77(0x20a)]?Object[_0x507d77(0x20a)](_0x2c57e2):[];}[_0x127735(0x224)](_0x1ad1f2){var _0x3b3379=_0x127735;return!!(_0x1ad1f2&&_0x426d5f[_0x3b3379(0x1c5)]&&this[_0x3b3379(0x196)](_0x1ad1f2)===_0x3b3379(0x15e)&&_0x1ad1f2['forEach']);}[_0x127735(0x1c4)](_0x1a0a0f,_0x4a80b8,_0x4f64fe){var _0x5b8975=_0x127735;return _0x4f64fe['noFunctions']?typeof _0x1a0a0f[_0x4a80b8]==_0x5b8975(0x173):!0x1;}[_0x127735(0x1ec)](_0x5293e3){var _0x11728a=_0x127735,_0x161237='';return _0x161237=typeof _0x5293e3,_0x161237===_0x11728a(0x166)?this[_0x11728a(0x196)](_0x5293e3)===_0x11728a(0x160)?_0x161237=_0x11728a(0x1e6):this[_0x11728a(0x196)](_0x5293e3)==='[object\\x20Date]'?_0x161237='date':this[_0x11728a(0x196)](_0x5293e3)==='[object\\x20BigInt]'?_0x161237=_0x11728a(0x182):_0x5293e3===null?_0x161237=_0x11728a(0x165):_0x5293e3[_0x11728a(0x1a3)]&&(_0x161237=_0x5293e3[_0x11728a(0x1a3)][_0x11728a(0x1c9)]||_0x161237):_0x161237===_0x11728a(0x1eb)&&this[_0x11728a(0x221)]&&_0x5293e3 instanceof this[_0x11728a(0x221)]&&(_0x161237=_0x11728a(0x14c)),_0x161237;}[_0x127735(0x196)](_0x3d1064){var _0x413d1f=_0x127735;return Object[_0x413d1f(0x195)][_0x413d1f(0x1af)]['call'](_0x3d1064);}[_0x127735(0x1c3)](_0xafb5c4){var _0x10550d=_0x127735;return _0xafb5c4===_0x10550d(0x1e9)||_0xafb5c4==='string'||_0xafb5c4===_0x10550d(0x17e);}['_isPrimitiveWrapperType'](_0x429062){var _0x4b1258=_0x127735;return _0x429062==='Boolean'||_0x429062===_0x4b1258(0x204)||_0x429062==='Number';}[_0x127735(0x154)](_0x29134e,_0x42ac35,_0x39d890,_0x17251c,_0x46dbca,_0x983f3){var _0x5dd65a=this;return function(_0x44eb69){var _0x2ba888=_0x33b2,_0x2f66ac=_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x1a4)],_0x419caf=_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x149)],_0x327987=_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x1f7)];_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x1f7)]=_0x2f66ac,_0x46dbca['node'][_0x2ba888(0x149)]=typeof _0x17251c=='number'?_0x17251c:_0x44eb69,_0x29134e['push'](_0x5dd65a['_property'](_0x42ac35,_0x39d890,_0x17251c,_0x46dbca,_0x983f3)),_0x46dbca['node']['parent']=_0x327987,_0x46dbca[_0x2ba888(0x214)][_0x2ba888(0x149)]=_0x419caf;};}[_0x127735(0x14a)](_0x1079f0,_0x42ff3c,_0x28dcfc,_0x16872f,_0x459e0f,_0x3fca62,_0x350643){var _0x728dbf=_0x127735,_0x41f1a7=this;return _0x42ff3c['_p_'+_0x459e0f[_0x728dbf(0x1af)]()]=!0x0,function(_0x3677ae){var _0xecfed8=_0x728dbf,_0x4e9bfa=_0x3fca62[_0xecfed8(0x214)][_0xecfed8(0x1a4)],_0x29c59e=_0x3fca62[_0xecfed8(0x214)][_0xecfed8(0x149)],_0x1a70ed=_0x3fca62['node'][_0xecfed8(0x1f7)];_0x3fca62['node'][_0xecfed8(0x1f7)]=_0x4e9bfa,_0x3fca62['node'][_0xecfed8(0x149)]=_0x3677ae,_0x1079f0[_0xecfed8(0x172)](_0x41f1a7[_0xecfed8(0x1c1)](_0x28dcfc,_0x16872f,_0x459e0f,_0x3fca62,_0x350643)),_0x3fca62[_0xecfed8(0x214)][_0xecfed8(0x1f7)]=_0x1a70ed,_0x3fca62[_0xecfed8(0x214)]['index']=_0x29c59e;};}[_0x127735(0x1c1)](_0x4b6b39,_0x454239,_0x420ca1,_0x1d6dd6,_0xfdc1f2){var _0x49f5a4=_0x127735,_0x201907=this;_0xfdc1f2||(_0xfdc1f2=function(_0x2eda18,_0x3fd888){return _0x2eda18[_0x3fd888];});var _0x1994ac=_0x420ca1['toString'](),_0x3115be=_0x1d6dd6[_0x49f5a4(0x210)]||{},_0x576f77=_0x1d6dd6[_0x49f5a4(0x211)],_0x2806ba=_0x1d6dd6[_0x49f5a4(0x190)];try{var _0x4b28f8=this[_0x49f5a4(0x20d)](_0x4b6b39),_0x3b2384=_0x1994ac;_0x4b28f8&&_0x3b2384[0x0]==='\\x27'&&(_0x3b2384=_0x3b2384['substr'](0x1,_0x3b2384[_0x49f5a4(0x1bc)]-0x2));var _0x33cb5b=_0x1d6dd6[_0x49f5a4(0x210)]=_0x3115be[_0x49f5a4(0x15f)+_0x3b2384];_0x33cb5b&&(_0x1d6dd6[_0x49f5a4(0x211)]=_0x1d6dd6['depth']+0x1),_0x1d6dd6[_0x49f5a4(0x190)]=!!_0x33cb5b;var _0x5c26b9=typeof _0x420ca1==_0x49f5a4(0x15d),_0x37f8f1={'name':_0x5c26b9||_0x4b28f8?_0x1994ac:this[_0x49f5a4(0x153)](_0x1994ac)};if(_0x5c26b9&&(_0x37f8f1['symbol']=!0x0),!(_0x454239==='array'||_0x454239===_0x49f5a4(0x1b8))){var _0x8f25d1=this[_0x49f5a4(0x167)](_0x4b6b39,_0x420ca1);if(_0x8f25d1&&(_0x8f25d1[_0x49f5a4(0x1ee)]&&(_0x37f8f1[_0x49f5a4(0x147)]=!0x0),_0x8f25d1[_0x49f5a4(0x1c7)]&&!_0x33cb5b&&!_0x1d6dd6['resolveGetters']))return _0x37f8f1[_0x49f5a4(0x1f1)]=!0x0,this[_0x49f5a4(0x1f5)](_0x37f8f1,_0x1d6dd6),_0x37f8f1;}var _0x2cd47d;try{_0x2cd47d=_0xfdc1f2(_0x4b6b39,_0x420ca1);}catch(_0x12a02c){return _0x37f8f1={'name':_0x1994ac,'type':_0x49f5a4(0x21d),'error':_0x12a02c[_0x49f5a4(0x1a1)]},this[_0x49f5a4(0x1f5)](_0x37f8f1,_0x1d6dd6),_0x37f8f1;}var _0x592b34=this[_0x49f5a4(0x1ec)](_0x2cd47d),_0x3cc690=this['_isPrimitiveType'](_0x592b34);if(_0x37f8f1[_0x49f5a4(0x1ac)]=_0x592b34,_0x3cc690)this[_0x49f5a4(0x1f5)](_0x37f8f1,_0x1d6dd6,_0x2cd47d,function(){var _0x56f47a=_0x49f5a4;_0x37f8f1[_0x56f47a(0x1aa)]=_0x2cd47d[_0x56f47a(0x1c6)](),!_0x33cb5b&&_0x201907[_0x56f47a(0x145)](_0x592b34,_0x37f8f1,_0x1d6dd6,{});});else{var _0x4fc792=_0x1d6dd6[_0x49f5a4(0x1ef)]&&_0x1d6dd6[_0x49f5a4(0x16d)]<_0x1d6dd6[_0x49f5a4(0x179)]&&_0x1d6dd6[_0x49f5a4(0x1a6)]['indexOf'](_0x2cd47d)<0x0&&_0x592b34!==_0x49f5a4(0x173)&&_0x1d6dd6[_0x49f5a4(0x156)]<_0x1d6dd6['autoExpandLimit'];_0x4fc792||_0x1d6dd6[_0x49f5a4(0x16d)]<_0x576f77||_0x33cb5b?(this[_0x49f5a4(0x21e)](_0x37f8f1,_0x2cd47d,_0x1d6dd6,_0x33cb5b||{}),this['_additionalMetadata'](_0x2cd47d,_0x37f8f1)):this[_0x49f5a4(0x1f5)](_0x37f8f1,_0x1d6dd6,_0x2cd47d,function(){var _0x1b0be1=_0x49f5a4;_0x592b34===_0x1b0be1(0x165)||_0x592b34===_0x1b0be1(0x1eb)||(delete _0x37f8f1['value'],_0x37f8f1[_0x1b0be1(0x199)]=!0x0);});}return _0x37f8f1;}finally{_0x1d6dd6[_0x49f5a4(0x210)]=_0x3115be,_0x1d6dd6[_0x49f5a4(0x211)]=_0x576f77,_0x1d6dd6[_0x49f5a4(0x190)]=_0x2806ba;}}[_0x127735(0x145)](_0x46f5d8,_0x989294,_0x2e316b,_0x232707){var _0x211045=_0x127735,_0x448778=_0x232707[_0x211045(0x1a5)]||_0x2e316b['strLength'];if((_0x46f5d8===_0x211045(0x164)||_0x46f5d8===_0x211045(0x204))&&_0x989294[_0x211045(0x1aa)]){let _0xeb3bb5=_0x989294[_0x211045(0x1aa)]['length'];_0x2e316b[_0x211045(0x18d)]+=_0xeb3bb5,_0x2e316b[_0x211045(0x18d)]>_0x2e316b[_0x211045(0x174)]?(_0x989294[_0x211045(0x199)]='',delete _0x989294['value']):_0xeb3bb5>_0x448778&&(_0x989294[_0x211045(0x199)]=_0x989294[_0x211045(0x1aa)]['substr'](0x0,_0x448778),delete _0x989294['value']);}}[_0x127735(0x20d)](_0x28b7d0){var _0x8a1886=_0x127735;return!!(_0x28b7d0&&_0x426d5f['Map']&&this[_0x8a1886(0x196)](_0x28b7d0)===_0x8a1886(0x1bd)&&_0x28b7d0[_0x8a1886(0x1dd)]);}[_0x127735(0x153)](_0x1e10cc){var _0x4a2d80=_0x127735;if(_0x1e10cc[_0x4a2d80(0x208)](/^\\d+$/))return _0x1e10cc;var _0x342eca;try{_0x342eca=JSON[_0x4a2d80(0x1fa)](''+_0x1e10cc);}catch{_0x342eca='\\x22'+this[_0x4a2d80(0x196)](_0x1e10cc)+'\\x22';}return _0x342eca[_0x4a2d80(0x208)](/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)?_0x342eca=_0x342eca[_0x4a2d80(0x1a0)](0x1,_0x342eca[_0x4a2d80(0x1bc)]-0x2):_0x342eca=_0x342eca[_0x4a2d80(0x150)](/'/g,'\\x5c\\x27')[_0x4a2d80(0x150)](/\\\\\"/g,'\\x22')[_0x4a2d80(0x150)](/(^\"|\"$)/g,'\\x27'),_0x342eca;}[_0x127735(0x1f5)](_0x311141,_0x4fe874,_0x4b456e,_0x2a1f80){var _0x3c1657=_0x127735;this[_0x3c1657(0x194)](_0x311141,_0x4fe874),_0x2a1f80&&_0x2a1f80(),this[_0x3c1657(0x169)](_0x4b456e,_0x311141),this['_treeNodePropertiesAfterFullValue'](_0x311141,_0x4fe874);}[_0x127735(0x194)](_0x3fd70b,_0x2d8af9){var _0x36dcf4=_0x127735;this['_setNodeId'](_0x3fd70b,_0x2d8af9),this['_setNodeQueryPath'](_0x3fd70b,_0x2d8af9),this[_0x36dcf4(0x17d)](_0x3fd70b,_0x2d8af9),this[_0x36dcf4(0x1ae)](_0x3fd70b,_0x2d8af9);}['_setNodeId'](_0x4e3852,_0x5907e8){}['_setNodeQueryPath'](_0x1cc8b4,_0x26819b){}['_setNodeLabel'](_0x565ccf,_0x199a64){}[_0x127735(0x14f)](_0x120c63){var _0x2708e2=_0x127735;return _0x120c63===this[_0x2708e2(0x201)];}[_0x127735(0x1c0)](_0x2653c7,_0x2fe267){var _0x2e41b4=_0x127735;this[_0x2e41b4(0x1f0)](_0x2653c7,_0x2fe267),this[_0x2e41b4(0x1d4)](_0x2653c7),_0x2fe267[_0x2e41b4(0x14d)]&&this[_0x2e41b4(0x185)](_0x2653c7),this[_0x2e41b4(0x1e0)](_0x2653c7,_0x2fe267),this[_0x2e41b4(0x191)](_0x2653c7,_0x2fe267),this[_0x2e41b4(0x219)](_0x2653c7);}['_additionalMetadata'](_0xaa1402,_0x1d0e69){var _0x2b6da8=_0x127735;let _0x5790d5;try{_0x426d5f[_0x2b6da8(0x1df)]&&(_0x5790d5=_0x426d5f[_0x2b6da8(0x1df)]['error'],_0x426d5f['console'][_0x2b6da8(0x20c)]=function(){}),_0xaa1402&&typeof _0xaa1402[_0x2b6da8(0x1bc)]==_0x2b6da8(0x17e)&&(_0x1d0e69[_0x2b6da8(0x1bc)]=_0xaa1402['length']);}catch{}finally{_0x5790d5&&(_0x426d5f[_0x2b6da8(0x1df)][_0x2b6da8(0x20c)]=_0x5790d5);}if(_0x1d0e69['type']===_0x2b6da8(0x17e)||_0x1d0e69[_0x2b6da8(0x1ac)]==='Number'){if(isNaN(_0x1d0e69[_0x2b6da8(0x1aa)]))_0x1d0e69['nan']=!0x0,delete _0x1d0e69[_0x2b6da8(0x1aa)];else switch(_0x1d0e69[_0x2b6da8(0x1aa)]){case Number[_0x2b6da8(0x17c)]:_0x1d0e69[_0x2b6da8(0x1d9)]=!0x0,delete _0x1d0e69[_0x2b6da8(0x1aa)];break;case Number[_0x2b6da8(0x1a2)]:_0x1d0e69[_0x2b6da8(0x1cb)]=!0x0,delete _0x1d0e69['value'];break;case 0x0:this['_isNegativeZero'](_0x1d0e69['value'])&&(_0x1d0e69['negativeZero']=!0x0);break;}}else _0x1d0e69[_0x2b6da8(0x1ac)]===_0x2b6da8(0x173)&&typeof _0xaa1402[_0x2b6da8(0x1c9)]=='string'&&_0xaa1402[_0x2b6da8(0x1c9)]&&_0x1d0e69['name']&&_0xaa1402[_0x2b6da8(0x1c9)]!==_0x1d0e69[_0x2b6da8(0x1c9)]&&(_0x1d0e69['funcName']=_0xaa1402[_0x2b6da8(0x1c9)]);}[_0x127735(0x1be)](_0x5bf79f){var _0x1e0bf2=_0x127735;return 0x1/_0x5bf79f===Number[_0x1e0bf2(0x1a2)];}[_0x127735(0x185)](_0x9ec463){var _0x244642=_0x127735;!_0x9ec463['props']||!_0x9ec463[_0x244642(0x162)][_0x244642(0x1bc)]||_0x9ec463[_0x244642(0x1ac)]===_0x244642(0x1e6)||_0x9ec463[_0x244642(0x1ac)]===_0x244642(0x1db)||_0x9ec463['type']===_0x244642(0x1c5)||_0x9ec463[_0x244642(0x162)]['sort'](function(_0x4ea9e0,_0x35c323){var _0x4b5cb2=_0x244642,_0x2036f3=_0x4ea9e0[_0x4b5cb2(0x1c9)][_0x4b5cb2(0x202)](),_0xbf0e75=_0x35c323[_0x4b5cb2(0x1c9)][_0x4b5cb2(0x202)]();return _0x2036f3<_0xbf0e75?-0x1:_0x2036f3>_0xbf0e75?0x1:0x0;});}['_addFunctionsNode'](_0x571411,_0x51166f){var _0x144384=_0x127735;if(!(_0x51166f[_0x144384(0x187)]||!_0x571411[_0x144384(0x162)]||!_0x571411[_0x144384(0x162)]['length'])){for(var _0x15f381=[],_0x4b7e4c=[],_0x1ee8d9=0x0,_0x157d1f=_0x571411[_0x144384(0x162)]['length'];_0x1ee8d9<_0x157d1f;_0x1ee8d9++){var _0x5d11be=_0x571411[_0x144384(0x162)][_0x1ee8d9];_0x5d11be[_0x144384(0x1ac)]===_0x144384(0x173)?_0x15f381[_0x144384(0x172)](_0x5d11be):_0x4b7e4c[_0x144384(0x172)](_0x5d11be);}if(!(!_0x4b7e4c[_0x144384(0x1bc)]||_0x15f381['length']<=0x1)){_0x571411[_0x144384(0x162)]=_0x4b7e4c;var _0x43d31c={'functionsNode':!0x0,'props':_0x15f381};this['_setNodeId'](_0x43d31c,_0x51166f),this['_setNodeLabel'](_0x43d31c,_0x51166f),this[_0x144384(0x1d4)](_0x43d31c),this['_setNodePermissions'](_0x43d31c,_0x51166f),_0x43d31c['id']+='\\x20f',_0x571411['props'][_0x144384(0x216)](_0x43d31c);}}}[_0x127735(0x191)](_0x496a9a,_0xbeea77){}[_0x127735(0x1d4)](_0x22b022){}[_0x127735(0x20f)](_0x357473){var _0xe4a9d0=_0x127735;return Array['isArray'](_0x357473)||typeof _0x357473==_0xe4a9d0(0x166)&&this['_objectToString'](_0x357473)==='[object\\x20Array]';}[_0x127735(0x1ae)](_0x2f40e6,_0x40541c){}[_0x127735(0x219)](_0x45fcae){var _0x5eb338=_0x127735;delete _0x45fcae['_hasSymbolPropertyOnItsPath'],delete _0x45fcae['_hasSetOnItsPath'],delete _0x45fcae[_0x5eb338(0x226)];}[_0x127735(0x17d)](_0x2c8e98,_0x5d16e9){}}let _0x38fd35=new _0x2e0d3c(),_0x3ae2cc={'props':0x64,'elements':0x64,'strLength':0x400*0x32,'totalStrLength':0x400*0x32,'autoExpandLimit':0x1388,'autoExpandMaxDepth':0xa},_0x4e441={'props':0x5,'elements':0x5,'strLength':0x100,'totalStrLength':0x100*0x3,'autoExpandLimit':0x1e,'autoExpandMaxDepth':0x2};function _0xa713d7(_0x1d4bd9,_0x56700c,_0x5e35a2,_0xca5fba,_0x5cb9b2,_0x46ecb3){var _0xc9442c=_0x127735;let _0x1ad82b,_0x568f00;try{_0x568f00=_0x5b689d(),_0x1ad82b=_0x2dbbb7[_0x56700c],!_0x1ad82b||_0x568f00-_0x1ad82b['ts']>0x1f4&&_0x1ad82b[_0xc9442c(0x1ba)]&&_0x1ad82b[_0xc9442c(0x19a)]/_0x1ad82b[_0xc9442c(0x1ba)]<0x64?(_0x2dbbb7[_0x56700c]=_0x1ad82b={'count':0x0,'time':0x0,'ts':_0x568f00},_0x2dbbb7[_0xc9442c(0x18f)]={}):_0x568f00-_0x2dbbb7[_0xc9442c(0x18f)]['ts']>0x32&&_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x1ba)]&&_0x2dbbb7[_0xc9442c(0x18f)]['time']/_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x1ba)]<0x64&&(_0x2dbbb7[_0xc9442c(0x18f)]={});let _0x55cfc9=[],_0x841e56=_0x1ad82b[_0xc9442c(0x1bb)]||_0x2dbbb7['hits'][_0xc9442c(0x1bb)]?_0x4e441:_0x3ae2cc,_0x97e270=_0x3d4a42=>{var _0x974ae0=_0xc9442c;let _0x533cf8={};return _0x533cf8[_0x974ae0(0x162)]=_0x3d4a42[_0x974ae0(0x162)],_0x533cf8[_0x974ae0(0x1b6)]=_0x3d4a42['elements'],_0x533cf8['strLength']=_0x3d4a42[_0x974ae0(0x1a5)],_0x533cf8['totalStrLength']=_0x3d4a42[_0x974ae0(0x174)],_0x533cf8[_0x974ae0(0x217)]=_0x3d4a42[_0x974ae0(0x217)],_0x533cf8[_0x974ae0(0x179)]=_0x3d4a42[_0x974ae0(0x179)],_0x533cf8[_0x974ae0(0x14d)]=!0x1,_0x533cf8[_0x974ae0(0x187)]=!_0x58bd93,_0x533cf8[_0x974ae0(0x211)]=0x1,_0x533cf8[_0x974ae0(0x16d)]=0x0,_0x533cf8[_0x974ae0(0x146)]=_0x974ae0(0x1e3),_0x533cf8[_0x974ae0(0x1a9)]='root_exp',_0x533cf8[_0x974ae0(0x1ef)]=!0x0,_0x533cf8[_0x974ae0(0x1a6)]=[],_0x533cf8[_0x974ae0(0x156)]=0x0,_0x533cf8['resolveGetters']=!0x0,_0x533cf8[_0x974ae0(0x18d)]=0x0,_0x533cf8[_0x974ae0(0x214)]={'current':void 0x0,'parent':void 0x0,'index':0x0},_0x533cf8;};for(var _0x46b7b6=0x0;_0x46b7b6<_0x5cb9b2[_0xc9442c(0x1bc)];_0x46b7b6++)_0x55cfc9[_0xc9442c(0x172)](_0x38fd35[_0xc9442c(0x21e)]({'timeNode':_0x1d4bd9===_0xc9442c(0x19a)||void 0x0},_0x5cb9b2[_0x46b7b6],_0x97e270(_0x841e56),{}));if(_0x1d4bd9===_0xc9442c(0x14b)||_0x1d4bd9===_0xc9442c(0x20c)){let _0x15fdf3=Error[_0xc9442c(0x21c)];try{Error['stackTraceLimit']=0x1/0x0,_0x55cfc9[_0xc9442c(0x172)](_0x38fd35[_0xc9442c(0x21e)]({'stackNode':!0x0},new Error()[_0xc9442c(0x1e4)],_0x97e270(_0x841e56),{'strLength':0x1/0x0}));}finally{Error[_0xc9442c(0x21c)]=_0x15fdf3;}}return{'method':'log','version':_0x2efb32,'args':[{'ts':_0x5e35a2,'session':_0xca5fba,'args':_0x55cfc9,'id':_0x56700c,'context':_0x46ecb3}]};}catch(_0x9d3ef5){return{'method':_0xc9442c(0x168),'version':_0x2efb32,'args':[{'ts':_0x5e35a2,'session':_0xca5fba,'args':[{'type':_0xc9442c(0x21d),'error':_0x9d3ef5&&_0x9d3ef5[_0xc9442c(0x1a1)]}],'id':_0x56700c,'context':_0x46ecb3}]};}finally{try{if(_0x1ad82b&&_0x568f00){let _0x38338e=_0x5b689d();_0x1ad82b['count']++,_0x1ad82b['time']+=_0x232d0d(_0x568f00,_0x38338e),_0x1ad82b['ts']=_0x38338e,_0x2dbbb7['hits']['count']++,_0x2dbbb7['hits'][_0xc9442c(0x19a)]+=_0x232d0d(_0x568f00,_0x38338e),_0x2dbbb7[_0xc9442c(0x18f)]['ts']=_0x38338e,(_0x1ad82b['count']>0x32||_0x1ad82b[_0xc9442c(0x19a)]>0x64)&&(_0x1ad82b[_0xc9442c(0x1bb)]=!0x0),(_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x1ba)]>0x3e8||_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x19a)]>0x12c)&&(_0x2dbbb7[_0xc9442c(0x18f)][_0xc9442c(0x1bb)]=!0x0);}}catch{}}}return _0xa713d7;}((_0x90c37a,_0x1d748d,_0x27f184,_0x1c3e41,_0x1752b9,_0x15c4be,_0x43ab6c,_0x5e0357,_0x38586c,_0x13e9ae,_0x8982c1)=>{var _0x593112=_0x31e486;if(_0x90c37a['_console_ninja'])return _0x90c37a[_0x593112(0x223)];if(!H(_0x90c37a,_0x5e0357,_0x1752b9))return _0x90c37a[_0x593112(0x223)]={'consoleLog':()=>{},'consoleTrace':()=>{},'consoleTime':()=>{},'consoleTimeEnd':()=>{},'autoLog':()=>{},'autoLogMany':()=>{},'autoTraceMany':()=>{},'coverage':()=>{},'autoTrace':()=>{},'autoTime':()=>{},'autoTimeEnd':()=>{}},_0x90c37a[_0x593112(0x223)];let _0x4097e6=B(_0x90c37a),_0x185aba=_0x4097e6['elapsed'],_0x28ef1c=_0x4097e6[_0x593112(0x177)],_0x34e4c3=_0x4097e6[_0x593112(0x22b)],_0x443c59={'hits':{},'ts':{}},_0x55abcc=X(_0x90c37a,_0x38586c,_0x443c59,_0x15c4be),_0xa8e15=_0x4cf894=>{_0x443c59['ts'][_0x4cf894]=_0x28ef1c();},_0x1fb3f6=(_0x5264c3,_0x5bc1dc)=>{var _0x303a3d=_0x593112;let _0x2b5f42=_0x443c59['ts'][_0x5bc1dc];if(delete _0x443c59['ts'][_0x5bc1dc],_0x2b5f42){let _0x227a4=_0x185aba(_0x2b5f42,_0x28ef1c());_0x4e158e(_0x55abcc(_0x303a3d(0x19a),_0x5264c3,_0x34e4c3(),_0x184b48,[_0x227a4],_0x5bc1dc));}},_0x3d7fa1=_0x3c5a62=>{var _0x47af33=_0x593112,_0x3ee072;return _0x1752b9===_0x47af33(0x22c)&&_0x90c37a['origin']&&((_0x3ee072=_0x3c5a62==null?void 0x0:_0x3c5a62['args'])==null?void 0x0:_0x3ee072[_0x47af33(0x1bc)])&&(_0x3c5a62['args'][0x0][_0x47af33(0x1d0)]=_0x90c37a[_0x47af33(0x1d0)]),_0x3c5a62;};_0x90c37a['_console_ninja']={'consoleLog':(_0x5a352e,_0x4835da)=>{var _0x454c01=_0x593112;_0x90c37a[_0x454c01(0x1df)][_0x454c01(0x168)][_0x454c01(0x1c9)]!==_0x454c01(0x19f)&&_0x4e158e(_0x55abcc(_0x454c01(0x168),_0x5a352e,_0x34e4c3(),_0x184b48,_0x4835da));},'consoleTrace':(_0x2d4513,_0x4e7919)=>{var _0x1df99f=_0x593112,_0x1c0c58,_0x151e7a;_0x90c37a[_0x1df99f(0x1df)][_0x1df99f(0x168)][_0x1df99f(0x1c9)]!=='disabledTrace'&&((_0x151e7a=(_0x1c0c58=_0x90c37a['process'])==null?void 0x0:_0x1c0c58[_0x1df99f(0x152)])!=null&&_0x151e7a[_0x1df99f(0x214)]&&(_0x90c37a[_0x1df99f(0x18e)]=!0x0),_0x4e158e(_0x3d7fa1(_0x55abcc(_0x1df99f(0x14b),_0x2d4513,_0x34e4c3(),_0x184b48,_0x4e7919))));},'consoleError':(_0x210567,_0x30a025)=>{var _0x3d6cfc=_0x593112;_0x90c37a[_0x3d6cfc(0x18e)]=!0x0,_0x4e158e(_0x3d7fa1(_0x55abcc('error',_0x210567,_0x34e4c3(),_0x184b48,_0x30a025)));},'consoleTime':_0x18b8d9=>{_0xa8e15(_0x18b8d9);},'consoleTimeEnd':(_0x3cf778,_0x592776)=>{_0x1fb3f6(_0x592776,_0x3cf778);},'autoLog':(_0x2ef76f,_0x399160)=>{var _0x49b3a5=_0x593112;_0x4e158e(_0x55abcc(_0x49b3a5(0x168),_0x399160,_0x34e4c3(),_0x184b48,[_0x2ef76f]));},'autoLogMany':(_0x4b08cb,_0x4e7de4)=>{var _0x18584b=_0x593112;_0x4e158e(_0x55abcc(_0x18584b(0x168),_0x4b08cb,_0x34e4c3(),_0x184b48,_0x4e7de4));},'autoTrace':(_0x3b69f0,_0x1d7a19)=>{var _0x37ed25=_0x593112;_0x4e158e(_0x3d7fa1(_0x55abcc(_0x37ed25(0x14b),_0x1d7a19,_0x34e4c3(),_0x184b48,[_0x3b69f0])));},'autoTraceMany':(_0x479c34,_0x19a2ab)=>{_0x4e158e(_0x3d7fa1(_0x55abcc('trace',_0x479c34,_0x34e4c3(),_0x184b48,_0x19a2ab)));},'autoTime':(_0x37f803,_0x171c24,_0x427588)=>{_0xa8e15(_0x427588);},'autoTimeEnd':(_0xae47fc,_0x2a9042,_0x3be603)=>{_0x1fb3f6(_0x2a9042,_0x3be603);},'coverage':_0x39e775=>{_0x4e158e({'method':'coverage','version':_0x15c4be,'args':[{'id':_0x39e775}]});}};let _0x4e158e=q(_0x90c37a,_0x1d748d,_0x27f184,_0x1c3e41,_0x1752b9,_0x13e9ae,_0x8982c1),_0x184b48=_0x90c37a[_0x593112(0x176)];return _0x90c37a[_0x593112(0x223)];})(globalThis,'127.0.0.1',_0x31e486(0x1b2),_0x31e486(0x203),_0x31e486(0x1d7),_0x31e486(0x207),'1737718497303',_0x31e486(0x222),_0x31e486(0x1b7),'',_0x31e486(0x151));"); - } catch (e) {} -} -; /* istanbul ignore next */ -function oo_oo(i) { - for (var _len = arguments.length, v = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - v[_key - 1] = arguments[_key]; - } - try { - oo_cm().consoleLog(i, v); - } catch (e) {} - return v; -} -; -oo_oo; /* istanbul ignore next */ -function oo_tr(i) { - for (var _len2 = arguments.length, v = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { - v[_key2 - 1] = arguments[_key2]; - } - try { - oo_cm().consoleTrace(i, v); - } catch (e) {} - return v; -} -; -oo_tr; /* istanbul ignore next */ -function oo_tx(i) { - for (var _len3 = arguments.length, v = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { - v[_key3 - 1] = arguments[_key3]; - } - try { - oo_cm().consoleError(i, v); - } catch (e) {} - return v; -} -; -oo_tx; /* istanbul ignore next */ -function oo_ts(v) { - try { - oo_cm().consoleTime(v); - } catch (e) {} - return v; -} -; -oo_ts; /* istanbul ignore next */ -function oo_te(v, i) { - try { - oo_cm().consoleTimeEnd(v, i); - } catch (e) {} - return v; -} -; -oo_te; /*eslint unicorn/no-abusive-eslint-disable:,eslint-comments/disable-enable-pair:,eslint-comments/no-unlimited-disable:,eslint-comments/no-aggregating-enable:,eslint-comments/no-duplicate-disable:,eslint-comments/no-unused-disable:,eslint-comments/no-unused-enable:,*/ /***/ }) @@ -1404,4 +1280,4 @@ oo_te; /*eslint unicorn/no-abusive-eslint-disable:,eslint-comments/disable-enabl /******/ var __webpack_exports__ = __webpack_require__.O(); /******/ } ]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUMsRUFBRTtFQUFFLElBQUk7SUFDdkI2SCxLQUFLLENBQUMsQ0FBQyxDQUFDa0IsY0FBYyxDQUFDZCxDQUFDLEVBQUVqSSxDQUFDLENBQUM7RUFDaEMsQ0FBQyxDQUNELE9BQU80QyxDQUFDLEVBQUUsQ0FBRTtFQUFFLE9BQU9xRixDQUFDO0FBQUU7QUFDeEI7QUFDQWEsS0FBSyxDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL3NjcmlwdHMvRHluYW1pY0ZpZWxkLnRzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvc2NyaXB0cy9mb3JtYnVpbGRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2ltcG9ydERlZmF1bHQgPSAodGhpcyAmJiB0aGlzLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgXCJkZWZhdWx0XCI6IG1vZCB9O1xufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuRHluYW1pY0ZpZWxkID0gdm9pZCAwO1xuY29uc3QganF1ZXJ5XzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZShcImpxdWVyeVwiKSk7XG5yZXF1aXJlKFwic2VsZWN0MlwiKTtcbmNsYXNzIER5bmFtaWNGaWVsZCB7XG4gICAgLyoqXG4gICAgICogSGlkZSBhbmQgU2hvdyBkaWZmZXJlbnQgZm9ybSBmaWVsZHMgYmFzZWQgb24gdm9jYWJ1bGFyeSBhbmQgb3RoZXIgdHlwZXNcbiAgICAgKi9cbiAgICBoaWRlU2hvd0Zvcm1GaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuaHVtYW5pdGFyaWFuU2NvcGVIaWRlVm9jYWJ1bGFyeVVyaSgpO1xuICAgICAgICB0aGlzLmNvdW50cnlCdWRnZXRIaWRlQ29kZUZpZWxkKCk7XG4gICAgICAgIHRoaXMuYWlkVHlwZVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgdGhpcy5zZWN0b3JWb2NhYnVsYXJ5SGlkZUZpZWxkKCk7XG4gICAgICAgIHRoaXMucG9saWN5Vm9jYWJ1bGFyeUhpZGVGaWVsZCgpO1xuICAgICAgICB0aGlzLnJlY2lwaWVudFZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgdGhpcy5zZWN0b3JWb2NhYnVsYXJ5SGlkZUZpZWxkKCk7XG4gICAgICAgIHRoaXMudGFnVm9jYWJ1bGFyeUhpZGVGaWVsZCgpO1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uQWlkVHlwZVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgdGhpcy5pbmRpY2F0b3JSZWZlcmVuY2VIaWRlRmllbGRVcmkoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSHVtYW5pdGFyaWFuIFNjb3BlIEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgZmllbGQgYmFzZWQgb24gJ0B2b2NhYnVsYXJ5JyBmaWVsZCB2YWx1ZVxuICAgICAqL1xuICAgIGh1bWFuaXRhcmlhblNjb3BlSGlkZVZvY2FidWxhcnlVcmkoKSB7XG4gICAgICAgIGNvbnN0IGh1bWFuaXRhcmlhblNjb3BlVm9jYWJ1bGFyeSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnc2VsZWN0W2lkXj1cImh1bWFuaXRhcmlhbl9zY29wZVwiXVtpZCo9XCJbdm9jYWJ1bGFyeV1cIl0nKTtcbiAgICAgICAgaWYgKGh1bWFuaXRhcmlhblNjb3BlVm9jYWJ1bGFyeS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyBoaWRlIGZpZWxkcyBvbiBwYWdlIGxvYWRcbiAgICAgICAgICAgIGpxdWVyeV8xLmRlZmF1bHQuZWFjaChodW1hbml0YXJpYW5TY29wZVZvY2FidWxhcnksIChpbmRleCwgc2NvcGUpID0+IHtcbiAgICAgICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsID0gKF9hID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHNjb3BlKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJyc7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSHVtYW5pdGFyaWFuU2NvcGVGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoc2NvcGUpLCB2YWwudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGhpZGUvc2hvdyBmaWVsZHMgb24gdmFsdWUgY2hhbmdlXG4gICAgICAgICAgICBodW1hbml0YXJpYW5TY29wZVZvY2FidWxhcnkub24oJ3NlbGVjdDI6c2VsZWN0JywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWwgPSBlLnBhcmFtcy5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSHVtYW5pdGFyaWFuU2NvcGVGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaW5kZXgpLCB2YWwpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBoaWRlL3Nob3cgZmllbGRzIG9uIHZhbHVlIGNsZWFyXG4gICAgICAgICAgICBodW1hbml0YXJpYW5TY29wZVZvY2FidWxhcnkub24oJ3NlbGVjdDI6Y2xlYXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSHVtYW5pdGFyaWFuU2NvcGVGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaW5kZXgpLCAnJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBoaWRlIGNvdW50cnkgYnVkZ2V0IGJhc2VkIG9uIHZvY2FidWxhcnlcbiAgICBoaWRlSHVtYW5pdGFyaWFuU2NvcGVGaWVsZChpbmRleCwgdmFsdWUpIHtcbiAgICAgICAgY29uc3QgaHVtYW5pdGFyaWFuU2NvcGVIaWRlVm9jYWJ1bGFyeVVyaSA9ICdpbnB1dFtpZF49XCJodW1hbml0YXJpYW5fc2NvcGVcIl1baWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXSc7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gJzk5Jykge1xuICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgIC5maW5kKGh1bWFuaXRhcmlhblNjb3BlSGlkZVZvY2FidWxhcnlVcmkpXG4gICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgIC5maW5kKGh1bWFuaXRhcmlhblNjb3BlSGlkZVZvY2FidWxhcnlVcmkpXG4gICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSHVtYW5pdGFyaWFuIFNjb3BlIEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgZmllbGQgYmFzZWQgb24gJ0B2b2NhYnVsYXJ5JyBmaWVsZCB2YWx1ZVxuICAgICAqL1xuICAgIGluZGljYXRvclJlZmVyZW5jZUhpZGVGaWVsZFVyaSgpIHtcbiAgICAgICAgY29uc3QgcmVmZXJlbmNlVm9jYWJ1bGFyeSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnc2VsZWN0W2lkXj1cInJlZmVyZW5jZVwiXVtpZCo9XCJbdm9jYWJ1bGFyeV1cIl0nKTtcbiAgICAgICAgaWYgKHJlZmVyZW5jZVZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gaGlkZSBmaWVsZHMgb24gcGFnZSBsb2FkXG4gICAgICAgICAgICBqcXVlcnlfMS5kZWZhdWx0LmVhY2gocmVmZXJlbmNlVm9jYWJ1bGFyeSwgKGluZGV4LCBzY29wZSkgPT4ge1xuICAgICAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWwgPSAoX2EgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoc2NvcGUpLnZhbCgpKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiAnJztcbiAgICAgICAgICAgICAgICB0aGlzLmluZGljYXRvclJlZmVyZW5jZUhpZGVGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoc2NvcGUpLCB2YWwudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGhpZGUvc2hvdyBmaWVsZHMgb24gdmFsdWUgY2hhbmdlXG4gICAgICAgICAgICByZWZlcmVuY2VWb2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOnNlbGVjdCcsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsID0gZS5wYXJhbXMuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaW5kaWNhdG9yUmVmZXJlbmNlSGlkZUZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KShpbmRleCksIHZhbCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGhpZGUvc2hvdyBmaWVsZHMgb24gdmFsdWUgY2xlYXJcbiAgICAgICAgICAgIHJlZmVyZW5jZVZvY2FidWxhcnkub24oJ3NlbGVjdDI6Y2xlYXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5pbmRpY2F0b3JSZWZlcmVuY2VIaWRlRmllbGQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGluZGV4KSwgJycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gaGlkZSBjb3VudHJ5IGJ1ZGdldCBiYXNlZCBvbiB2b2NhYnVsYXJ5XG4gICAgaW5kaWNhdG9yUmVmZXJlbmNlSGlkZUZpZWxkKGluZGV4LCB2YWx1ZSkge1xuICAgICAgICBjb25zdCByZWZlcmVuY2VVcmkgPSAnaW5wdXRbaWRePVwicmVmZXJlbmNlXCJdW2lkKj1cIltpbmRpY2F0b3JfdXJpXVwiXSc7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gJzk5Jykge1xuICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgIC5maW5kKHJlZmVyZW5jZVVyaSlcbiAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgLmZpbmQocmVmZXJlbmNlVXJpKVxuICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvdW50cnkgQnVkZ2V0IEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIHNob3cvaGlkZSAnY29kZScgZmllbGQgYmFzZWQgb24gJ0B2b2NhYnVsYXJ5JyBmaWVsZCB2YWx1ZVxuICAgICAqL1xuICAgIGNvdW50cnlCdWRnZXRIaWRlQ29kZUZpZWxkKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGNvbnN0IGNvdW50cnlCdWRnZXRWb2NhYnVsYXJ5ID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdzZWxlY3QjY291bnRyeV9idWRnZXRfdm9jYWJ1bGFyeScpO1xuICAgICAgICBpZiAoY291bnRyeUJ1ZGdldFZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gaGlkZS9zaG93IG9uIHBhZ2UgbG9hZFxuICAgICAgICAgICAgY29uc3QgdmFsID0gKF9hID0gY291bnRyeUJ1ZGdldFZvY2FidWxhcnkudmFsKCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6ICcxJztcbiAgICAgICAgICAgIHRoaXMuaGlkZUNvdW50cnlCdWRnZXRGaWVsZCh2YWwudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAvLyBoaWRlL3Nob3cgb24gdmFsdWUgY2hhbmdlXG4gICAgICAgICAgICBjb3VudHJ5QnVkZ2V0Vm9jYWJ1bGFyeS5vbignc2VsZWN0MjpzZWxlY3QnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbCA9IGUucGFyYW1zLmRhdGEuaWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ291bnRyeUJ1ZGdldEZpZWxkKHZhbCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vaGlkZS9zaG93IGJhc2VkIG9uIHZhbHVlIGNsZWFyZWRcbiAgICAgICAgICAgIGNvdW50cnlCdWRnZXRWb2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOmNsZWFyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUNvdW50cnlCdWRnZXRGaWVsZCgnJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIaWRlIENvdW50cnkgQnVkZ2V0IEZpZWxkc1xuICAgICAqL1xuICAgIGhpZGVDb3VudHJ5QnVkZ2V0RmllbGQodmFsdWUpIHtcbiAgICAgICAgY29uc3QgY291bnRyeUJ1ZGdldENvZGVJbnB1dCA9ICdpbnB1dFtpZF49XCJidWRnZXRfaXRlbVwiXVtpZCo9XCJbY29kZV90ZXh0XVwiXScsIGNvdW50cnlCdWRnZXRDb2RlU2VsZWN0ID0gJ3NlbGVjdFtpZF49XCJidWRnZXRfaXRlbVwiXVtpZCo9XCJbY29kZV1cIl0nO1xuICAgICAgICBpZiAodmFsdWUgPT09ICcxJykge1xuICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGNvdW50cnlCdWRnZXRDb2RlU2VsZWN0KVxuICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoY291bnRyeUJ1ZGdldENvZGVJbnB1dClcbiAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KShjb3VudHJ5QnVkZ2V0Q29kZVNlbGVjdClcbiAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KShjb3VudHJ5QnVkZ2V0Q29kZUlucHV0KVxuICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFpZFR5cGUgRm9ybSBQYWdlXG4gICAgICpcbiAgICAgKiBATG9naWMgaGlkZSB2b2NhYnVsYXJ5LXVyaSBhbmQgY29kZXMgZmllbGQgYmFzZWQgb24gJ0B2b2NhYnVsYXJ5JyBmaWVsZCB2YWx1ZVxuICAgICAqL1xuICAgIGFpZFR5cGVWb2NhYnVsYXJ5SGlkZUZpZWxkKCkge1xuICAgICAgICBjb25zdCBhaWR0eXBlX3ZvY2FidWxhcnkgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3NlbGVjdFtpZCo9XCJkZWZhdWx0X2FpZF90eXBlX3ZvY2FidWxhcnlcIl0nKTtcbiAgICAgICAgaWYgKGFpZHR5cGVfdm9jYWJ1bGFyeS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBqcXVlcnlfMS5kZWZhdWx0LmVhY2goYWlkdHlwZV92b2NhYnVsYXJ5LCAoaW5kZXgsIGl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IChfYSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KShpdGVtKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJzEnO1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUFpZFR5cGVTZWxlY3RGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaXRlbSksIGRhdGEudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGFpZHR5cGVfdm9jYWJ1bGFyeS5vbignc2VsZWN0MjpzZWxlY3QnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBlLnBhcmFtcy5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUFpZFR5cGVTZWxlY3RGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGFpZHR5cGVfdm9jYWJ1bGFyeS5vbignc2VsZWN0MjpjbGVhcicsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQWlkVHlwZVNlbGVjdEZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLCAnJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBaWRUeXBlIEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgYW5kIGNvZGVzIGZpZWxkIGJhc2VkIG9uICdAdm9jYWJ1bGFyeScgZmllbGQgdmFsdWVcbiAgICAgKi9cbiAgICB0cmFuc2FjdGlvbkFpZFR5cGVWb2NhYnVsYXJ5SGlkZUZpZWxkKCkge1xuICAgICAgICBjb25zdCBhaWR0eXBlX3ZvY2FidWxhcnkgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3NlbGVjdFtpZCo9XCJhaWRfdHlwZV92b2NhYnVsYXJ5XCJdJyk7XG4gICAgICAgIGlmIChhaWR0eXBlX3ZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAganF1ZXJ5XzEuZGVmYXVsdC5lYWNoKGFpZHR5cGVfdm9jYWJ1bGFyeSwgKGluZGV4LCBpdGVtKSA9PiB7XG4gICAgICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSAoX2EgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaXRlbSkudmFsKCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6ICcxJztcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUcmFuc2FjdGlvbkFpZFR5cGVTZWxlY3RGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaXRlbSksIGRhdGEudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGFpZHR5cGVfdm9jYWJ1bGFyeS5vbignc2VsZWN0MjpzZWxlY3QnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBlLnBhcmFtcy5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVRyYW5zYWN0aW9uQWlkVHlwZVNlbGVjdEZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLCBkYXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYWlkdHlwZV92b2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOmNsZWFyJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUcmFuc2FjdGlvbkFpZFR5cGVTZWxlY3RGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgJycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGlkZSBBaWQgVHlwZSBTZWxlY3QgRmllbGRzXG4gICAgICovXG4gICAgaGlkZUFpZFR5cGVTZWxlY3RGaWVsZChpbmRleCwgdmFsdWUpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdF9haWRfdHlwZSA9ICdzZWxlY3RbaWQqPVwiW2RlZmF1bHRfYWlkX3R5cGVdXCJdJywgZWFybWFya2luZ19jYXRlZ29yeSA9ICdzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfY2F0ZWdvcnldXCJdJywgZWFybWFya2luZ19tb2RhbGl0eSA9ICdzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfbW9kYWxpdHldXCJdJywgY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzID0gJ3NlbGVjdFtpZCo9XCJbY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzXVwiXScsIGNhc2UxID0gJ3NlbGVjdFtpZCo9XCJbZWFybWFya2luZ19jYXRlZ29yeV1cIl0sc2VsZWN0W2lkKj1cIltlYXJtYXJraW5nX21vZGFsaXR5XVwiXSxzZWxlY3RbaWQqPVwiW2Nhc2hfYW5kX3ZvdWNoZXJfbW9kYWxpdGllc11cIl0nLCBjYXNlMiA9ICdzZWxlY3RbaWQqPVwiW2RlZmF1bHRfYWlkX3R5cGVdXCJdLHNlbGVjdFtpZCo9XCJbZWFybWFya2luZ19tb2RhbGl0eV1cIl0sc2VsZWN0W2lkKj1cIltjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXNdXCJdJywgY2FzZTMgPSAnc2VsZWN0W2lkKj1cIltkZWZhdWx0X2FpZF90eXBlXVwiXSxzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfY2F0ZWdvcnldXCJdLHNlbGVjdFtpZCo9XCJbY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzXVwiXScsIGNhc2U0ID0gJ3NlbGVjdFtpZCo9XCJbZGVmYXVsdF9haWRfdHlwZV1cIl0sc2VsZWN0W2lkKj1cIltlYXJtYXJraW5nX2NhdGVnb3J5XVwiXSxzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfbW9kYWxpdHldXCJdJztcbiAgICAgICAgc3dpdGNoICh2YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSAnMic6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoZWFybWFya2luZ19jYXRlZ29yeSlcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMyc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoZWFybWFya2luZ19tb2RhbGl0eSlcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UzKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnNCc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTQpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGRlZmF1bHRfYWlkX3R5cGUpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMSlcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIaWRlIFRyYW5zYWN0aW9uIEFpZCBUeXBlIFNlbGVjdCBGaWVsZHNcbiAgICAgKi9cbiAgICBoaWRlVHJhbnNhY3Rpb25BaWRUeXBlU2VsZWN0RmllbGQoaW5kZXgsIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGFpZF90eXBlID0gJ3NlbGVjdFtpZCo9XCJbYWlkX3R5cGVfY29kZV1cIl0nLCBlYXJtYXJraW5nX2NhdGVnb3J5ID0gJ3NlbGVjdFtpZCo9XCJbZWFybWFya2luZ19jYXRlZ29yeV1cIl0nLCBlYXJtYXJraW5nX21vZGFsaXR5ID0gJ3NlbGVjdFtpZCo9XCJbZWFybWFya2luZ19tb2RhbGl0eV1cIl0nLCBjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXMgPSAnc2VsZWN0W2lkKj1cIltjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXNdXCJdJywgY2FzZTEgPSAnc2VsZWN0W2lkKj1cIltlYXJtYXJraW5nX2NhdGVnb3J5XVwiXSxzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfbW9kYWxpdHldXCJdLHNlbGVjdFtpZCo9XCJbY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzXVwiXScsIGNhc2UyID0gJ3NlbGVjdFtpZCo9XCJbYWlkX3R5cGVfY29kZV1cIl0sc2VsZWN0W2lkKj1cIltlYXJtYXJraW5nX21vZGFsaXR5XVwiXSxzZWxlY3RbaWQqPVwiW2Nhc2hfYW5kX3ZvdWNoZXJfbW9kYWxpdGllc11cIl0nLCBjYXNlMyA9ICdzZWxlY3RbaWQqPVwiW2FpZF90eXBlX2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbZWFybWFya2luZ19jYXRlZ29yeV1cIl0sc2VsZWN0W2lkKj1cIltjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXNdXCJdJywgY2FzZTQgPSAnc2VsZWN0W2lkKj1cIlthaWRfdHlwZV9jb2RlXVwiXSxzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfY2F0ZWdvcnldXCJdLHNlbGVjdFtpZCo9XCJbZWFybWFya2luZ19tb2RhbGl0eV1cIl0nO1xuICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlICcyJzpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChlYXJtYXJraW5nX2NhdGVnb3J5KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTIpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICczJzpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChlYXJtYXJraW5nX21vZGFsaXR5KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTMpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICc0JzpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXMpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlNClcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoYWlkX3R5cGUpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMSlcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBQb2xpY3kgTWFya2VyIEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgYW5kIGNvZGVzIGZpZWxkIGJhc2VkIG9uICdAdm9jYWJ1bGFyeScgZmllbGQgdmFsdWVcbiAgICAgKi9cbiAgICBwb2xpY3lWb2NhYnVsYXJ5SGlkZUZpZWxkKCkge1xuICAgICAgICBjb25zdCBwb2xpY3ltYWtlcl92b2NhYnVsYXJ5ID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdzZWxlY3RbaWQqPVwicG9saWN5X21hcmtlcl92b2NhYnVsYXJ5XCJdJyk7XG4gICAgICAgIGlmIChwb2xpY3ltYWtlcl92b2NhYnVsYXJ5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGpxdWVyeV8xLmRlZmF1bHQuZWFjaChwb2xpY3ltYWtlcl92b2NhYnVsYXJ5LCAoaW5kZXgsIHBvbGljeV9tYXJrZXIpID0+IHtcbiAgICAgICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IChfYSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KShwb2xpY3lfbWFya2VyKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJzEnO1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVBvbGljeU1ha2VyRmllbGQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHBvbGljeV9tYXJrZXIpLCBkYXRhLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwb2xpY3ltYWtlcl92b2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOnNlbGVjdCcsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IGUucGFyYW1zLmRhdGEuaWQ7XG4gICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlUG9saWN5TWFrZXJGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBvbGljeW1ha2VyX3ZvY2FidWxhcnkub24oJ3NlbGVjdDI6Y2xlYXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVBvbGljeU1ha2VyRmllbGQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCksICc5OScpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGlkZXMgUG9saWN5IE1hcmtlciBGb3JtIEZpZWxkc1xuICAgICAqL1xuICAgIGhpZGVQb2xpY3lNYWtlckZpZWxkKGluZGV4LCB2YWx1ZSkge1xuICAgICAgICBjb25zdCBjYXNlMV9zaG93ID0gJ3NlbGVjdFtpZCo9XCJbcG9saWN5X21hcmtlcl1cIl0nLCBjYXNlMl9zaG93ID0gJ2lucHV0W2lkKj1cIltwb2xpY3lfbWFya2VyX3RleHRdXCJdLGlucHV0W2lkKj1cIlt2b2NhYnVsYXJ5X3VyaV1cIl0nLCBjYXNlMSA9ICdpbnB1dFtpZCo9XCJbcG9saWN5X21hcmtlcl90ZXh0XVwiXSxpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJywgY2FzZTIgPSAnc2VsZWN0W2lkKj1cIltwb2xpY3lfbWFya2VyXVwiXSc7XG4gICAgICAgIHN3aXRjaCAodmFsdWUpIHtcbiAgICAgICAgICAgIGNhc2UgJzEnOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UxX3Nob3cpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMSlcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJzk5JzpcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTJfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlY3RvciBGb3JtIFBhZ2VcbiAgICAgKlxuICAgICAqIEBMb2dpYyBoaWRlIHZvY2FidWxhcnktdXJpIGFuZCBjb2RlcyBmaWVsZCBiYXNlZCBvbiAnQHZvY2FidWxhcnknIGZpZWxkIHZhbHVlXG4gICAgICovXG4gICAgc2VjdG9yVm9jYWJ1bGFyeUhpZGVGaWVsZCgpIHtcbiAgICAgICAgY29uc3Qgc2VjdG9yX3ZvY2FidWxhcnkgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3NlbGVjdFtpZCo9XCJzZWN0b3Jfdm9jYWJ1bGFyeVwiXScpO1xuICAgICAgICBpZiAoc2VjdG9yX3ZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAganF1ZXJ5XzEuZGVmYXVsdC5lYWNoKHNlY3Rvcl92b2NhYnVsYXJ5LCAoaW5kZXgsIHNlY3RvcikgPT4ge1xuICAgICAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gKF9hID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHNlY3RvcikudmFsKCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6ICcxJztcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVTZWN0b3JGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoc2VjdG9yKSwgZGF0YS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2VjdG9yX3ZvY2FidWxhcnkub24oJ3NlbGVjdDI6c2VsZWN0JywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gZS5wYXJhbXMuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVTZWN0b3JGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHNlY3Rvcl92b2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOmNsZWFyJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVTZWN0b3JGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgJycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGlkZSBTZWN0b3IgRm9ybSBmaWVsZHNcbiAgICAgKi9cbiAgICBoaWRlU2VjdG9yRmllbGQoaW5kZXgsIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGNhc2UxX3Nob3cgPSAnc2VsZWN0W2lkKj1cIltjb2RlXVwiXScsIGNhc2UyX3Nob3cgPSAnc2VsZWN0W2lkKj1cIltjYXRlZ29yeV9jb2RlXVwiXScsIGNhc2U3X3Nob3cgPSAnc2VsZWN0W2lkKj1cIltzZGdfZ29hbF1cIl0nLCBjYXNlOF9zaG93ID0gJ3NlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0nLCBjYXNlOThfOTlfc2hvdyA9ICdpbnB1dFtpZCo9XCJbdGV4dF1cIl0saW5wdXRbaWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXScsIGRlZmF1bHRfc2hvdyA9ICdpbnB1dFtpZCo9XCJbdGV4dF1cIl0nLCBjYXNlMSA9ICdzZWxlY3RbaWQqPVwiW2NhdGVnb3J5X2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX2dvYWxdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0saW5wdXRbaWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXSxpbnB1dFtpZCo9XCJbdGV4dF1cIl0nLCBjYXNlMiA9ICdpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdLHNlbGVjdFtpZCo9XCJbc2RnX2dvYWxdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0sc2VsZWN0W2lkKj1cIltjb2RlXVwiXSxpbnB1dFtpZCo9XCJbdGV4dF1cIl0nLCBjYXNlNyA9ICdpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdLHNlbGVjdFtpZCo9XCJbY2F0ZWdvcnlfY29kZV1cIl0sc2VsZWN0W2lkKj1cIltzZGdfdGFyZ2V0XVwiXSxzZWxlY3RbaWQqPVwiW2NvZGVdXCJdLGlucHV0W2lkKj1cIlt0ZXh0XVwiXScsIGNhc2U4ID0gJ2lucHV0W2lkKj1cIlt2b2NhYnVsYXJ5X3VyaV1cIl0sc2VsZWN0W2lkKj1cIltjYXRlZ29yeV9jb2RlXVwiXSxzZWxlY3RbaWQqPVwiW3NkZ19nb2FsXVwiXSxzZWxlY3RbaWQqPVwiW2NvZGVdXCJdLGlucHV0W2lkKj1cIlt0ZXh0XVwiXScsIGNhc2U5OF85OSA9ICdzZWxlY3RbaWQqPVwiW2NhdGVnb3J5X2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX2dvYWxdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0sc2VsZWN0W2lkKj1cIltjb2RlXVwiXScsIGRlZmF1bHRfaGlkZSA9ICdzZWxlY3RbaWQqPVwiW2NhdGVnb3J5X2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX2dvYWxdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0sc2VsZWN0W2lkKj1cIltjb2RlXVwiXSxpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJztcbiAgICAgICAgc3dpdGNoICh2YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSAnMSc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTFfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UxKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMic6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTJfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnNyc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTdfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U3KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOCc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZThfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U4KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOTgnOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U5OF85OV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTk4Xzk5KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOTknOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U5OF85OV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTk4Xzk5KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChkZWZhdWx0X3Nob3cpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChkZWZhdWx0X2hpZGUpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogIFJlY2lwaWVudCBWb2NhYnVsYXJ5IEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgYW5kIGNvZGVzIGZpZWxkIGJhc2VkIG9uICdAdm9jYWJ1bGFyeScgZmllbGQgdmFsdWVcbiAgICAgKi9cbiAgICByZWNpcGllbnRWb2NhYnVsYXJ5SGlkZUZpZWxkKCkge1xuICAgICAgICBjb25zdCByZWdpb25fdm9jYWJ1bGFyeSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnc2VsZWN0W2lkKj1cInJlZ2lvbl92b2NhYnVsYXJ5XCJdJyk7XG4gICAgICAgIGlmIChyZWdpb25fdm9jYWJ1bGFyeS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBqcXVlcnlfMS5kZWZhdWx0LmVhY2gocmVnaW9uX3ZvY2FidWxhcnksIChpbmRleCwgcmVnaW9uX3ZvY2FiKSA9PiB7XG4gICAgICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSAoX2EgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkocmVnaW9uX3ZvY2FiKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJzEnO1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVJlY2lwaWVudFJlZ2lvbkZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KShyZWdpb25fdm9jYWIpLCBkYXRhLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZWdpb25fdm9jYWJ1bGFyeS5vbignc2VsZWN0MjpzZWxlY3QnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBlLnBhcmFtcy5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVJlY2lwaWVudFJlZ2lvbkZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLCBkYXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVnaW9uX3ZvY2FidWxhcnkub24oJ3NlbGVjdDI6Y2xlYXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVJlY2lwaWVudFJlZ2lvbkZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLCAnJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIaWRlcyBSZWNpcGllbnQgUmVnaW9uIEZvcm0gRmllbGRzXG4gICAgICovXG4gICAgaGlkZVJlY2lwaWVudFJlZ2lvbkZpZWxkKGluZGV4LCB2YWx1ZSkge1xuICAgICAgICBjb25zdCBjYXNlMV9zaG93ID0gJ3NlbGVjdFtpZCo9XCJbcmVnaW9uX2NvZGVdXCJdJywgY2FzZTJfc2hvdyA9ICdpbnB1dFtpZCo9XCJbY3VzdG9tX2NvZGVdXCJdLCBpbnB1dFtpZCo9XCJbY29kZV1cIl0nLCBjYXNlOTlfc2hvdyA9ICdpbnB1dFtpZCo9XCJbY3VzdG9tX2NvZGVdXCJdLGlucHV0W2lkKj1cIlt2b2NhYnVsYXJ5X3VyaV1cIl0sIGlucHV0W2lkKj1cIltjb2RlXVwiXScsIGNhc2UxID0gJ2lucHV0W2lkKj1cIltjdXN0b21fY29kZV1cIl0saW5wdXRbaWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXSxpbnB1dFtpZCo9XCJbY29kZV1cIl0nLCBjYXNlMiA9ICdzZWxlY3RbaWQqPVwiW3JlZ2lvbl9jb2RlXVwiXSxpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJywgY2FzZTk5ID0gJ3NlbGVjdFtpZCo9XCJbcmVnaW9uX2NvZGVdXCJdJztcbiAgICAgICAgc3dpdGNoICh2YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSAnMSc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTFfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UxKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMic6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTJfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOTknOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U5OV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTk5KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMl9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTIpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlcyBBY3Rpdml0eSBpZGVudGlmaWVyXG4gICAgICovXG4gICAgdXBkYXRlQWN0aXZpdHlJZGVudGlmaWVyKCkge1xuICAgICAgICBjb25zdCBhY3Rpdml0eV9pZGVudGlmaWVyID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjYWN0aXZpdHlfaWRlbnRpZmllcicpO1xuICAgICAgICBpZiAoYWN0aXZpdHlfaWRlbnRpZmllci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBhY3Rpdml0eV9pZGVudGlmaWVyLm9uKCdrZXl1cCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJyNpYXRpX2lkZW50aWZpZXJfdGV4dCcpLnZhbCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5pZGVudGlmaWVyJykuYXR0cignYWN0aXZpdHlfaWRlbnRpZmllcicpICsgYC0keygwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS52YWwoKX1gKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRhZyBGb3JtIFBhZ2VcbiAgICAgKlxuICAgICAqIEBMb2dpYyBoaWRlIHZvY2FidWxhcnktdXJpIGFuZCBjb2RlcyBmaWVsZCBiYXNlZCBvbiAnQHZvY2FidWxhcnknIGZpZWxkIHZhbHVlXG4gICAgICovXG4gICAgdGFnVm9jYWJ1bGFyeUhpZGVGaWVsZCgpIHtcbiAgICAgICAgY29uc3QgdGFnX3ZvY2FidWxhcnkgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3NlbGVjdFtpZCo9XCJ0YWdfdm9jYWJ1bGFyeVwiXScpO1xuICAgICAgICBpZiAodGFnX3ZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAganF1ZXJ5XzEuZGVmYXVsdC5lYWNoKHRhZ192b2NhYnVsYXJ5LCAoaW5kZXgsIHRhZykgPT4ge1xuICAgICAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gKF9hID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhZykudmFsKCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6ICcxJztcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUYWdGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFnKSwgZGF0YS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGFnX3ZvY2FidWxhcnkub24oJ3NlbGVjdDI6c2VsZWN0JywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gZS5wYXJhbXMuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUYWdGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRhZ192b2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOmNsZWFyJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUYWdGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgJycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGlkZSBUYWcgRm9ybSBmaWVsZHNcbiAgICAgKi9cbiAgICBoaWRlVGFnRmllbGQoaW5kZXgsIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGNhc2UxX3Nob3cgPSAnaW5wdXRbaWQqPVwiW3RhZ190ZXh0XVwiXScsIGNhc2UyX3Nob3cgPSAnc2VsZWN0W2lkKj1cIltnb2Fsc190YWdfY29kZV1cIl0nLCBjYXNlM19zaG93ID0gJ3NlbGVjdFtpZCo9XCJbdGFyZ2V0c190YWdfY29kZV1cIl0nLCBjYXNlOTlfc2hvdyA9ICdpbnB1dFtpZCo9XCJbdGFnX3RleHRdXCJdLCBpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJywgY2FzZTEgPSAnc2VsZWN0W2lkKj1cIltnb2Fsc190YWdfY29kZV1cIl0sc2VsZWN0W2lkKj1cIlt0YXJnZXRzX3RhZ19jb2RlXVwiXSxpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJywgY2FzZTIgPSAnaW5wdXRbaWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXSxzZWxlY3RbaWQqPVwiW3RhcmdldHNfdGFnX2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbdGFyZ2V0c190YWdfY29kZV1cIl0saW5wdXRbaWQqPVwiW3RhZ190ZXh0XVwiXScsIGNhc2UzID0gJ2lucHV0W2lkKj1cIlt2b2NhYnVsYXJ5X3VyaV1cIl0sc2VsZWN0W2lkKj1cIltnb2Fsc190YWdfY29kZV1cIl0saW5wdXRbaWQqPVwiW3RhZ190ZXh0XVwiXScsIGNhc2U5OSA9ICdzZWxlY3RbaWQqPVwiW2dvYWxzX3RhZ19jb2RlXVwiXSxzZWxlY3RbaWQqPVwiW3RhcmdldHNfdGFnX2NvZGVdXCJdJztcbiAgICAgICAgc3dpdGNoICh2YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSAnMSc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTFfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UxKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMic6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTJfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMyc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTNfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UzKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOTknOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U5OV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTk5KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTEpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnRzLkR5bmFtaWNGaWVsZCA9IER5bmFtaWNGaWVsZDtcbi8qXG4gKlxuICogSGVscCBUZXh0IE9wZW4gQ2xvc2UgSGFuZGxlcnMgU3RhcnRcbiAqXG4gKi9cbigwLCBqcXVlcnlfMS5kZWZhdWx0KShkb2N1bWVudCkub24oJ2NsaWNrJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKCEoMCwganF1ZXJ5XzEuZGVmYXVsdCkoZXZlbnQudGFyZ2V0KS5jbG9zZXN0KCcuaGVscCcpLmxlbmd0aCkge1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5oZWxwX190ZXh0JykucmVtb3ZlQXR0cignc3R5bGUnKTtcbiAgICB9XG59KTtcbigwLCBqcXVlcnlfMS5kZWZhdWx0KShkb2N1bWVudCkub24oJ2NsaWNrJywgJy5oZWxwJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgLyogZXNsaW50LWRpc2FibGUgKi8gY29uc29sZS5sb2coLi4ub29fb28oYDc5NjMyMjg0M185ODlfMl85ODlfMjJfNGAsICdIZWxsbycpKTtcbiAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5oZWxwX190ZXh0JykucmVtb3ZlQXR0cignc3R5bGUnKTtcbiAgICBjb25zdCBoZWxwVGV4dCA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS5maW5kKCcuaGVscF9fdGV4dCcpO1xuICAgIGlmIChoZWxwVGV4dC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGhlbHBUZXh0LmNzcyh7XG4gICAgICAgICAgICBvcGFjaXR5OiAnMScsXG4gICAgICAgICAgICB2aXNpYmlsaXR5OiAndmlzaWJsZScsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGV2ZW50LnRhcmdldCkuY2xvc2VzdCgnLmNsb3NlLWhlbHAnKS5sZW5ndGgpIHtcbiAgICAgICAgY2xvc2VIZWxwVGV4dChoZWxwVGV4dCk7XG4gICAgfVxufSk7XG4oMCwganF1ZXJ5XzEuZGVmYXVsdCkoZG9jdW1lbnQpLm9uKCdrZXlkb3duJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VzY2FwZScpIHtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuaGVscF9fdGV4dCcpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY2xvc2VIZWxwVGV4dCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcykpO1xuICAgICAgICB9KTtcbiAgICB9XG59KTtcbi8qKlxuICogQ2xvc2VzIHRoZSBoZWxwIHRleHQgdG9vbHRpcCBieSBzZXR0aW5nIGl0cyBDU1MgcHJvcGVydGllcyB0byBtYWtlIGl0IGludmlzaWJsZSBhbmQgbm9uLWludGVyYWN0aXZlLlxuICogQWZ0ZXIgYSBkZWxheSwgaXQgcmVtb3ZlcyB0aGUgaW5saW5lIHN0eWxlcyB0byByZXNldCB0aGUgZWxlbWVudCdzIHN0YXRlLlxuICpcbiAqIEBwYXJhbSBoZWxwVGV4dCAtIFRoZSBqUXVlcnkgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgdG9vbHRpcCBlbGVtZW50IHRvIGJlIGNsb3NlZC5cbiAqL1xuZnVuY3Rpb24gY2xvc2VIZWxwVGV4dChoZWxwVGV4dCkge1xuICAgIGhlbHBUZXh0LmNzcyh7XG4gICAgICAgICdwb2ludGVyLWV2ZW50cyc6ICdub25lJyxcbiAgICAgICAgb3BhY2l0eTogJzAnLFxuICAgICAgICB2aXNpYmlsaXR5OiAnaW52aXNpYmxlJyxcbiAgICB9KTtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaGVscFRleHQucmVtb3ZlQXR0cignc3R5bGUnKTtcbiAgICB9LCAxMDAwKTtcbn1cbi8qXG4gKlxuICogSGVscCBUZXh0IE9wZW4gQ2xvc2UgSGFuZGxlcnMgRW5kXG4gKlxuICovXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyAvKiBjOCBpZ25vcmUgc3RhcnQgKi8gLyogZXNsaW50LWRpc2FibGUgKi8gO1xuZnVuY3Rpb24gb29fY20oKSB7IHRyeSB7XG4gICAgcmV0dXJuICgwLCBldmFsKShcImdsb2JhbFRoaXMuX2NvbnNvbGVfbmluamFcIikgfHwgKDAsIGV2YWwpKFwiLyogaHR0cHM6Ly9naXRodWIuY29tL3dhbGxhYnlqcy9jb25zb2xlLW5pbmphI2hvdy1kb2VzLWl0LXdvcmsgKi8ndXNlIHN0cmljdCc7dmFyIF8weDMxZTQ4Nj1fMHgzM2IyO2Z1bmN0aW9uIF8weDMzYjIoXzB4MmQxNjE1LF8weDI5Y2NiNCl7dmFyIF8weDM0ZTlmMz1fMHgzNGU5KCk7cmV0dXJuIF8weDMzYjI9ZnVuY3Rpb24oXzB4MzNiMjNiLF8weDM5M2E3NCl7XzB4MzNiMjNiPV8weDMzYjIzYi0weDE0NTt2YXIgXzB4NDEyNzJkPV8weDM0ZTlmM1tfMHgzM2IyM2JdO3JldHVybiBfMHg0MTI3MmQ7fSxfMHgzM2IyKF8weDJkMTYxNSxfMHgyOWNjYjQpO31mdW5jdGlvbiBfMHgzNGU5KCl7dmFyIF8weDE3MDRmMj1bJ2V4cElkJywnc2V0dGVyJywnbm9kZU1vZHVsZXMnLCdpbmRleCcsJ19hZGRPYmplY3RQcm9wZXJ0eScsJ3RyYWNlJywnSFRNTEFsbENvbGxlY3Rpb24nLCdzb3J0UHJvcHMnLCdkYXRlJywnX2lzVW5kZWZpbmVkJywncmVwbGFjZScsJzEnLCd2ZXJzaW9ucycsJ19wcm9wZXJ0eU5hbWUnLCdfYWRkUHJvcGVydHknLCdfZGlzcG9zZVdlYnNvY2tldCcsJ2F1dG9FeHBhbmRQcm9wZXJ0eUNvdW50JywnX2luTmV4dEVkZ2UnLCdsb2dnZXJcXFxceDIwZmFpbGVkXFxcXHgyMHRvXFxcXHgyMGNvbm5lY3RcXFxceDIwdG9cXFxceDIwaG9zdCcsJ3NsaWNlJywnbG9jYXRpb24nLCdkZWZpbmVQcm9wZXJ0eScsJ19rZXlTdHJSZWdFeHAnLCdzeW1ib2wnLCdbb2JqZWN0XFxcXHgyMFNldF0nLCdfcF8nLCdbb2JqZWN0XFxcXHgyMEFycmF5XScsJ3Byb2Nlc3MnLCdwcm9wcycsJ19zZW5kRXJyb3JNZXNzYWdlJywnc3RyaW5nJywnbnVsbCcsJ29iamVjdCcsJ19nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3InLCdsb2cnLCdfYWRkaXRpb25hbE1ldGFkYXRhJywnYmluZCcsJ3BlcmZvcm1hbmNlJywnMjkxME55VkNRRCcsJ2xldmVsJywnaW5jbHVkZXMnLCdlbGFwc2VkJywnX2Nvbm5lY3RUb0hvc3ROb3cnLCdjYWxsJywncHVzaCcsJ2Z1bmN0aW9uJywndG90YWxTdHJMZW5ndGgnLCdocnRpbWUnLCdfY29uc29sZV9uaW5qYV9zZXNzaW9uJywndGltZVN0YW1wJywnZnJvbUNoYXJDb2RlJywnYXV0b0V4cGFuZE1heERlcHRoJywnd3M6Ly8nLCdfbnVtYmVyUmVnRXhwJywnUE9TSVRJVkVfSU5GSU5JVFknLCdfc2V0Tm9kZUV4cHJlc3Npb25QYXRoJywnbnVtYmVyJywnam9pbicsJ2NhcHBlZFByb3BzJywnb25tZXNzYWdlJywnYmlnaW50JywnX2lzUHJpbWl0aXZlV3JhcHBlclR5cGUnLCd0aGVuJywnX3NvcnRQcm9wcycsJ2VudicsJ25vRnVuY3Rpb25zJywnX3F1b3RlZFJlZ0V4cCcsJ2xvZ2dlclxcXFx4MjBmYWlsZWRcXFxceDIwdG9cXFxceDIwY29ubmVjdFxcXFx4MjB0b1xcXFx4MjBob3N0LFxcXFx4MjBzZWVcXFxceDIwJywnY29uY2F0JywnZW5kc1dpdGgnLCdwZXJmX2hvb2tzJywnYWxsU3RyTGVuZ3RoJywnX25pbmphSWdub3JlTmV4dEVycm9yJywnaGl0cycsJ2lzRXhwcmVzc2lvblRvRXZhbHVhdGUnLCdfYWRkTG9hZE5vZGUnLCdhc3RybycsJ19zb2NrZXQnLCdfdHJlZU5vZGVQcm9wZXJ0aWVzQmVmb3JlRnVsbFZhbHVlJywncHJvdG90eXBlJywnX29iamVjdFRvU3RyaW5nJywnX3dzJywnODM3NDQ3OFB0Y2FqaicsJ2NhcHBlZCcsJ3RpbWUnLCc4MTQ2MGduTXNhQycsJ0NvbnNvbGVcXFxceDIwTmluamFcXFxceDIwZmFpbGVkXFxcXHgyMHRvXFxcXHgyMHNlbmRcXFxceDIwbG9ncyxcXFxceDIwcmVmcmVzaGluZ1xcXFx4MjB0aGVcXFxceDIwcGFnZVxcXFx4MjBtYXlcXFxceDIwaGVscDtcXFxceDIwYWxzb1xcXFx4MjBzZWVcXFxceDIwJywndGVzdCcsJ193ZWJTb2NrZXRFcnJvckRvY3NMaW5rJywnZGlzYWJsZWRMb2cnLCdzdWJzdHInLCdtZXNzYWdlJywnTkVHQVRJVkVfSU5GSU5JVFknLCdjb25zdHJ1Y3RvcicsJ2N1cnJlbnQnLCdzdHJMZW5ndGgnLCdhdXRvRXhwYW5kUHJldmlvdXNPYmplY3RzJywnMjY5NTg4MHp6YnhoWCcsJ3VybCcsJ3Jvb3RFeHByZXNzaW9uJywndmFsdWUnLCdtZXRob2QnLCd0eXBlJywnb25lcnJvcicsJ19zZXROb2RlUGVybWlzc2lvbnMnLCd0b1N0cmluZycsJ19fZXMnKydNb2R1bGUnLCdwYXRoJywnMzM0NTMnLCdfbWF4Q29ubmVjdEF0dGVtcHRDb3VudCcsJ19XZWJTb2NrZXRDbGFzcycsJzEyOTZFcG1NbHUnLCdlbGVtZW50cycsJycsJ0Vycm9yJywnX3BfbGVuZ3RoJywnY291bnQnLCdyZWR1Y2VMaW1pdHMnLCdsZW5ndGgnLCdbb2JqZWN0XFxcXHgyME1hcF0nLCdfaXNOZWdhdGl2ZVplcm8nLCdfZ2V0T3duUHJvcGVydHlOYW1lcycsJ190cmVlTm9kZVByb3BlcnRpZXNBZnRlckZ1bGxWYWx1ZScsJ19wcm9wZXJ0eScsJ2RlZmF1bHQnLCdfaXNQcmltaXRpdmVUeXBlJywnX2JsYWNrbGlzdGVkUHJvcGVydHknLCdTZXQnLCd2YWx1ZU9mJywnZ2V0JywncGF0aFRvRmlsZVVSTCcsJ25hbWUnLCdDb25zb2xlXFxcXHgyME5pbmphXFxcXHgyMGZhaWxlZFxcXFx4MjB0b1xcXFx4MjBzZW5kXFxcXHgyMGxvZ3MsXFxcXHgyMHJlc3RhcnRpbmdcXFxceDIwdGhlXFxcXHgyMHByb2Nlc3NcXFxceDIwbWF5XFxcXHgyMGhlbHA7XFxcXHgyMGFsc29cXFxceDIwc2VlXFxcXHgyMCcsJ25lZ2F0aXZlSW5maW5pdHknLCdlbnVtZXJhYmxlJywnY2FwcGVkRWxlbWVudHMnLCdcXFxceDIwc2VydmVyJywnU3ltYm9sJywnb3JpZ2luJywnb25jbG9zZScsJ3JlYWR5U3RhdGUnLCd3YXJuJywnX3NldE5vZGVFeHBhbmRhYmxlU3RhdGUnLCdjYXRjaCcsJ2Nsb3NlJywnd2VicGFjaycsJ2hvc3QnLCdwb3NpdGl2ZUluZmluaXR5JywnX2Nvbm5lY3RBdHRlbXB0Q291bnQnLCdNYXAnLCdfZGF0ZVRvU3RyaW5nJywnZm9yRWFjaCcsJ29ub3BlbicsJ2NvbnNvbGUnLCdfYWRkRnVuY3Rpb25zTm9kZScsJ3dzL2luZGV4LmpzJywnZ2V0V2ViU29ja2V0Q2xhc3MnLCdyb290X2V4cF9pZCcsJ3N0YWNrJywnX3BfbmFtZScsJ2FycmF5JywnX2F0dGVtcHRUb1JlY29ubmVjdFNob3J0bHknLCcxMTYyMnVtZndYeScsJ2Jvb2xlYW4nLCc0MjY1NmtqZ1pKWicsJ3VuZGVmaW5lZCcsJ190eXBlJywndG9VcHBlckNhc2UnLCdzZXQnLCdhdXRvRXhwYW5kJywnX3NldE5vZGVMYWJlbCcsJ2dldHRlcicsJ19hbGxvd2VkVG9Db25uZWN0T25TZW5kJywnbWFwJywnX2luQnJvd3NlcicsJ19wcm9jZXNzVHJlZU5vZGVSZXN1bHQnLCdfY29ubmVjdGVkJywncGFyZW50JywncGFyc2UnLCdhcmdzJywnc3RyaW5naWZ5JywnZGF0YScsJ19nZXRPd25Qcm9wZXJ0eVN5bWJvbHMnLCd1bnJlZicsJ19TeW1ib2wnLCdORVhUX1JVTlRJTUUnLCdob3N0bmFtZScsJ191bmRlZmluZWQnLCd0b0xvd2VyQ2FzZScsXFxcIi9ob21lL2ZsdWZmeS8udnNjb2RlL2V4dGVuc2lvbnMvd2FsbGFieWpzLmNvbnNvbGUtbmluamEtMS4wLjM4Mi9ub2RlX21vZHVsZXNcXFwiLCdTdHJpbmcnLCdSZWdFeHAnLCdfV2ViU29ja2V0JywnMS4wLjAnLCdtYXRjaCcsJ19jb25uZWN0aW5nJywnZ2V0T3duUHJvcGVydHlTeW1ib2xzJywnZ2xvYmFsJywnZXJyb3InLCdfaXNNYXAnLCcxOTgxNTgxV09pQ1h1JywnX2lzQXJyYXknLCdleHByZXNzaW9uc1RvRXZhbHVhdGUnLCdkZXB0aCcsJ2V2ZW50UmVjZWl2ZWRDYWxsYmFjaycsJ19hbGxvd2VkVG9TZW5kJywnbm9kZScsJ2RvY2tlcml6ZWRBcHAnLCd1bnNoaWZ0JywnYXV0b0V4cGFuZExpbWl0JywnZ2V0T3duUHJvcGVydHlOYW1lcycsJ19jbGVhbk5vZGUnLCdfcmVjb25uZWN0VGltZW91dCcsJ19yZWdFeHBUb1N0cmluZycsJ3N0YWNrVHJhY2VMaW1pdCcsJ3Vua25vd24nLCdzZXJpYWxpemUnLCdlZGdlJywncG9ydCcsJ19IVE1MQWxsQ29sbGVjdGlvbicsW1xcXCJsb2NhbGhvc3RcXFwiLFxcXCIxMjcuMC4wLjFcXFwiLFxcXCJleGFtcGxlLmN5cHJlc3MuaW9cXFwiLFxcXCJmbHVmZnlcXFwiLFxcXCIxOTIuMTY4LjEwLjE3NlxcXCJdLCdfY29uc29sZV9uaW5qYScsJ19pc1NldCcsJ3JlbWl4JywnX2hhc01hcE9uSXRzUGF0aCcsJ3NlZVxcXFx4MjBodHRwczovL3Rpbnl1cmwuY29tLzJ2dDhqeHp3XFxcXHgyMGZvclxcXFx4MjBtb3JlXFxcXHgyMGluZm8uJywnXFxcXHgyMGJyb3dzZXInLCdmYWlsZWRcXFxceDIwdG9cXFxceDIwZmluZFxcXFx4MjBhbmRcXFxceDIwbG9hZFxcXFx4MjBXZWJTb2NrZXQnLCdzb21lJywnbm93JywnbmV4dC5qcycsJ19jb25zb2xlTmluamFBbGxvd2VkVG9TdGFydCcsJzU3NDYwMG9wYVdxeicsJ3NlbmQnLCdfY2FwSWZTdHJpbmcnXTtfMHgzNGU5PWZ1bmN0aW9uKCl7cmV0dXJuIF8weDE3MDRmMjt9O3JldHVybiBfMHgzNGU5KCk7fShmdW5jdGlvbihfMHg0OWU3MTksXzB4MmI0YmM4KXt2YXIgXzB4ZWM2MzBjPV8weDMzYjIsXzB4NTFmM2MyPV8weDQ5ZTcxOSgpO3doaWxlKCEhW10pe3RyeXt2YXIgXzB4M2JjOTJjPXBhcnNlSW50KF8weGVjNjMwYygweDE5YikpLzB4MSstcGFyc2VJbnQoXzB4ZWM2MzBjKDB4MjJlKSkvMHgyK3BhcnNlSW50KF8weGVjNjMwYygweDIwZSkpLzB4MystcGFyc2VJbnQoXzB4ZWM2MzBjKDB4MWE3KSkvMHg0Ky1wYXJzZUludChfMHhlYzYzMGMoMHgxNmMpKS8weDUqKHBhcnNlSW50KF8weGVjNjMwYygweDFlOCkpLzB4NikrcGFyc2VJbnQoXzB4ZWM2MzBjKDB4MTk4KSkvMHg3K3BhcnNlSW50KF8weGVjNjMwYygweDFlYSkpLzB4OCoocGFyc2VJbnQoXzB4ZWM2MzBjKDB4MWI1KSkvMHg5KTtpZihfMHgzYmM5MmM9PT1fMHgyYjRiYzgpYnJlYWs7ZWxzZSBfMHg1MWYzYzJbJ3B1c2gnXShfMHg1MWYzYzJbJ3NoaWZ0J10oKSk7fWNhdGNoKF8weDIyODY5ZSl7XzB4NTFmM2MyWydwdXNoJ10oXzB4NTFmM2MyWydzaGlmdCddKCkpO319fShfMHgzNGU5LDB4OTZjNDkpKTt2YXIgSz1PYmplY3RbJ2NyZWF0ZSddLFE9T2JqZWN0W18weDMxZTQ4NigweDE1YildLEc9T2JqZWN0WydnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3InXSxlZT1PYmplY3RbXzB4MzFlNDg2KDB4MjE4KV0sdGU9T2JqZWN0WydnZXRQcm90b3R5cGVPZiddLG5lPU9iamVjdFsncHJvdG90eXBlJ11bJ2hhc093blByb3BlcnR5J10scmU9KF8weDI4OWNmMCxfMHgxNzMyM2MsXzB4MTJkNjNjLF8weDFlOWI2ZCk9Pnt2YXIgXzB4Mzc0MmRhPV8weDMxZTQ4NjtpZihfMHgxNzMyM2MmJnR5cGVvZiBfMHgxNzMyM2M9PV8weDM3NDJkYSgweDE2Nil8fHR5cGVvZiBfMHgxNzMyM2M9PV8weDM3NDJkYSgweDE3Mykpe2ZvcihsZXQgXzB4MzBjOGU5IG9mIGVlKF8weDE3MzIzYykpIW5lW18weDM3NDJkYSgweDE3MSldKF8weDI4OWNmMCxfMHgzMGM4ZTkpJiZfMHgzMGM4ZTkhPT1fMHgxMmQ2M2MmJlEoXzB4Mjg5Y2YwLF8weDMwYzhlOSx7J2dldCc6KCk9Pl8weDE3MzIzY1tfMHgzMGM4ZTldLCdlbnVtZXJhYmxlJzohKF8weDFlOWI2ZD1HKF8weDE3MzIzYyxfMHgzMGM4ZTkpKXx8XzB4MWU5YjZkW18weDM3NDJkYSgweDFjYyldfSk7fXJldHVybiBfMHgyODljZjA7fSxWPShfMHg0ZDQzYjMsXzB4MjhjNjk5LF8weDNlNGViYyk9PihfMHgzZTRlYmM9XzB4NGQ0M2IzIT1udWxsP0sodGUoXzB4NGQ0M2IzKSk6e30scmUoXzB4MjhjNjk5fHwhXzB4NGQ0M2IzfHwhXzB4NGQ0M2IzW18weDMxZTQ4NigweDFiMCldP1EoXzB4M2U0ZWJjLF8weDMxZTQ4NigweDFjMikseyd2YWx1ZSc6XzB4NGQ0M2IzLCdlbnVtZXJhYmxlJzohMHgwfSk6XzB4M2U0ZWJjLF8weDRkNDNiMykpLFo9Y2xhc3N7Y29uc3RydWN0b3IoXzB4MTkwYWE4LF8weDQ4YjUxOSxfMHgxZjFkZGQsXzB4MmE0OWY4LF8weGRkNDQ4YSxfMHgyNmJhZWUpe3ZhciBfMHhjZDM5MzE9XzB4MzFlNDg2LF8weDI5MTFjNSxfMHgxOTUzOGMsXzB4M2U3YjI0LF8weDE3MDU3MTt0aGlzWydnbG9iYWwnXT1fMHgxOTBhYTgsdGhpc1snaG9zdCddPV8weDQ4YjUxOSx0aGlzW18weGNkMzkzMSgweDIyMCldPV8weDFmMWRkZCx0aGlzW18weGNkMzkzMSgweDE0OCldPV8weDJhNDlmOCx0aGlzWydkb2NrZXJpemVkQXBwJ109XzB4ZGQ0NDhhLHRoaXNbJ2V2ZW50UmVjZWl2ZWRDYWxsYmFjayddPV8weDI2YmFlZSx0aGlzWydfYWxsb3dlZFRvU2VuZCddPSEweDAsdGhpc1snX2FsbG93ZWRUb0Nvbm5lY3RPblNlbmQnXT0hMHgwLHRoaXNbJ19jb25uZWN0ZWQnXT0hMHgxLHRoaXNbXzB4Y2QzOTMxKDB4MjA5KV09ITB4MSx0aGlzW18weGNkMzkzMSgweDE1NyldPSgoXzB4MTk1MzhjPShfMHgyOTExYzU9XzB4MTkwYWE4Wydwcm9jZXNzJ10pPT1udWxsP3ZvaWQgMHgwOl8weDI5MTFjNVsnZW52J10pPT1udWxsP3ZvaWQgMHgwOl8weDE5NTM4Y1snTkVYVF9SVU5USU1FJ10pPT09J2VkZ2UnLHRoaXNbXzB4Y2QzOTMxKDB4MWY0KV09ISgoXzB4MTcwNTcxPShfMHgzZTdiMjQ9dGhpc1tfMHhjZDM5MzEoMHgyMGIpXVtfMHhjZDM5MzEoMHgxNjEpXSk9PW51bGw/dm9pZCAweDA6XzB4M2U3YjI0W18weGNkMzkzMSgweDE1MildKSE9bnVsbCYmXzB4MTcwNTcxW18weGNkMzkzMSgweDIxNCldKSYmIXRoaXNbXzB4Y2QzOTMxKDB4MTU3KV0sdGhpc1tfMHhjZDM5MzEoMHgxYjQpXT1udWxsLHRoaXNbXzB4Y2QzOTMxKDB4MWRhKV09MHgwLHRoaXNbXzB4Y2QzOTMxKDB4MWIzKV09MHgxNCx0aGlzWydfd2ViU29ja2V0RXJyb3JEb2NzTGluayddPSdodHRwczovL3Rpbnl1cmwuY29tLzM3eDhiNzl0Jyx0aGlzW18weGNkMzkzMSgweDE2MyldPSh0aGlzW18weGNkMzkzMSgweDFmNCldP18weGNkMzkzMSgweDE5Yyk6XzB4Y2QzOTMxKDB4MWNhKSkrdGhpc1tfMHhjZDM5MzEoMHgxOWUpXTt9YXN5bmNbXzB4MzFlNDg2KDB4MWUyKV0oKXt2YXIgXzB4MzQwOWE5PV8weDMxZTQ4NixfMHgyYjNmODYsXzB4NDQ4MDMwO2lmKHRoaXNbXzB4MzQwOWE5KDB4MWI0KV0pcmV0dXJuIHRoaXNbXzB4MzQwOWE5KDB4MWI0KV07bGV0IF8weDUyODYzNjtpZih0aGlzWydfaW5Ccm93c2VyJ118fHRoaXNbXzB4MzQwOWE5KDB4MTU3KV0pXzB4NTI4NjM2PXRoaXNbXzB4MzQwOWE5KDB4MjBiKV1bJ1dlYlNvY2tldCddO2Vsc2V7aWYoKF8weDJiM2Y4Nj10aGlzW18weDM0MDlhOSgweDIwYildWydwcm9jZXNzJ10pIT1udWxsJiZfMHgyYjNmODZbXzB4MzQwOWE5KDB4MjA2KV0pXzB4NTI4NjM2PShfMHg0NDgwMzA9dGhpc1snZ2xvYmFsJ11bJ3Byb2Nlc3MnXSk9PW51bGw/dm9pZCAweDA6XzB4NDQ4MDMwW18weDM0MDlhOSgweDIwNildO2Vsc2UgdHJ5e2xldCBfMHgxMDg4YjQ9YXdhaXQgaW1wb3J0KF8weDM0MDlhOSgweDFiMSkpO18weDUyODYzNj0oYXdhaXQgaW1wb3J0KChhd2FpdCBpbXBvcnQoXzB4MzQwOWE5KDB4MWE4KSkpW18weDM0MDlhOSgweDFjOCldKF8weDEwODhiNFtfMHgzNDA5YTkoMHgxN2YpXSh0aGlzW18weDM0MDlhOSgweDE0OCldLF8weDM0MDlhOSgweDFlMSkpKVtfMHgzNDA5YTkoMHgxYWYpXSgpKSlbJ2RlZmF1bHQnXTt9Y2F0Y2h7dHJ5e18weDUyODYzNj1yZXF1aXJlKHJlcXVpcmUoJ3BhdGgnKVtfMHgzNDA5YTkoMHgxN2YpXSh0aGlzWydub2RlTW9kdWxlcyddLCd3cycpKTt9Y2F0Y2h7dGhyb3cgbmV3IEVycm9yKF8weDM0MDlhOSgweDIyOSkpO319fXJldHVybiB0aGlzW18weDM0MDlhOSgweDFiNCldPV8weDUyODYzNixfMHg1Mjg2MzY7fVtfMHgzMWU0ODYoMHgxNzApXSgpe3ZhciBfMHgyOWE4MjU9XzB4MzFlNDg2O3RoaXNbJ19jb25uZWN0aW5nJ118fHRoaXNbJ19jb25uZWN0ZWQnXXx8dGhpc1tfMHgyOWE4MjUoMHgxZGEpXT49dGhpc1tfMHgyOWE4MjUoMHgxYjMpXXx8KHRoaXNbXzB4MjlhODI1KDB4MWYyKV09ITB4MSx0aGlzW18weDI5YTgyNSgweDIwOSldPSEweDAsdGhpc1tfMHgyOWE4MjUoMHgxZGEpXSsrLHRoaXNbXzB4MjlhODI1KDB4MTk3KV09bmV3IFByb21pc2UoKF8weDFmMmM0OCxfMHg1YjAyZjgpPT57dmFyIF8weDQxM2NhOT1fMHgyOWE4MjU7dGhpc1tfMHg0MTNjYTkoMHgxZTIpXSgpW18weDQxM2NhOSgweDE4NCldKF8weDRlOWZiOD0+e3ZhciBfMHgyMzFmZDk9XzB4NDEzY2E5O2xldCBfMHgxNWJhOGE9bmV3IF8weDRlOWZiOChfMHgyMzFmZDkoMHgxN2EpKyghdGhpc1snX2luQnJvd3NlciddJiZ0aGlzW18weDIzMWZkOSgweDIxNSldPydnYXRld2F5LmRvY2tlci5pbnRlcm5hbCc6dGhpc1tfMHgyMzFmZDkoMHgxZDgpXSkrJzonK3RoaXNbXzB4MjMxZmQ5KDB4MjIwKV0pO18weDE1YmE4YVsnb25lcnJvciddPSgpPT57dmFyIF8weDQ4ZDQxOD1fMHgyMzFmZDk7dGhpc1tfMHg0OGQ0MTgoMHgyMTMpXT0hMHgxLHRoaXNbXzB4NDhkNDE4KDB4MTU1KV0oXzB4MTViYThhKSx0aGlzW18weDQ4ZDQxOCgweDFlNyldKCksXzB4NWIwMmY4KG5ldyBFcnJvcignbG9nZ2VyXFxcXHgyMHdlYnNvY2tldFxcXFx4MjBlcnJvcicpKTt9LF8weDE1YmE4YVsnb25vcGVuJ109KCk9Pnt2YXIgXzB4M2VkNjExPV8weDIzMWZkOTt0aGlzW18weDNlZDYxMSgweDFmNCldfHxfMHgxNWJhOGFbXzB4M2VkNjExKDB4MTkzKV0mJl8weDE1YmE4YVsnX3NvY2tldCddW18weDNlZDYxMSgweDFmZCldJiZfMHgxNWJhOGFbXzB4M2VkNjExKDB4MTkzKV1bXzB4M2VkNjExKDB4MWZkKV0oKSxfMHgxZjJjNDgoXzB4MTViYThhKTt9LF8weDE1YmE4YVtfMHgyMzFmZDkoMHgxZDEpXT0oKT0+e3ZhciBfMHg4Njk2MjY9XzB4MjMxZmQ5O3RoaXNbXzB4ODY5NjI2KDB4MWYyKV09ITB4MCx0aGlzW18weDg2OTYyNigweDE1NSldKF8weDE1YmE4YSksdGhpc1tfMHg4Njk2MjYoMHgxZTcpXSgpO30sXzB4MTViYThhW18weDIzMWZkOSgweDE4MSldPV8weDNkOGFjZT0+e3ZhciBfMHgxMjIzYmE9XzB4MjMxZmQ5O3RyeXtpZighKF8weDNkOGFjZSE9bnVsbCYmXzB4M2Q4YWNlWydkYXRhJ10pfHwhdGhpc1tfMHgxMjIzYmEoMHgyMTIpXSlyZXR1cm47bGV0IF8weDUyZjM4PUpTT05bXzB4MTIyM2JhKDB4MWY4KV0oXzB4M2Q4YWNlW18weDEyMjNiYSgweDFmYildKTt0aGlzWydldmVudFJlY2VpdmVkQ2FsbGJhY2snXShfMHg1MmYzOFtfMHgxMjIzYmEoMHgxYWIpXSxfMHg1MmYzOFtfMHgxMjIzYmEoMHgxZjkpXSx0aGlzW18weDEyMjNiYSgweDIwYildLHRoaXNbXzB4MTIyM2JhKDB4MWY0KV0pO31jYXRjaHt9fTt9KVsndGhlbiddKF8weDIxMzc0MD0+KHRoaXNbXzB4NDEzY2E5KDB4MWY2KV09ITB4MCx0aGlzW18weDQxM2NhOSgweDIwOSldPSEweDEsdGhpc1tfMHg0MTNjYTkoMHgxZjIpXT0hMHgxLHRoaXNbJ19hbGxvd2VkVG9TZW5kJ109ITB4MCx0aGlzW18weDQxM2NhOSgweDFkYSldPTB4MCxfMHgyMTM3NDApKVtfMHg0MTNjYTkoMHgxZDUpXShfMHgyNDQ4NzY9Pih0aGlzW18weDQxM2NhOSgweDFmNildPSEweDEsdGhpc1tfMHg0MTNjYTkoMHgyMDkpXT0hMHgxLGNvbnNvbGVbXzB4NDEzY2E5KDB4MWQzKV0oXzB4NDEzY2E5KDB4MTg5KSt0aGlzW18weDQxM2NhOSgweDE5ZSldKSxfMHg1YjAyZjgobmV3IEVycm9yKCdmYWlsZWRcXFxceDIwdG9cXFxceDIwY29ubmVjdFxcXFx4MjB0b1xcXFx4MjBob3N0OlxcXFx4MjAnKyhfMHgyNDQ4NzYmJl8weDI0NDg3NlsnbWVzc2FnZSddKSkpKSk7fSkpO31bXzB4MzFlNDg2KDB4MTU1KV0oXzB4MzhjZDFmKXt2YXIgXzB4MjI2YmFmPV8weDMxZTQ4Njt0aGlzW18weDIyNmJhZigweDFmNildPSEweDEsdGhpc1tfMHgyMjZiYWYoMHgyMDkpXT0hMHgxO3RyeXtfMHgzOGNkMWZbXzB4MjI2YmFmKDB4MWQxKV09bnVsbCxfMHgzOGNkMWZbXzB4MjI2YmFmKDB4MWFkKV09bnVsbCxfMHgzOGNkMWZbXzB4MjI2YmFmKDB4MWRlKV09bnVsbDt9Y2F0Y2h7fXRyeXtfMHgzOGNkMWZbXzB4MjI2YmFmKDB4MWQyKV08MHgyJiZfMHgzOGNkMWZbXzB4MjI2YmFmKDB4MWQ2KV0oKTt9Y2F0Y2h7fX1bXzB4MzFlNDg2KDB4MWU3KV0oKXt2YXIgXzB4NTM1ZTczPV8weDMxZTQ4NjtjbGVhclRpbWVvdXQodGhpc1tfMHg1MzVlNzMoMHgyMWEpXSksISh0aGlzWydfY29ubmVjdEF0dGVtcHRDb3VudCddPj10aGlzWydfbWF4Q29ubmVjdEF0dGVtcHRDb3VudCddKSYmKHRoaXNbJ19yZWNvbm5lY3RUaW1lb3V0J109c2V0VGltZW91dCgoKT0+e3ZhciBfMHg0NjUxNDI9XzB4NTM1ZTczLF8weDE0Y2Q1YTt0aGlzW18weDQ2NTE0MigweDFmNildfHx0aGlzW18weDQ2NTE0MigweDIwOSldfHwodGhpc1snX2Nvbm5lY3RUb0hvc3ROb3cnXSgpLChfMHgxNGNkNWE9dGhpc1tfMHg0NjUxNDIoMHgxOTcpXSk9PW51bGx8fF8weDE0Y2Q1YVsnY2F0Y2gnXSgoKT0+dGhpc1tfMHg0NjUxNDIoMHgxZTcpXSgpKSk7fSwweDFmNCksdGhpc1tfMHg1MzVlNzMoMHgyMWEpXVtfMHg1MzVlNzMoMHgxZmQpXSYmdGhpc1tfMHg1MzVlNzMoMHgyMWEpXVsndW5yZWYnXSgpKTt9YXN5bmNbXzB4MzFlNDg2KDB4MjJmKV0oXzB4NWYyN2EyKXt2YXIgXzB4MzQyOWE0PV8weDMxZTQ4Njt0cnl7aWYoIXRoaXNbXzB4MzQyOWE0KDB4MjEzKV0pcmV0dXJuO3RoaXNbXzB4MzQyOWE0KDB4MWYyKV0mJnRoaXNbXzB4MzQyOWE0KDB4MTcwKV0oKSwoYXdhaXQgdGhpc1snX3dzJ10pW18weDM0MjlhNCgweDIyZildKEpTT05bXzB4MzQyOWE0KDB4MWZhKV0oXzB4NWYyN2EyKSk7fWNhdGNoKF8weDVhZmVjNil7Y29uc29sZVtfMHgzNDI5YTQoMHgxZDMpXSh0aGlzW18weDM0MjlhNCgweDE2MyldKyc6XFxcXHgyMCcrKF8weDVhZmVjNiYmXzB4NWFmZWM2W18weDM0MjlhNCgweDFhMSldKSksdGhpc1snX2FsbG93ZWRUb1NlbmQnXT0hMHgxLHRoaXNbXzB4MzQyOWE0KDB4MWU3KV0oKTt9fX07ZnVuY3Rpb24gcShfMHg0Mjk4NmQsXzB4MjAzYTM4LF8weDMwOTI3YSxfMHgxYjk1OTQsXzB4MjUwYmJlLF8weDJlMjU2ZixfMHgzMDFiMjIsXzB4M2Y3YzI2PWllKXt2YXIgXzB4MzczMTMxPV8weDMxZTQ4NjtsZXQgXzB4M2QwOTRlPV8weDMwOTI3YVsnc3BsaXQnXSgnLCcpW18weDM3MzEzMSgweDFmMyldKF8weDUzNDU0Nj0+e3ZhciBfMHg1M2Y2NTE9XzB4MzczMTMxLF8weDQ2OTQzNCxfMHgxOTVmMjMsXzB4NGJlYTVmLF8weDE0NDJlODt0cnl7aWYoIV8weDQyOTg2ZFtfMHg1M2Y2NTEoMHgxNzYpXSl7bGV0IF8weDIzMDNlYj0oKF8weDE5NWYyMz0oXzB4NDY5NDM0PV8weDQyOTg2ZFtfMHg1M2Y2NTEoMHgxNjEpXSk9PW51bGw/dm9pZCAweDA6XzB4NDY5NDM0W18weDUzZjY1MSgweDE1MildKT09bnVsbD92b2lkIDB4MDpfMHgxOTVmMjNbXzB4NTNmNjUxKDB4MjE0KV0pfHwoKF8weDE0NDJlOD0oXzB4NGJlYTVmPV8weDQyOTg2ZFtfMHg1M2Y2NTEoMHgxNjEpXSk9PW51bGw/dm9pZCAweDA6XzB4NGJlYTVmW18weDUzZjY1MSgweDE4NildKT09bnVsbD92b2lkIDB4MDpfMHgxNDQyZThbXzB4NTNmNjUxKDB4MWZmKV0pPT09XzB4NTNmNjUxKDB4MjFmKTsoXzB4MjUwYmJlPT09XzB4NTNmNjUxKDB4MjJjKXx8XzB4MjUwYmJlPT09XzB4NTNmNjUxKDB4MjI1KXx8XzB4MjUwYmJlPT09XzB4NTNmNjUxKDB4MTkyKXx8XzB4MjUwYmJlPT09J2FuZ3VsYXInKSYmKF8weDI1MGJiZSs9XzB4MjMwM2ViP18weDUzZjY1MSgweDFjZSk6XzB4NTNmNjUxKDB4MjI4KSksXzB4NDI5ODZkWydfY29uc29sZV9uaW5qYV9zZXNzaW9uJ109eydpZCc6K25ldyBEYXRlKCksJ3Rvb2wnOl8weDI1MGJiZX0sXzB4MzAxYjIyJiZfMHgyNTBiYmUmJiFfMHgyMzAzZWImJmNvbnNvbGVbXzB4NTNmNjUxKDB4MTY4KV0oJyVjXFxcXHgyMENvbnNvbGVcXFxceDIwTmluamFcXFxceDIwZXh0ZW5zaW9uXFxcXHgyMGlzXFxcXHgyMGNvbm5lY3RlZFxcXFx4MjB0b1xcXFx4MjAnKyhfMHgyNTBiYmVbJ2NoYXJBdCddKDB4MClbXzB4NTNmNjUxKDB4MWVkKV0oKStfMHgyNTBiYmVbXzB4NTNmNjUxKDB4MWEwKV0oMHgxKSkrJywnLCdiYWNrZ3JvdW5kOlxcXFx4MjByZ2IoMzAsMzAsMzApO1xcXFx4MjBjb2xvcjpcXFxceDIwcmdiKDI1NSwyMTMsOTIpJyxfMHg1M2Y2NTEoMHgyMjcpKTt9bGV0IF8weDI3M2I2ND1uZXcgWihfMHg0Mjk4NmQsXzB4MjAzYTM4LF8weDUzNDU0NixfMHgxYjk1OTQsXzB4MmUyNTZmLF8weDNmN2MyNik7cmV0dXJuIF8weDI3M2I2NFtfMHg1M2Y2NTEoMHgyMmYpXVtfMHg1M2Y2NTEoMHgxNmEpXShfMHgyNzNiNjQpO31jYXRjaChfMHgyMDM0ZDYpe3JldHVybiBjb25zb2xlW18weDUzZjY1MSgweDFkMyldKF8weDUzZjY1MSgweDE1OCksXzB4MjAzNGQ2JiZfMHgyMDM0ZDZbXzB4NTNmNjUxKDB4MWExKV0pLCgpPT57fTt9fSk7cmV0dXJuIF8weDRlZWZhNT0+XzB4M2QwOTRlW18weDM3MzEzMSgweDFkZCldKF8weDNkYTkxYT0+XzB4M2RhOTFhKF8weDRlZWZhNSkpO31mdW5jdGlvbiBpZShfMHgxYzc3NTEsXzB4MjIyY2QwLF8weDFlZTNlMixfMHg1MmY2YTkpe3ZhciBfMHg0ODY2ODA9XzB4MzFlNDg2O18weDUyZjZhOSYmXzB4MWM3NzUxPT09J3JlbG9hZCcmJl8weDFlZTNlMltfMHg0ODY2ODAoMHgxNWEpXVsncmVsb2FkJ10oKTt9ZnVuY3Rpb24gQihfMHhmNjIwOGQpe3ZhciBfMHg1MjAxZWY9XzB4MzFlNDg2LF8weDRjOGNmOSxfMHgzYzc0ZGU7bGV0IF8weDNhODFhMz1mdW5jdGlvbihfMHg0ZjU2ZDcsXzB4NDdhYTQ4KXtyZXR1cm4gXzB4NDdhYTQ4LV8weDRmNTZkNzt9LF8weDRlMzY2NTtpZihfMHhmNjIwOGRbJ3BlcmZvcm1hbmNlJ10pXzB4NGUzNjY1PWZ1bmN0aW9uKCl7dmFyIF8weDEyMDUyZj1fMHgzM2IyO3JldHVybiBfMHhmNjIwOGRbXzB4MTIwNTJmKDB4MTZiKV1bXzB4MTIwNTJmKDB4MjJiKV0oKTt9O2Vsc2V7aWYoXzB4ZjYyMDhkW18weDUyMDFlZigweDE2MSldJiZfMHhmNjIwOGRbJ3Byb2Nlc3MnXVtfMHg1MjAxZWYoMHgxNzUpXSYmKChfMHgzYzc0ZGU9KF8weDRjOGNmOT1fMHhmNjIwOGRbXzB4NTIwMWVmKDB4MTYxKV0pPT1udWxsP3ZvaWQgMHgwOl8weDRjOGNmOVtfMHg1MjAxZWYoMHgxODYpXSk9PW51bGw/dm9pZCAweDA6XzB4M2M3NGRlW18weDUyMDFlZigweDFmZildKSE9PSdlZGdlJylfMHg0ZTM2NjU9ZnVuY3Rpb24oKXt2YXIgXzB4NTRjNWEwPV8weDUyMDFlZjtyZXR1cm4gXzB4ZjYyMDhkW18weDU0YzVhMCgweDE2MSldW18weDU0YzVhMCgweDE3NSldKCk7fSxfMHgzYTgxYTM9ZnVuY3Rpb24oXzB4NDY5YmFiLF8weDE5YjViNCl7cmV0dXJuIDB4M2U4KihfMHgxOWI1YjRbMHgwXS1fMHg0NjliYWJbMHgwXSkrKF8weDE5YjViNFsweDFdLV8weDQ2OWJhYlsweDFdKS8weGY0MjQwO307ZWxzZSB0cnl7bGV0IHtwZXJmb3JtYW5jZTpfMHg0MjBiZTd9PXJlcXVpcmUoXzB4NTIwMWVmKDB4MThjKSk7XzB4NGUzNjY1PWZ1bmN0aW9uKCl7cmV0dXJuIF8weDQyMGJlN1snbm93J10oKTt9O31jYXRjaHtfMHg0ZTM2NjU9ZnVuY3Rpb24oKXtyZXR1cm4rbmV3IERhdGUoKTt9O319cmV0dXJueydlbGFwc2VkJzpfMHgzYTgxYTMsJ3RpbWVTdGFtcCc6XzB4NGUzNjY1LCdub3cnOigpPT5EYXRlWydub3cnXSgpfTt9ZnVuY3Rpb24gSChfMHgxNjAxZjYsXzB4NDU5Y2QxLF8weDQ3YjJiMCl7dmFyIF8weDQzYTc1MD1fMHgzMWU0ODYsXzB4MjAwOGRjLF8weDQwNDE2ZixfMHgxOTBkZWYsXzB4NWJiZjI0LF8weDU1YWE4NTtpZihfMHgxNjAxZjZbXzB4NDNhNzUwKDB4MjJkKV0hPT12b2lkIDB4MClyZXR1cm4gXzB4MTYwMWY2W18weDQzYTc1MCgweDIyZCldO2xldCBfMHgyMGRjOTQ9KChfMHg0MDQxNmY9KF8weDIwMDhkYz1fMHgxNjAxZjZbXzB4NDNhNzUwKDB4MTYxKV0pPT1udWxsP3ZvaWQgMHgwOl8weDIwMDhkY1tfMHg0M2E3NTAoMHgxNTIpXSk9PW51bGw/dm9pZCAweDA6XzB4NDA0MTZmWydub2RlJ10pfHwoKF8weDViYmYyND0oXzB4MTkwZGVmPV8weDE2MDFmNltfMHg0M2E3NTAoMHgxNjEpXSk9PW51bGw/dm9pZCAweDA6XzB4MTkwZGVmW18weDQzYTc1MCgweDE4NildKT09bnVsbD92b2lkIDB4MDpfMHg1YmJmMjRbXzB4NDNhNzUwKDB4MWZmKV0pPT09J2VkZ2UnO2Z1bmN0aW9uIF8weGYzMTRjYyhfMHgzYTFlOTgpe3ZhciBfMHgyYmUzNDQ9XzB4NDNhNzUwO2lmKF8weDNhMWU5OFsnc3RhcnRzV2l0aCddKCcvJykmJl8weDNhMWU5OFtfMHgyYmUzNDQoMHgxOGIpXSgnLycpKXtsZXQgXzB4MTRjOTBjPW5ldyBSZWdFeHAoXzB4M2ExZTk4W18weDJiZTM0NCgweDE1OSldKDB4MSwtMHgxKSk7cmV0dXJuIF8weDUwMjhiMj0+XzB4MTRjOTBjW18weDJiZTM0NCgweDE5ZCldKF8weDUwMjhiMik7fWVsc2V7aWYoXzB4M2ExZTk4W18weDJiZTM0NCgweDE2ZSldKCcqJyl8fF8weDNhMWU5OFtfMHgyYmUzNDQoMHgxNmUpXSgnPycpKXtsZXQgXzB4Mjg2N2VlPW5ldyBSZWdFeHAoJ14nK18weDNhMWU5OFtfMHgyYmUzNDQoMHgxNTApXSgvXFxcXC4vZyxTdHJpbmdbXzB4MmJlMzQ0KDB4MTc4KV0oMHg1YykrJy4nKVsncmVwbGFjZSddKC9cXFxcKi9nLCcuKicpW18weDJiZTM0NCgweDE1MCldKC9cXFxcPy9nLCcuJykrU3RyaW5nW18weDJiZTM0NCgweDE3OCldKDB4MjQpKTtyZXR1cm4gXzB4YTA3MTZjPT5fMHgyODY3ZWVbJ3Rlc3QnXShfMHhhMDcxNmMpO31lbHNlIHJldHVybiBfMHg0YmEwNmE9Pl8weDRiYTA2YT09PV8weDNhMWU5ODt9fWxldCBfMHg1M2M4OTA9XzB4NDU5Y2QxWydtYXAnXShfMHhmMzE0Y2MpO3JldHVybiBfMHgxNjAxZjZbXzB4NDNhNzUwKDB4MjJkKV09XzB4MjBkYzk0fHwhXzB4NDU5Y2QxLCFfMHgxNjAxZjZbJ19jb25zb2xlTmluamFBbGxvd2VkVG9TdGFydCddJiYoKF8weDU1YWE4NT1fMHgxNjAxZjZbJ2xvY2F0aW9uJ10pPT1udWxsP3ZvaWQgMHgwOl8weDU1YWE4NVtfMHg0M2E3NTAoMHgyMDApXSkmJihfMHgxNjAxZjZbXzB4NDNhNzUwKDB4MjJkKV09XzB4NTNjODkwW18weDQzYTc1MCgweDIyYSldKF8weDQxNjYyNT0+XzB4NDE2NjI1KF8weDE2MDFmNlsnbG9jYXRpb24nXVsnaG9zdG5hbWUnXSkpKSxfMHgxNjAxZjZbXzB4NDNhNzUwKDB4MjJkKV07fWZ1bmN0aW9uIFgoXzB4NDI2ZDVmLF8weDU4YmQ5MyxfMHgyZGJiYjcsXzB4MmVmYjMyKXt2YXIgXzB4MTI3NzM1PV8weDMxZTQ4NjtfMHg0MjZkNWY9XzB4NDI2ZDVmLF8weDU4YmQ5Mz1fMHg1OGJkOTMsXzB4MmRiYmI3PV8weDJkYmJiNyxfMHgyZWZiMzI9XzB4MmVmYjMyO2xldCBfMHhiYmY1MmY9QihfMHg0MjZkNWYpLF8weDIzMmQwZD1fMHhiYmY1MmZbXzB4MTI3NzM1KDB4MTZmKV0sXzB4NWI2ODlkPV8weGJiZjUyZltfMHgxMjc3MzUoMHgxNzcpXTtjbGFzcyBfMHgyZTBkM2N7Y29uc3RydWN0b3IoKXt2YXIgXzB4NTQyMWI5PV8weDEyNzczNTt0aGlzW18weDU0MjFiOSgweDE1YyldPS9eKD8hKD86ZG98aWZ8aW58Zm9yfGxldHxuZXd8dHJ5fHZhcnxjYXNlfGVsc2V8ZW51bXxldmFsfGZhbHNlfG51bGx8dGhpc3x0cnVlfHZvaWR8d2l0aHxicmVha3xjYXRjaHxjbGFzc3xjb25zdHxzdXBlcnx0aHJvd3x3aGlsZXx5aWVsZHxkZWxldGV8ZXhwb3J0fGltcG9ydHxwdWJsaWN8cmV0dXJufHN0YXRpY3xzd2l0Y2h8dHlwZW9mfGRlZmF1bHR8ZXh0ZW5kc3xmaW5hbGx5fHBhY2thZ2V8cHJpdmF0ZXxjb250aW51ZXxkZWJ1Z2dlcnxmdW5jdGlvbnxhcmd1bWVudHN8aW50ZXJmYWNlfHByb3RlY3RlZHxpbXBsZW1lbnRzfGluc3RhbmNlb2YpJClbXyRhLXpBLVpcXFxceEEwLVxcXFx1RkZGRl1bXyRhLXpBLVowLTlcXFxceEEwLVxcXFx1RkZGRl0qJC8sdGhpc1tfMHg1NDIxYjkoMHgxN2IpXT0vXigwfFsxLTldWzAtOV0qKSQvLHRoaXNbXzB4NTQyMWI5KDB4MTg4KV09LycoW15cXFxcXFxcXCddfFxcXFxcXFxcJykqJy8sdGhpc1snX3VuZGVmaW5lZCddPV8weDQyNmQ1ZltfMHg1NDIxYjkoMHgxZWIpXSx0aGlzW18weDU0MjFiOSgweDIyMSldPV8weDQyNmQ1ZltfMHg1NDIxYjkoMHgxNGMpXSx0aGlzW18weDU0MjFiOSgweDE2NyldPU9iamVjdFsnZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yJ10sdGhpc1tfMHg1NDIxYjkoMHgxYmYpXT1PYmplY3RbXzB4NTQyMWI5KDB4MjE4KV0sdGhpc1snX1N5bWJvbCddPV8weDQyNmQ1ZltfMHg1NDIxYjkoMHgxY2YpXSx0aGlzW18weDU0MjFiOSgweDIxYildPVJlZ0V4cFtfMHg1NDIxYjkoMHgxOTUpXVsndG9TdHJpbmcnXSx0aGlzW18weDU0MjFiOSgweDFkYyldPURhdGVbXzB4NTQyMWI5KDB4MTk1KV1bJ3RvU3RyaW5nJ107fVsnc2VyaWFsaXplJ10oXzB4NTE1MGIyLF8weGQ0MGE0YixfMHgxYzc5MDAsXzB4NDE5NmQ3KXt2YXIgXzB4MmM3ZDA0PV8weDEyNzczNSxfMHgzOGU5NGE9dGhpcyxfMHg4NzlkOTg9XzB4MWM3OTAwW18weDJjN2QwNCgweDFlZildO2Z1bmN0aW9uIF8weDgwMWU0NShfMHg0YmY2NDMsXzB4NDA2ZTkzLF8weDMwM2YyZCl7dmFyIF8weDQ1NzgwOT1fMHgyYzdkMDQ7XzB4NDA2ZTkzWyd0eXBlJ109J3Vua25vd24nLF8weDQwNmU5M1tfMHg0NTc4MDkoMHgyMGMpXT1fMHg0YmY2NDNbXzB4NDU3ODA5KDB4MWExKV0sXzB4MTIyOWIyPV8weDMwM2YyZFtfMHg0NTc4MDkoMHgyMTQpXVtfMHg0NTc4MDkoMHgxYTQpXSxfMHgzMDNmMmRbXzB4NDU3ODA5KDB4MjE0KV1bXzB4NDU3ODA5KDB4MWE0KV09XzB4NDA2ZTkzLF8weDM4ZTk0YVsnX3RyZWVOb2RlUHJvcGVydGllc0JlZm9yZUZ1bGxWYWx1ZSddKF8weDQwNmU5MyxfMHgzMDNmMmQpO310cnl7XzB4MWM3OTAwWydsZXZlbCddKyssXzB4MWM3OTAwW18weDJjN2QwNCgweDFlZildJiZfMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MWE2KV1bXzB4MmM3ZDA0KDB4MTcyKV0oXzB4ZDQwYTRiKTt2YXIgXzB4NWQ4YTE2LF8weDUxNmIyMCxfMHgyNWI5MDIsXzB4MjE4ZjU1LF8weDVkMWU0Yj1bXSxfMHg3MzUyNDQ9W10sXzB4NGYxNWZlLF8weDJlYTdhZT10aGlzW18weDJjN2QwNCgweDFlYyldKF8weGQ0MGE0YiksXzB4Mzk3YzdlPV8weDJlYTdhZT09PV8weDJjN2QwNCgweDFlNiksXzB4MjIzZTc3PSEweDEsXzB4MmVmMzRiPV8weDJlYTdhZT09PV8weDJjN2QwNCgweDE3MyksXzB4MWIxOGJjPXRoaXNbJ19pc1ByaW1pdGl2ZVR5cGUnXShfMHgyZWE3YWUpLF8weDVjNGZkZD10aGlzW18weDJjN2QwNCgweDE4MyldKF8weDJlYTdhZSksXzB4MTFhMTVkPV8weDFiMThiY3x8XzB4NWM0ZmRkLF8weDUwM2EyZD17fSxfMHg1MzllZDM9MHgwLF8weDQxMmVkYT0hMHgxLF8weDEyMjliMixfMHgxMjk3NzY9L14oKFsxLTldezF9WzAtOV0qKXwwKSQvO2lmKF8weDFjNzkwMFtfMHgyYzdkMDQoMHgyMTEpXSl7aWYoXzB4Mzk3YzdlKXtpZihfMHg1MTZiMjA9XzB4ZDQwYTRiWydsZW5ndGgnXSxfMHg1MTZiMjA+XzB4MWM3OTAwW18weDJjN2QwNCgweDFiNildKXtmb3IoXzB4MjViOTAyPTB4MCxfMHgyMThmNTU9XzB4MWM3OTAwW18weDJjN2QwNCgweDFiNildLF8weDVkOGExNj1fMHgyNWI5MDI7XzB4NWQ4YTE2PF8weDIxOGY1NTtfMHg1ZDhhMTYrKylfMHg3MzUyNDRbJ3B1c2gnXShfMHgzOGU5NGFbXzB4MmM3ZDA0KDB4MTU0KV0oXzB4NWQxZTRiLF8weGQ0MGE0YixfMHgyZWE3YWUsXzB4NWQ4YTE2LF8weDFjNzkwMCkpO18weDUxNTBiMltfMHgyYzdkMDQoMHgxY2QpXT0hMHgwO31lbHNle2ZvcihfMHgyNWI5MDI9MHgwLF8weDIxOGY1NT1fMHg1MTZiMjAsXzB4NWQ4YTE2PV8weDI1YjkwMjtfMHg1ZDhhMTY8XzB4MjE4ZjU1O18weDVkOGExNisrKV8weDczNTI0NFtfMHgyYzdkMDQoMHgxNzIpXShfMHgzOGU5NGFbXzB4MmM3ZDA0KDB4MTU0KV0oXzB4NWQxZTRiLF8weGQ0MGE0YixfMHgyZWE3YWUsXzB4NWQ4YTE2LF8weDFjNzkwMCkpO31fMHgxYzc5MDBbJ2F1dG9FeHBhbmRQcm9wZXJ0eUNvdW50J10rPV8weDczNTI0NFtfMHgyYzdkMDQoMHgxYmMpXTt9aWYoIShfMHgyZWE3YWU9PT1fMHgyYzdkMDQoMHgxNjUpfHxfMHgyZWE3YWU9PT0ndW5kZWZpbmVkJykmJiFfMHgxYjE4YmMmJl8weDJlYTdhZSE9PV8weDJjN2QwNCgweDIwNCkmJl8weDJlYTdhZSE9PSdCdWZmZXInJiZfMHgyZWE3YWUhPT1fMHgyYzdkMDQoMHgxODIpKXt2YXIgXzB4M2VmYTJkPV8weDQxOTZkN1tfMHgyYzdkMDQoMHgxNjIpXXx8XzB4MWM3OTAwWydwcm9wcyddO2lmKHRoaXNbXzB4MmM3ZDA0KDB4MjI0KV0oXzB4ZDQwYTRiKT8oXzB4NWQ4YTE2PTB4MCxfMHhkNDBhNGJbJ2ZvckVhY2gnXShmdW5jdGlvbihfMHgyMGNmNWUpe3ZhciBfMHgzMDEwYTQ9XzB4MmM3ZDA0O2lmKF8weDUzOWVkMysrLF8weDFjNzkwMFtfMHgzMDEwYTQoMHgxNTYpXSsrLF8weDUzOWVkMz5fMHgzZWZhMmQpe18weDQxMmVkYT0hMHgwO3JldHVybjt9aWYoIV8weDFjNzkwMFtfMHgzMDEwYTQoMHgxOTApXSYmXzB4MWM3OTAwW18weDMwMTBhNCgweDFlZildJiZfMHgxYzc5MDBbXzB4MzAxMGE0KDB4MTU2KV0+XzB4MWM3OTAwWydhdXRvRXhwYW5kTGltaXQnXSl7XzB4NDEyZWRhPSEweDA7cmV0dXJuO31fMHg3MzUyNDRbXzB4MzAxMGE0KDB4MTcyKV0oXzB4MzhlOTRhW18weDMwMTBhNCgweDE1NCldKF8weDVkMWU0YixfMHhkNDBhNGIsXzB4MzAxMGE0KDB4MWM1KSxfMHg1ZDhhMTYrKyxfMHgxYzc5MDAsZnVuY3Rpb24oXzB4NTExZjc4KXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gXzB4NTExZjc4O307fShfMHgyMGNmNWUpKSk7fSkpOnRoaXNbXzB4MmM3ZDA0KDB4MjBkKV0oXzB4ZDQwYTRiKSYmXzB4ZDQwYTRiW18weDJjN2QwNCgweDFkZCldKGZ1bmN0aW9uKF8weDE4YzM5MCxfMHg0MDA0ZjUpe3ZhciBfMHg0MzZhNDM9XzB4MmM3ZDA0O2lmKF8weDUzOWVkMysrLF8weDFjNzkwMFtfMHg0MzZhNDMoMHgxNTYpXSsrLF8weDUzOWVkMz5fMHgzZWZhMmQpe18weDQxMmVkYT0hMHgwO3JldHVybjt9aWYoIV8weDFjNzkwMFsnaXNFeHByZXNzaW9uVG9FdmFsdWF0ZSddJiZfMHgxYzc5MDBbXzB4NDM2YTQzKDB4MWVmKV0mJl8weDFjNzkwMFtfMHg0MzZhNDMoMHgxNTYpXT5fMHgxYzc5MDBbXzB4NDM2YTQzKDB4MjE3KV0pe18weDQxMmVkYT0hMHgwO3JldHVybjt9dmFyIF8weDRhOGYxYz1fMHg0MDA0ZjVbXzB4NDM2YTQzKDB4MWFmKV0oKTtfMHg0YThmMWNbXzB4NDM2YTQzKDB4MWJjKV0+MHg2NCYmKF8weDRhOGYxYz1fMHg0YThmMWNbXzB4NDM2YTQzKDB4MTU5KV0oMHgwLDB4NjQpKycuLi4nKSxfMHg3MzUyNDRbXzB4NDM2YTQzKDB4MTcyKV0oXzB4MzhlOTRhWydfYWRkUHJvcGVydHknXShfMHg1ZDFlNGIsXzB4ZDQwYTRiLF8weDQzNmE0MygweDFkYiksXzB4NGE4ZjFjLF8weDFjNzkwMCxmdW5jdGlvbihfMHgxYmRhM2Mpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBfMHgxYmRhM2M7fTt9KF8weDE4YzM5MCkpKTt9KSwhXzB4MjIzZTc3KXt0cnl7Zm9yKF8weDRmMTVmZSBpbiBfMHhkNDBhNGIpaWYoIShfMHgzOTdjN2UmJl8weDEyOTc3NltfMHgyYzdkMDQoMHgxOWQpXShfMHg0ZjE1ZmUpKSYmIXRoaXNbJ19ibGFja2xpc3RlZFByb3BlcnR5J10oXzB4ZDQwYTRiLF8weDRmMTVmZSxfMHgxYzc5MDApKXtpZihfMHg1MzllZDMrKyxfMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MTU2KV0rKyxfMHg1MzllZDM+XzB4M2VmYTJkKXtfMHg0MTJlZGE9ITB4MDticmVhazt9aWYoIV8weDFjNzkwMFtfMHgyYzdkMDQoMHgxOTApXSYmXzB4MWM3OTAwWydhdXRvRXhwYW5kJ10mJl8weDFjNzkwMFtfMHgyYzdkMDQoMHgxNTYpXT5fMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MjE3KV0pe18weDQxMmVkYT0hMHgwO2JyZWFrO31fMHg3MzUyNDRbXzB4MmM3ZDA0KDB4MTcyKV0oXzB4MzhlOTRhW18weDJjN2QwNCgweDE0YSldKF8weDVkMWU0YixfMHg1MDNhMmQsXzB4ZDQwYTRiLF8weDJlYTdhZSxfMHg0ZjE1ZmUsXzB4MWM3OTAwKSk7fX1jYXRjaHt9aWYoXzB4NTAzYTJkW18weDJjN2QwNCgweDFiOSldPSEweDAsXzB4MmVmMzRiJiYoXzB4NTAzYTJkW18weDJjN2QwNCgweDFlNSldPSEweDApLCFfMHg0MTJlZGEpe3ZhciBfMHgzZWFiYjk9W11bXzB4MmM3ZDA0KDB4MThhKV0odGhpc1snX2dldE93blByb3BlcnR5TmFtZXMnXShfMHhkNDBhNGIpKVtfMHgyYzdkMDQoMHgxOGEpXSh0aGlzW18weDJjN2QwNCgweDFmYyldKF8weGQ0MGE0YikpO2ZvcihfMHg1ZDhhMTY9MHgwLF8weDUxNmIyMD1fMHgzZWFiYjlbXzB4MmM3ZDA0KDB4MWJjKV07XzB4NWQ4YTE2PF8weDUxNmIyMDtfMHg1ZDhhMTYrKylpZihfMHg0ZjE1ZmU9XzB4M2VhYmI5W18weDVkOGExNl0sIShfMHgzOTdjN2UmJl8weDEyOTc3NltfMHgyYzdkMDQoMHgxOWQpXShfMHg0ZjE1ZmVbJ3RvU3RyaW5nJ10oKSkpJiYhdGhpc1snX2JsYWNrbGlzdGVkUHJvcGVydHknXShfMHhkNDBhNGIsXzB4NGYxNWZlLF8weDFjNzkwMCkmJiFfMHg1MDNhMmRbJ19wXycrXzB4NGYxNWZlW18weDJjN2QwNCgweDFhZildKCldKXtpZihfMHg1MzllZDMrKyxfMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MTU2KV0rKyxfMHg1MzllZDM+XzB4M2VmYTJkKXtfMHg0MTJlZGE9ITB4MDticmVhazt9aWYoIV8weDFjNzkwMFtfMHgyYzdkMDQoMHgxOTApXSYmXzB4MWM3OTAwW18weDJjN2QwNCgweDFlZildJiZfMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MTU2KV0+XzB4MWM3OTAwW18weDJjN2QwNCgweDIxNyldKXtfMHg0MTJlZGE9ITB4MDticmVhazt9XzB4NzM1MjQ0W18weDJjN2QwNCgweDE3MildKF8weDM4ZTk0YVtfMHgyYzdkMDQoMHgxNGEpXShfMHg1ZDFlNGIsXzB4NTAzYTJkLF8weGQ0MGE0YixfMHgyZWE3YWUsXzB4NGYxNWZlLF8weDFjNzkwMCkpO319fX19aWYoXzB4NTE1MGIyW18weDJjN2QwNCgweDFhYyldPV8weDJlYTdhZSxfMHgxMWExNWQ/KF8weDUxNTBiMlsndmFsdWUnXT1fMHhkNDBhNGJbXzB4MmM3ZDA0KDB4MWM2KV0oKSx0aGlzW18weDJjN2QwNCgweDE0NSldKF8weDJlYTdhZSxfMHg1MTUwYjIsXzB4MWM3OTAwLF8weDQxOTZkNykpOl8weDJlYTdhZT09PV8weDJjN2QwNCgweDE0ZSk/XzB4NTE1MGIyWyd2YWx1ZSddPXRoaXNbXzB4MmM3ZDA0KDB4MWRjKV1bJ2NhbGwnXShfMHhkNDBhNGIpOl8weDJlYTdhZT09PV8weDJjN2QwNCgweDE4Mik/XzB4NTE1MGIyW18weDJjN2QwNCgweDFhYSldPV8weGQ0MGE0YltfMHgyYzdkMDQoMHgxYWYpXSgpOl8weDJlYTdhZT09PV8weDJjN2QwNCgweDIwNSk/XzB4NTE1MGIyWyd2YWx1ZSddPXRoaXNbXzB4MmM3ZDA0KDB4MjFiKV1bXzB4MmM3ZDA0KDB4MTcxKV0oXzB4ZDQwYTRiKTpfMHgyZWE3YWU9PT1fMHgyYzdkMDQoMHgxNWQpJiZ0aGlzW18weDJjN2QwNCgweDFmZSldP18weDUxNTBiMltfMHgyYzdkMDQoMHgxYWEpXT10aGlzW18weDJjN2QwNCgweDFmZSldW18weDJjN2QwNCgweDE5NSldWyd0b1N0cmluZyddW18weDJjN2QwNCgweDE3MSldKF8weGQ0MGE0Yik6IV8weDFjNzkwMFtfMHgyYzdkMDQoMHgyMTEpXSYmIShfMHgyZWE3YWU9PT1fMHgyYzdkMDQoMHgxNjUpfHxfMHgyZWE3YWU9PT1fMHgyYzdkMDQoMHgxZWIpKSYmKGRlbGV0ZSBfMHg1MTUwYjJbJ3ZhbHVlJ10sXzB4NTE1MGIyW18weDJjN2QwNCgweDE5OSldPSEweDApLF8weDQxMmVkYSYmKF8weDUxNTBiMltfMHgyYzdkMDQoMHgxODApXT0hMHgwKSxfMHgxMjI5YjI9XzB4MWM3OTAwW18weDJjN2QwNCgweDIxNCldW18weDJjN2QwNCgweDFhNCldLF8weDFjNzkwMFtfMHgyYzdkMDQoMHgyMTQpXVtfMHgyYzdkMDQoMHgxYTQpXT1fMHg1MTUwYjIsdGhpc1tfMHgyYzdkMDQoMHgxOTQpXShfMHg1MTUwYjIsXzB4MWM3OTAwKSxfMHg3MzUyNDRbJ2xlbmd0aCddKXtmb3IoXzB4NWQ4YTE2PTB4MCxfMHg1MTZiMjA9XzB4NzM1MjQ0W18weDJjN2QwNCgweDFiYyldO18weDVkOGExNjxfMHg1MTZiMjA7XzB4NWQ4YTE2KyspXzB4NzM1MjQ0W18weDVkOGExNl0oXzB4NWQ4YTE2KTt9XzB4NWQxZTRiW18weDJjN2QwNCgweDFiYyldJiYoXzB4NTE1MGIyW18weDJjN2QwNCgweDE2MildPV8weDVkMWU0Yik7fWNhdGNoKF8weDhjOTg5NCl7XzB4ODAxZTQ1KF8weDhjOTg5NCxfMHg1MTUwYjIsXzB4MWM3OTAwKTt9cmV0dXJuIHRoaXNbXzB4MmM3ZDA0KDB4MTY5KV0oXzB4ZDQwYTRiLF8weDUxNTBiMiksdGhpc1tfMHgyYzdkMDQoMHgxYzApXShfMHg1MTUwYjIsXzB4MWM3OTAwKSxfMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MjE0KV1bXzB4MmM3ZDA0KDB4MWE0KV09XzB4MTIyOWIyLF8weDFjNzkwMFtfMHgyYzdkMDQoMHgxNmQpXS0tLF8weDFjNzkwMFsnYXV0b0V4cGFuZCddPV8weDg3OWQ5OCxfMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MWVmKV0mJl8weDFjNzkwMFtfMHgyYzdkMDQoMHgxYTYpXVsncG9wJ10oKSxfMHg1MTUwYjI7fVtfMHgxMjc3MzUoMHgxZmMpXShfMHgyYzU3ZTIpe3ZhciBfMHg1MDdkNzc9XzB4MTI3NzM1O3JldHVybiBPYmplY3RbXzB4NTA3ZDc3KDB4MjBhKV0/T2JqZWN0W18weDUwN2Q3NygweDIwYSldKF8weDJjNTdlMik6W107fVtfMHgxMjc3MzUoMHgyMjQpXShfMHgxYWQxZjIpe3ZhciBfMHgzYjMzNzk9XzB4MTI3NzM1O3JldHVybiEhKF8weDFhZDFmMiYmXzB4NDI2ZDVmW18weDNiMzM3OSgweDFjNSldJiZ0aGlzW18weDNiMzM3OSgweDE5NildKF8weDFhZDFmMik9PT1fMHgzYjMzNzkoMHgxNWUpJiZfMHgxYWQxZjJbJ2ZvckVhY2gnXSk7fVtfMHgxMjc3MzUoMHgxYzQpXShfMHgxYTBhMGYsXzB4NGE4MGI4LF8weDRmNjRmZSl7dmFyIF8weDViODk3NT1fMHgxMjc3MzU7cmV0dXJuIF8weDRmNjRmZVsnbm9GdW5jdGlvbnMnXT90eXBlb2YgXzB4MWEwYTBmW18weDRhODBiOF09PV8weDViODk3NSgweDE3Myk6ITB4MTt9W18weDEyNzczNSgweDFlYyldKF8weDUyOTNlMyl7dmFyIF8weDExNzI4YT1fMHgxMjc3MzUsXzB4MTYxMjM3PScnO3JldHVybiBfMHgxNjEyMzc9dHlwZW9mIF8weDUyOTNlMyxfMHgxNjEyMzc9PT1fMHgxMTcyOGEoMHgxNjYpP3RoaXNbXzB4MTE3MjhhKDB4MTk2KV0oXzB4NTI5M2UzKT09PV8weDExNzI4YSgweDE2MCk/XzB4MTYxMjM3PV8weDExNzI4YSgweDFlNik6dGhpc1tfMHgxMTcyOGEoMHgxOTYpXShfMHg1MjkzZTMpPT09J1tvYmplY3RcXFxceDIwRGF0ZV0nP18weDE2MTIzNz0nZGF0ZSc6dGhpc1tfMHgxMTcyOGEoMHgxOTYpXShfMHg1MjkzZTMpPT09J1tvYmplY3RcXFxceDIwQmlnSW50XSc/XzB4MTYxMjM3PV8weDExNzI4YSgweDE4Mik6XzB4NTI5M2UzPT09bnVsbD9fMHgxNjEyMzc9XzB4MTE3MjhhKDB4MTY1KTpfMHg1MjkzZTNbXzB4MTE3MjhhKDB4MWEzKV0mJihfMHgxNjEyMzc9XzB4NTI5M2UzW18weDExNzI4YSgweDFhMyldW18weDExNzI4YSgweDFjOSldfHxfMHgxNjEyMzcpOl8weDE2MTIzNz09PV8weDExNzI4YSgweDFlYikmJnRoaXNbXzB4MTE3MjhhKDB4MjIxKV0mJl8weDUyOTNlMyBpbnN0YW5jZW9mIHRoaXNbXzB4MTE3MjhhKDB4MjIxKV0mJihfMHgxNjEyMzc9XzB4MTE3MjhhKDB4MTRjKSksXzB4MTYxMjM3O31bXzB4MTI3NzM1KDB4MTk2KV0oXzB4M2QxMDY0KXt2YXIgXzB4NDEzZDFmPV8weDEyNzczNTtyZXR1cm4gT2JqZWN0W18weDQxM2QxZigweDE5NSldW18weDQxM2QxZigweDFhZildWydjYWxsJ10oXzB4M2QxMDY0KTt9W18weDEyNzczNSgweDFjMyldKF8weGFmYjVjNCl7dmFyIF8weDEwNTUwZD1fMHgxMjc3MzU7cmV0dXJuIF8weGFmYjVjND09PV8weDEwNTUwZCgweDFlOSl8fF8weGFmYjVjND09PSdzdHJpbmcnfHxfMHhhZmI1YzQ9PT1fMHgxMDU1MGQoMHgxN2UpO31bJ19pc1ByaW1pdGl2ZVdyYXBwZXJUeXBlJ10oXzB4NDI5MDYyKXt2YXIgXzB4NGIxMjU4PV8weDEyNzczNTtyZXR1cm4gXzB4NDI5MDYyPT09J0Jvb2xlYW4nfHxfMHg0MjkwNjI9PT1fMHg0YjEyNTgoMHgyMDQpfHxfMHg0MjkwNjI9PT0nTnVtYmVyJzt9W18weDEyNzczNSgweDE1NCldKF8weDI5MTM0ZSxfMHg0MmFjMzUsXzB4MzlkODkwLF8weDE3MjUxYyxfMHg0NmRiY2EsXzB4OTgzZjMpe3ZhciBfMHg1ZGQ2NWE9dGhpcztyZXR1cm4gZnVuY3Rpb24oXzB4NDRlYjY5KXt2YXIgXzB4MmJhODg4PV8weDMzYjIsXzB4MmY2NmFjPV8weDQ2ZGJjYVtfMHgyYmE4ODgoMHgyMTQpXVtfMHgyYmE4ODgoMHgxYTQpXSxfMHg0MTljYWY9XzB4NDZkYmNhW18weDJiYTg4OCgweDIxNCldW18weDJiYTg4OCgweDE0OSldLF8weDMyNzk4Nz1fMHg0NmRiY2FbXzB4MmJhODg4KDB4MjE0KV1bXzB4MmJhODg4KDB4MWY3KV07XzB4NDZkYmNhW18weDJiYTg4OCgweDIxNCldW18weDJiYTg4OCgweDFmNyldPV8weDJmNjZhYyxfMHg0NmRiY2FbJ25vZGUnXVtfMHgyYmE4ODgoMHgxNDkpXT10eXBlb2YgXzB4MTcyNTFjPT0nbnVtYmVyJz9fMHgxNzI1MWM6XzB4NDRlYjY5LF8weDI5MTM0ZVsncHVzaCddKF8weDVkZDY1YVsnX3Byb3BlcnR5J10oXzB4NDJhYzM1LF8weDM5ZDg5MCxfMHgxNzI1MWMsXzB4NDZkYmNhLF8weDk4M2YzKSksXzB4NDZkYmNhWydub2RlJ11bJ3BhcmVudCddPV8weDMyNzk4NyxfMHg0NmRiY2FbXzB4MmJhODg4KDB4MjE0KV1bXzB4MmJhODg4KDB4MTQ5KV09XzB4NDE5Y2FmO307fVtfMHgxMjc3MzUoMHgxNGEpXShfMHgxMDc5ZjAsXzB4NDJmZjNjLF8weDI4ZGNmYyxfMHgxNjg3MmYsXzB4NDU5ZTBmLF8weDNmY2E2MixfMHgzNTA2NDMpe3ZhciBfMHg3MjhkYmY9XzB4MTI3NzM1LF8weDQxZjFhNz10aGlzO3JldHVybiBfMHg0MmZmM2NbJ19wXycrXzB4NDU5ZTBmW18weDcyOGRiZigweDFhZildKCldPSEweDAsZnVuY3Rpb24oXzB4MzY3N2FlKXt2YXIgXzB4ZWNmZWQ4PV8weDcyOGRiZixfMHg0ZTliZmE9XzB4M2ZjYTYyW18weGVjZmVkOCgweDIxNCldW18weGVjZmVkOCgweDFhNCldLF8weDI5YzU5ZT1fMHgzZmNhNjJbXzB4ZWNmZWQ4KDB4MjE0KV1bXzB4ZWNmZWQ4KDB4MTQ5KV0sXzB4MWE3MGVkPV8weDNmY2E2Mlsnbm9kZSddW18weGVjZmVkOCgweDFmNyldO18weDNmY2E2Mlsnbm9kZSddW18weGVjZmVkOCgweDFmNyldPV8weDRlOWJmYSxfMHgzZmNhNjJbJ25vZGUnXVtfMHhlY2ZlZDgoMHgxNDkpXT1fMHgzNjc3YWUsXzB4MTA3OWYwW18weGVjZmVkOCgweDE3MildKF8weDQxZjFhN1tfMHhlY2ZlZDgoMHgxYzEpXShfMHgyOGRjZmMsXzB4MTY4NzJmLF8weDQ1OWUwZixfMHgzZmNhNjIsXzB4MzUwNjQzKSksXzB4M2ZjYTYyW18weGVjZmVkOCgweDIxNCldW18weGVjZmVkOCgweDFmNyldPV8weDFhNzBlZCxfMHgzZmNhNjJbXzB4ZWNmZWQ4KDB4MjE0KV1bJ2luZGV4J109XzB4MjljNTllO307fVtfMHgxMjc3MzUoMHgxYzEpXShfMHg0YjZiMzksXzB4NDU0MjM5LF8weDQyMGNhMSxfMHgxZDZkZDYsXzB4ZmRjMWYyKXt2YXIgXzB4NDlmNWE0PV8weDEyNzczNSxfMHgyMDE5MDc9dGhpcztfMHhmZGMxZjJ8fChfMHhmZGMxZjI9ZnVuY3Rpb24oXzB4MmVkYTE4LF8weDNmZDg4OCl7cmV0dXJuIF8weDJlZGExOFtfMHgzZmQ4ODhdO30pO3ZhciBfMHgxOTk0YWM9XzB4NDIwY2ExWyd0b1N0cmluZyddKCksXzB4MzExNWJlPV8weDFkNmRkNltfMHg0OWY1YTQoMHgyMTApXXx8e30sXzB4NTc2Zjc3PV8weDFkNmRkNltfMHg0OWY1YTQoMHgyMTEpXSxfMHgyODA2YmE9XzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDE5MCldO3RyeXt2YXIgXzB4NGIyOGY4PXRoaXNbXzB4NDlmNWE0KDB4MjBkKV0oXzB4NGI2YjM5KSxfMHgzYjIzODQ9XzB4MTk5NGFjO18weDRiMjhmOCYmXzB4M2IyMzg0WzB4MF09PT0nXFxcXHgyNycmJihfMHgzYjIzODQ9XzB4M2IyMzg0WydzdWJzdHInXSgweDEsXzB4M2IyMzg0W18weDQ5ZjVhNCgweDFiYyldLTB4MikpO3ZhciBfMHgzM2NiNWI9XzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDIxMCldPV8weDMxMTViZVtfMHg0OWY1YTQoMHgxNWYpK18weDNiMjM4NF07XzB4MzNjYjViJiYoXzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDIxMSldPV8weDFkNmRkNlsnZGVwdGgnXSsweDEpLF8weDFkNmRkNltfMHg0OWY1YTQoMHgxOTApXT0hIV8weDMzY2I1Yjt2YXIgXzB4NWMyNmI5PXR5cGVvZiBfMHg0MjBjYTE9PV8weDQ5ZjVhNCgweDE1ZCksXzB4MzdmOGYxPXsnbmFtZSc6XzB4NWMyNmI5fHxfMHg0YjI4Zjg/XzB4MTk5NGFjOnRoaXNbXzB4NDlmNWE0KDB4MTUzKV0oXzB4MTk5NGFjKX07aWYoXzB4NWMyNmI5JiYoXzB4MzdmOGYxWydzeW1ib2wnXT0hMHgwKSwhKF8weDQ1NDIzOT09PSdhcnJheSd8fF8weDQ1NDIzOT09PV8weDQ5ZjVhNCgweDFiOCkpKXt2YXIgXzB4OGYyNWQxPXRoaXNbXzB4NDlmNWE0KDB4MTY3KV0oXzB4NGI2YjM5LF8weDQyMGNhMSk7aWYoXzB4OGYyNWQxJiYoXzB4OGYyNWQxW18weDQ5ZjVhNCgweDFlZSldJiYoXzB4MzdmOGYxW18weDQ5ZjVhNCgweDE0NyldPSEweDApLF8weDhmMjVkMVtfMHg0OWY1YTQoMHgxYzcpXSYmIV8weDMzY2I1YiYmIV8weDFkNmRkNlsncmVzb2x2ZUdldHRlcnMnXSkpcmV0dXJuIF8weDM3ZjhmMVtfMHg0OWY1YTQoMHgxZjEpXT0hMHgwLHRoaXNbXzB4NDlmNWE0KDB4MWY1KV0oXzB4MzdmOGYxLF8weDFkNmRkNiksXzB4MzdmOGYxO312YXIgXzB4MmNkNDdkO3RyeXtfMHgyY2Q0N2Q9XzB4ZmRjMWYyKF8weDRiNmIzOSxfMHg0MjBjYTEpO31jYXRjaChfMHgxMmEwMmMpe3JldHVybiBfMHgzN2Y4ZjE9eyduYW1lJzpfMHgxOTk0YWMsJ3R5cGUnOl8weDQ5ZjVhNCgweDIxZCksJ2Vycm9yJzpfMHgxMmEwMmNbXzB4NDlmNWE0KDB4MWExKV19LHRoaXNbXzB4NDlmNWE0KDB4MWY1KV0oXzB4MzdmOGYxLF8weDFkNmRkNiksXzB4MzdmOGYxO312YXIgXzB4NTkyYjM0PXRoaXNbXzB4NDlmNWE0KDB4MWVjKV0oXzB4MmNkNDdkKSxfMHgzY2M2OTA9dGhpc1snX2lzUHJpbWl0aXZlVHlwZSddKF8weDU5MmIzNCk7aWYoXzB4MzdmOGYxW18weDQ5ZjVhNCgweDFhYyldPV8weDU5MmIzNCxfMHgzY2M2OTApdGhpc1tfMHg0OWY1YTQoMHgxZjUpXShfMHgzN2Y4ZjEsXzB4MWQ2ZGQ2LF8weDJjZDQ3ZCxmdW5jdGlvbigpe3ZhciBfMHg1NmY0N2E9XzB4NDlmNWE0O18weDM3ZjhmMVtfMHg1NmY0N2EoMHgxYWEpXT1fMHgyY2Q0N2RbXzB4NTZmNDdhKDB4MWM2KV0oKSwhXzB4MzNjYjViJiZfMHgyMDE5MDdbXzB4NTZmNDdhKDB4MTQ1KV0oXzB4NTkyYjM0LF8weDM3ZjhmMSxfMHgxZDZkZDYse30pO30pO2Vsc2V7dmFyIF8weDRmYzc5Mj1fMHgxZDZkZDZbXzB4NDlmNWE0KDB4MWVmKV0mJl8weDFkNmRkNltfMHg0OWY1YTQoMHgxNmQpXTxfMHgxZDZkZDZbXzB4NDlmNWE0KDB4MTc5KV0mJl8weDFkNmRkNltfMHg0OWY1YTQoMHgxYTYpXVsnaW5kZXhPZiddKF8weDJjZDQ3ZCk8MHgwJiZfMHg1OTJiMzQhPT1fMHg0OWY1YTQoMHgxNzMpJiZfMHgxZDZkZDZbXzB4NDlmNWE0KDB4MTU2KV08XzB4MWQ2ZGQ2WydhdXRvRXhwYW5kTGltaXQnXTtfMHg0ZmM3OTJ8fF8weDFkNmRkNltfMHg0OWY1YTQoMHgxNmQpXTxfMHg1NzZmNzd8fF8weDMzY2I1Yj8odGhpc1tfMHg0OWY1YTQoMHgyMWUpXShfMHgzN2Y4ZjEsXzB4MmNkNDdkLF8weDFkNmRkNixfMHgzM2NiNWJ8fHt9KSx0aGlzWydfYWRkaXRpb25hbE1ldGFkYXRhJ10oXzB4MmNkNDdkLF8weDM3ZjhmMSkpOnRoaXNbXzB4NDlmNWE0KDB4MWY1KV0oXzB4MzdmOGYxLF8weDFkNmRkNixfMHgyY2Q0N2QsZnVuY3Rpb24oKXt2YXIgXzB4MWIwYmUxPV8weDQ5ZjVhNDtfMHg1OTJiMzQ9PT1fMHgxYjBiZTEoMHgxNjUpfHxfMHg1OTJiMzQ9PT1fMHgxYjBiZTEoMHgxZWIpfHwoZGVsZXRlIF8weDM3ZjhmMVsndmFsdWUnXSxfMHgzN2Y4ZjFbXzB4MWIwYmUxKDB4MTk5KV09ITB4MCk7fSk7fXJldHVybiBfMHgzN2Y4ZjE7fWZpbmFsbHl7XzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDIxMCldPV8weDMxMTViZSxfMHgxZDZkZDZbXzB4NDlmNWE0KDB4MjExKV09XzB4NTc2Zjc3LF8weDFkNmRkNltfMHg0OWY1YTQoMHgxOTApXT1fMHgyODA2YmE7fX1bXzB4MTI3NzM1KDB4MTQ1KV0oXzB4NDZmNWQ4LF8weDk4OTI5NCxfMHgyZTMxNmIsXzB4MjMyNzA3KXt2YXIgXzB4MjExMDQ1PV8weDEyNzczNSxfMHg0NDg3Nzg9XzB4MjMyNzA3W18weDIxMTA0NSgweDFhNSldfHxfMHgyZTMxNmJbJ3N0ckxlbmd0aCddO2lmKChfMHg0NmY1ZDg9PT1fMHgyMTEwNDUoMHgxNjQpfHxfMHg0NmY1ZDg9PT1fMHgyMTEwNDUoMHgyMDQpKSYmXzB4OTg5Mjk0W18weDIxMTA0NSgweDFhYSldKXtsZXQgXzB4ZWIzYmI1PV8weDk4OTI5NFtfMHgyMTEwNDUoMHgxYWEpXVsnbGVuZ3RoJ107XzB4MmUzMTZiW18weDIxMTA0NSgweDE4ZCldKz1fMHhlYjNiYjUsXzB4MmUzMTZiW18weDIxMTA0NSgweDE4ZCldPl8weDJlMzE2YltfMHgyMTEwNDUoMHgxNzQpXT8oXzB4OTg5Mjk0W18weDIxMTA0NSgweDE5OSldPScnLGRlbGV0ZSBfMHg5ODkyOTRbJ3ZhbHVlJ10pOl8weGViM2JiNT5fMHg0NDg3NzgmJihfMHg5ODkyOTRbXzB4MjExMDQ1KDB4MTk5KV09XzB4OTg5Mjk0W18weDIxMTA0NSgweDFhYSldWydzdWJzdHInXSgweDAsXzB4NDQ4Nzc4KSxkZWxldGUgXzB4OTg5Mjk0Wyd2YWx1ZSddKTt9fVtfMHgxMjc3MzUoMHgyMGQpXShfMHgyOGI3ZDApe3ZhciBfMHg4YTE4ODY9XzB4MTI3NzM1O3JldHVybiEhKF8weDI4YjdkMCYmXzB4NDI2ZDVmWydNYXAnXSYmdGhpc1tfMHg4YTE4ODYoMHgxOTYpXShfMHgyOGI3ZDApPT09XzB4OGExODg2KDB4MWJkKSYmXzB4MjhiN2QwW18weDhhMTg4NigweDFkZCldKTt9W18weDEyNzczNSgweDE1MyldKF8weDFlMTBjYyl7dmFyIF8weDRhMmQ4MD1fMHgxMjc3MzU7aWYoXzB4MWUxMGNjW18weDRhMmQ4MCgweDIwOCldKC9eXFxcXGQrJC8pKXJldHVybiBfMHgxZTEwY2M7dmFyIF8weDM0MmVjYTt0cnl7XzB4MzQyZWNhPUpTT05bXzB4NGEyZDgwKDB4MWZhKV0oJycrXzB4MWUxMGNjKTt9Y2F0Y2h7XzB4MzQyZWNhPSdcXFxceDIyJyt0aGlzW18weDRhMmQ4MCgweDE5NildKF8weDFlMTBjYykrJ1xcXFx4MjInO31yZXR1cm4gXzB4MzQyZWNhW18weDRhMmQ4MCgweDIwOCldKC9eXFxcIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVxcXCIkLyk/XzB4MzQyZWNhPV8weDM0MmVjYVtfMHg0YTJkODAoMHgxYTApXSgweDEsXzB4MzQyZWNhW18weDRhMmQ4MCgweDFiYyldLTB4Mik6XzB4MzQyZWNhPV8weDM0MmVjYVtfMHg0YTJkODAoMHgxNTApXSgvJy9nLCdcXFxceDVjXFxcXHgyNycpW18weDRhMmQ4MCgweDE1MCldKC9cXFxcXFxcXFxcXCIvZywnXFxcXHgyMicpW18weDRhMmQ4MCgweDE1MCldKC8oXlxcXCJ8XFxcIiQpL2csJ1xcXFx4MjcnKSxfMHgzNDJlY2E7fVtfMHgxMjc3MzUoMHgxZjUpXShfMHgzMTExNDEsXzB4NGZlODc0LF8weDRiNDU2ZSxfMHgyYTFmODApe3ZhciBfMHgzYzE2NTc9XzB4MTI3NzM1O3RoaXNbXzB4M2MxNjU3KDB4MTk0KV0oXzB4MzExMTQxLF8weDRmZTg3NCksXzB4MmExZjgwJiZfMHgyYTFmODAoKSx0aGlzW18weDNjMTY1NygweDE2OSldKF8weDRiNDU2ZSxfMHgzMTExNDEpLHRoaXNbJ190cmVlTm9kZVByb3BlcnRpZXNBZnRlckZ1bGxWYWx1ZSddKF8weDMxMTE0MSxfMHg0ZmU4NzQpO31bXzB4MTI3NzM1KDB4MTk0KV0oXzB4M2ZkNzBiLF8weDJkOGFmOSl7dmFyIF8weDM2ZGNmND1fMHgxMjc3MzU7dGhpc1snX3NldE5vZGVJZCddKF8weDNmZDcwYixfMHgyZDhhZjkpLHRoaXNbJ19zZXROb2RlUXVlcnlQYXRoJ10oXzB4M2ZkNzBiLF8weDJkOGFmOSksdGhpc1tfMHgzNmRjZjQoMHgxN2QpXShfMHgzZmQ3MGIsXzB4MmQ4YWY5KSx0aGlzW18weDM2ZGNmNCgweDFhZSldKF8weDNmZDcwYixfMHgyZDhhZjkpO31bJ19zZXROb2RlSWQnXShfMHg0ZTM4NTIsXzB4NTkwN2U4KXt9Wydfc2V0Tm9kZVF1ZXJ5UGF0aCddKF8weDFjYzhiNCxfMHgyNjgxOWIpe31bJ19zZXROb2RlTGFiZWwnXShfMHg1NjVjY2YsXzB4MTk5YTY0KXt9W18weDEyNzczNSgweDE0ZildKF8weDEyMGM2Myl7dmFyIF8weDI3MDhlMj1fMHgxMjc3MzU7cmV0dXJuIF8weDEyMGM2Mz09PXRoaXNbXzB4MjcwOGUyKDB4MjAxKV07fVtfMHgxMjc3MzUoMHgxYzApXShfMHgyNjUzYzcsXzB4MmZlMjY3KXt2YXIgXzB4MmU0MWI0PV8weDEyNzczNTt0aGlzW18weDJlNDFiNCgweDFmMCldKF8weDI2NTNjNyxfMHgyZmUyNjcpLHRoaXNbXzB4MmU0MWI0KDB4MWQ0KV0oXzB4MjY1M2M3KSxfMHgyZmUyNjdbXzB4MmU0MWI0KDB4MTRkKV0mJnRoaXNbXzB4MmU0MWI0KDB4MTg1KV0oXzB4MjY1M2M3KSx0aGlzW18weDJlNDFiNCgweDFlMCldKF8weDI2NTNjNyxfMHgyZmUyNjcpLHRoaXNbXzB4MmU0MWI0KDB4MTkxKV0oXzB4MjY1M2M3LF8weDJmZTI2NyksdGhpc1tfMHgyZTQxYjQoMHgyMTkpXShfMHgyNjUzYzcpO31bJ19hZGRpdGlvbmFsTWV0YWRhdGEnXShfMHhhYTE0MDIsXzB4MWQwZTY5KXt2YXIgXzB4MmI2ZGE4PV8weDEyNzczNTtsZXQgXzB4NTc5MGQ1O3RyeXtfMHg0MjZkNWZbXzB4MmI2ZGE4KDB4MWRmKV0mJihfMHg1NzkwZDU9XzB4NDI2ZDVmW18weDJiNmRhOCgweDFkZildWydlcnJvciddLF8weDQyNmQ1ZlsnY29uc29sZSddW18weDJiNmRhOCgweDIwYyldPWZ1bmN0aW9uKCl7fSksXzB4YWExNDAyJiZ0eXBlb2YgXzB4YWExNDAyW18weDJiNmRhOCgweDFiYyldPT1fMHgyYjZkYTgoMHgxN2UpJiYoXzB4MWQwZTY5W18weDJiNmRhOCgweDFiYyldPV8weGFhMTQwMlsnbGVuZ3RoJ10pO31jYXRjaHt9ZmluYWxseXtfMHg1NzkwZDUmJihfMHg0MjZkNWZbXzB4MmI2ZGE4KDB4MWRmKV1bXzB4MmI2ZGE4KDB4MjBjKV09XzB4NTc5MGQ1KTt9aWYoXzB4MWQwZTY5Wyd0eXBlJ109PT1fMHgyYjZkYTgoMHgxN2UpfHxfMHgxZDBlNjlbXzB4MmI2ZGE4KDB4MWFjKV09PT0nTnVtYmVyJyl7aWYoaXNOYU4oXzB4MWQwZTY5W18weDJiNmRhOCgweDFhYSldKSlfMHgxZDBlNjlbJ25hbiddPSEweDAsZGVsZXRlIF8weDFkMGU2OVtfMHgyYjZkYTgoMHgxYWEpXTtlbHNlIHN3aXRjaChfMHgxZDBlNjlbXzB4MmI2ZGE4KDB4MWFhKV0pe2Nhc2UgTnVtYmVyW18weDJiNmRhOCgweDE3YyldOl8weDFkMGU2OVtfMHgyYjZkYTgoMHgxZDkpXT0hMHgwLGRlbGV0ZSBfMHgxZDBlNjlbXzB4MmI2ZGE4KDB4MWFhKV07YnJlYWs7Y2FzZSBOdW1iZXJbXzB4MmI2ZGE4KDB4MWEyKV06XzB4MWQwZTY5W18weDJiNmRhOCgweDFjYildPSEweDAsZGVsZXRlIF8weDFkMGU2OVsndmFsdWUnXTticmVhaztjYXNlIDB4MDp0aGlzWydfaXNOZWdhdGl2ZVplcm8nXShfMHgxZDBlNjlbJ3ZhbHVlJ10pJiYoXzB4MWQwZTY5WyduZWdhdGl2ZVplcm8nXT0hMHgwKTticmVhazt9fWVsc2UgXzB4MWQwZTY5W18weDJiNmRhOCgweDFhYyldPT09XzB4MmI2ZGE4KDB4MTczKSYmdHlwZW9mIF8weGFhMTQwMltfMHgyYjZkYTgoMHgxYzkpXT09J3N0cmluZycmJl8weGFhMTQwMltfMHgyYjZkYTgoMHgxYzkpXSYmXzB4MWQwZTY5WyduYW1lJ10mJl8weGFhMTQwMltfMHgyYjZkYTgoMHgxYzkpXSE9PV8weDFkMGU2OVtfMHgyYjZkYTgoMHgxYzkpXSYmKF8weDFkMGU2OVsnZnVuY05hbWUnXT1fMHhhYTE0MDJbXzB4MmI2ZGE4KDB4MWM5KV0pO31bXzB4MTI3NzM1KDB4MWJlKV0oXzB4NWJmNzlmKXt2YXIgXzB4MWUwYmYyPV8weDEyNzczNTtyZXR1cm4gMHgxL18weDViZjc5Zj09PU51bWJlcltfMHgxZTBiZjIoMHgxYTIpXTt9W18weDEyNzczNSgweDE4NSldKF8weDllYzQ2Myl7dmFyIF8weDI0NDY0Mj1fMHgxMjc3MzU7IV8weDllYzQ2M1sncHJvcHMnXXx8IV8weDllYzQ2M1tfMHgyNDQ2NDIoMHgxNjIpXVtfMHgyNDQ2NDIoMHgxYmMpXXx8XzB4OWVjNDYzW18weDI0NDY0MigweDFhYyldPT09XzB4MjQ0NjQyKDB4MWU2KXx8XzB4OWVjNDYzW18weDI0NDY0MigweDFhYyldPT09XzB4MjQ0NjQyKDB4MWRiKXx8XzB4OWVjNDYzWyd0eXBlJ109PT1fMHgyNDQ2NDIoMHgxYzUpfHxfMHg5ZWM0NjNbXzB4MjQ0NjQyKDB4MTYyKV1bJ3NvcnQnXShmdW5jdGlvbihfMHg0ZWE5ZTAsXzB4MzVjMzIzKXt2YXIgXzB4NGI1Y2IyPV8weDI0NDY0MixfMHgyMDM2ZjM9XzB4NGVhOWUwW18weDRiNWNiMigweDFjOSldW18weDRiNWNiMigweDIwMildKCksXzB4YmYwZTc1PV8weDM1YzMyM1tfMHg0YjVjYjIoMHgxYzkpXVtfMHg0YjVjYjIoMHgyMDIpXSgpO3JldHVybiBfMHgyMDM2ZjM8XzB4YmYwZTc1Py0weDE6XzB4MjAzNmYzPl8weGJmMGU3NT8weDE6MHgwO30pO31bJ19hZGRGdW5jdGlvbnNOb2RlJ10oXzB4NTcxNDExLF8weDUxMTY2Zil7dmFyIF8weDE0NDM4ND1fMHgxMjc3MzU7aWYoIShfMHg1MTE2NmZbXzB4MTQ0Mzg0KDB4MTg3KV18fCFfMHg1NzE0MTFbXzB4MTQ0Mzg0KDB4MTYyKV18fCFfMHg1NzE0MTFbXzB4MTQ0Mzg0KDB4MTYyKV1bJ2xlbmd0aCddKSl7Zm9yKHZhciBfMHgxNWYzODE9W10sXzB4NGI3ZTRjPVtdLF8weDFlZThkOT0weDAsXzB4MTU3ZDFmPV8weDU3MTQxMVtfMHgxNDQzODQoMHgxNjIpXVsnbGVuZ3RoJ107XzB4MWVlOGQ5PF8weDE1N2QxZjtfMHgxZWU4ZDkrKyl7dmFyIF8weDVkMTFiZT1fMHg1NzE0MTFbXzB4MTQ0Mzg0KDB4MTYyKV1bXzB4MWVlOGQ5XTtfMHg1ZDExYmVbXzB4MTQ0Mzg0KDB4MWFjKV09PT1fMHgxNDQzODQoMHgxNzMpP18weDE1ZjM4MVtfMHgxNDQzODQoMHgxNzIpXShfMHg1ZDExYmUpOl8weDRiN2U0Y1tfMHgxNDQzODQoMHgxNzIpXShfMHg1ZDExYmUpO31pZighKCFfMHg0YjdlNGNbXzB4MTQ0Mzg0KDB4MWJjKV18fF8weDE1ZjM4MVsnbGVuZ3RoJ108PTB4MSkpe18weDU3MTQxMVtfMHgxNDQzODQoMHgxNjIpXT1fMHg0YjdlNGM7dmFyIF8weDQzZDMxYz17J2Z1bmN0aW9uc05vZGUnOiEweDAsJ3Byb3BzJzpfMHgxNWYzODF9O3RoaXNbJ19zZXROb2RlSWQnXShfMHg0M2QzMWMsXzB4NTExNjZmKSx0aGlzWydfc2V0Tm9kZUxhYmVsJ10oXzB4NDNkMzFjLF8weDUxMTY2ZiksdGhpc1tfMHgxNDQzODQoMHgxZDQpXShfMHg0M2QzMWMpLHRoaXNbJ19zZXROb2RlUGVybWlzc2lvbnMnXShfMHg0M2QzMWMsXzB4NTExNjZmKSxfMHg0M2QzMWNbJ2lkJ10rPSdcXFxceDIwZicsXzB4NTcxNDExWydwcm9wcyddW18weDE0NDM4NCgweDIxNildKF8weDQzZDMxYyk7fX19W18weDEyNzczNSgweDE5MSldKF8weDQ5NmE5YSxfMHhiZWVhNzcpe31bXzB4MTI3NzM1KDB4MWQ0KV0oXzB4MjJiMDIyKXt9W18weDEyNzczNSgweDIwZildKF8weDM1NzQ3Myl7dmFyIF8weGU0YTlkMD1fMHgxMjc3MzU7cmV0dXJuIEFycmF5Wydpc0FycmF5J10oXzB4MzU3NDczKXx8dHlwZW9mIF8weDM1NzQ3Mz09XzB4ZTRhOWQwKDB4MTY2KSYmdGhpc1snX29iamVjdFRvU3RyaW5nJ10oXzB4MzU3NDczKT09PSdbb2JqZWN0XFxcXHgyMEFycmF5XSc7fVtfMHgxMjc3MzUoMHgxYWUpXShfMHgyZjQwZTYsXzB4NDA1NDFjKXt9W18weDEyNzczNSgweDIxOSldKF8weDQ1ZmNhZSl7dmFyIF8weDVlYjMzOD1fMHgxMjc3MzU7ZGVsZXRlIF8weDQ1ZmNhZVsnX2hhc1N5bWJvbFByb3BlcnR5T25JdHNQYXRoJ10sZGVsZXRlIF8weDQ1ZmNhZVsnX2hhc1NldE9uSXRzUGF0aCddLGRlbGV0ZSBfMHg0NWZjYWVbXzB4NWViMzM4KDB4MjI2KV07fVtfMHgxMjc3MzUoMHgxN2QpXShfMHgyYzhlOTgsXzB4NWQxNmU5KXt9fWxldCBfMHgzOGZkMzU9bmV3IF8weDJlMGQzYygpLF8weDNhZTJjYz17J3Byb3BzJzoweDY0LCdlbGVtZW50cyc6MHg2NCwnc3RyTGVuZ3RoJzoweDQwMCoweDMyLCd0b3RhbFN0ckxlbmd0aCc6MHg0MDAqMHgzMiwnYXV0b0V4cGFuZExpbWl0JzoweDEzODgsJ2F1dG9FeHBhbmRNYXhEZXB0aCc6MHhhfSxfMHg0ZTQ0MT17J3Byb3BzJzoweDUsJ2VsZW1lbnRzJzoweDUsJ3N0ckxlbmd0aCc6MHgxMDAsJ3RvdGFsU3RyTGVuZ3RoJzoweDEwMCoweDMsJ2F1dG9FeHBhbmRMaW1pdCc6MHgxZSwnYXV0b0V4cGFuZE1heERlcHRoJzoweDJ9O2Z1bmN0aW9uIF8weGE3MTNkNyhfMHgxZDRiZDksXzB4NTY3MDBjLF8weDVlMzVhMixfMHhjYTVmYmEsXzB4NWNiOWIyLF8weDQ2ZWNiMyl7dmFyIF8weGM5NDQyYz1fMHgxMjc3MzU7bGV0IF8weDFhZDgyYixfMHg1NjhmMDA7dHJ5e18weDU2OGYwMD1fMHg1YjY4OWQoKSxfMHgxYWQ4MmI9XzB4MmRiYmI3W18weDU2NzAwY10sIV8weDFhZDgyYnx8XzB4NTY4ZjAwLV8weDFhZDgyYlsndHMnXT4weDFmNCYmXzB4MWFkODJiW18weGM5NDQyYygweDFiYSldJiZfMHgxYWQ4MmJbXzB4Yzk0NDJjKDB4MTlhKV0vXzB4MWFkODJiW18weGM5NDQyYygweDFiYSldPDB4NjQ/KF8weDJkYmJiN1tfMHg1NjcwMGNdPV8weDFhZDgyYj17J2NvdW50JzoweDAsJ3RpbWUnOjB4MCwndHMnOl8weDU2OGYwMH0sXzB4MmRiYmI3W18weGM5NDQyYygweDE4ZildPXt9KTpfMHg1NjhmMDAtXzB4MmRiYmI3W18weGM5NDQyYygweDE4ZildWyd0cyddPjB4MzImJl8weDJkYmJiN1tfMHhjOTQ0MmMoMHgxOGYpXVtfMHhjOTQ0MmMoMHgxYmEpXSYmXzB4MmRiYmI3W18weGM5NDQyYygweDE4ZildWyd0aW1lJ10vXzB4MmRiYmI3W18weGM5NDQyYygweDE4ZildW18weGM5NDQyYygweDFiYSldPDB4NjQmJihfMHgyZGJiYjdbXzB4Yzk0NDJjKDB4MThmKV09e30pO2xldCBfMHg1NWNmYzk9W10sXzB4ODQxZTU2PV8weDFhZDgyYltfMHhjOTQ0MmMoMHgxYmIpXXx8XzB4MmRiYmI3WydoaXRzJ11bXzB4Yzk0NDJjKDB4MWJiKV0/XzB4NGU0NDE6XzB4M2FlMmNjLF8weDk3ZTI3MD1fMHgzZDRhNDI9Pnt2YXIgXzB4OTc0YWUwPV8weGM5NDQyYztsZXQgXzB4NTMzY2Y4PXt9O3JldHVybiBfMHg1MzNjZjhbXzB4OTc0YWUwKDB4MTYyKV09XzB4M2Q0YTQyW18weDk3NGFlMCgweDE2MildLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxYjYpXT1fMHgzZDRhNDJbJ2VsZW1lbnRzJ10sXzB4NTMzY2Y4WydzdHJMZW5ndGgnXT1fMHgzZDRhNDJbXzB4OTc0YWUwKDB4MWE1KV0sXzB4NTMzY2Y4Wyd0b3RhbFN0ckxlbmd0aCddPV8weDNkNGE0MltfMHg5NzRhZTAoMHgxNzQpXSxfMHg1MzNjZjhbXzB4OTc0YWUwKDB4MjE3KV09XzB4M2Q0YTQyW18weDk3NGFlMCgweDIxNyldLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxNzkpXT1fMHgzZDRhNDJbXzB4OTc0YWUwKDB4MTc5KV0sXzB4NTMzY2Y4W18weDk3NGFlMCgweDE0ZCldPSEweDEsXzB4NTMzY2Y4W18weDk3NGFlMCgweDE4NyldPSFfMHg1OGJkOTMsXzB4NTMzY2Y4W18weDk3NGFlMCgweDIxMSldPTB4MSxfMHg1MzNjZjhbXzB4OTc0YWUwKDB4MTZkKV09MHgwLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxNDYpXT1fMHg5NzRhZTAoMHgxZTMpLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxYTkpXT0ncm9vdF9leHAnLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxZWYpXT0hMHgwLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxYTYpXT1bXSxfMHg1MzNjZjhbXzB4OTc0YWUwKDB4MTU2KV09MHgwLF8weDUzM2NmOFsncmVzb2x2ZUdldHRlcnMnXT0hMHgwLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxOGQpXT0weDAsXzB4NTMzY2Y4W18weDk3NGFlMCgweDIxNCldPXsnY3VycmVudCc6dm9pZCAweDAsJ3BhcmVudCc6dm9pZCAweDAsJ2luZGV4JzoweDB9LF8weDUzM2NmODt9O2Zvcih2YXIgXzB4NDZiN2I2PTB4MDtfMHg0NmI3YjY8XzB4NWNiOWIyW18weGM5NDQyYygweDFiYyldO18weDQ2YjdiNisrKV8weDU1Y2ZjOVtfMHhjOTQ0MmMoMHgxNzIpXShfMHgzOGZkMzVbXzB4Yzk0NDJjKDB4MjFlKV0oeyd0aW1lTm9kZSc6XzB4MWQ0YmQ5PT09XzB4Yzk0NDJjKDB4MTlhKXx8dm9pZCAweDB9LF8weDVjYjliMltfMHg0NmI3YjZdLF8weDk3ZTI3MChfMHg4NDFlNTYpLHt9KSk7aWYoXzB4MWQ0YmQ5PT09XzB4Yzk0NDJjKDB4MTRiKXx8XzB4MWQ0YmQ5PT09XzB4Yzk0NDJjKDB4MjBjKSl7bGV0IF8weDE1ZmRmMz1FcnJvcltfMHhjOTQ0MmMoMHgyMWMpXTt0cnl7RXJyb3JbJ3N0YWNrVHJhY2VMaW1pdCddPTB4MS8weDAsXzB4NTVjZmM5W18weGM5NDQyYygweDE3MildKF8weDM4ZmQzNVtfMHhjOTQ0MmMoMHgyMWUpXSh7J3N0YWNrTm9kZSc6ITB4MH0sbmV3IEVycm9yKClbXzB4Yzk0NDJjKDB4MWU0KV0sXzB4OTdlMjcwKF8weDg0MWU1NikseydzdHJMZW5ndGgnOjB4MS8weDB9KSk7fWZpbmFsbHl7RXJyb3JbXzB4Yzk0NDJjKDB4MjFjKV09XzB4MTVmZGYzO319cmV0dXJueydtZXRob2QnOidsb2cnLCd2ZXJzaW9uJzpfMHgyZWZiMzIsJ2FyZ3MnOlt7J3RzJzpfMHg1ZTM1YTIsJ3Nlc3Npb24nOl8weGNhNWZiYSwnYXJncyc6XzB4NTVjZmM5LCdpZCc6XzB4NTY3MDBjLCdjb250ZXh0JzpfMHg0NmVjYjN9XX07fWNhdGNoKF8weDlkM2VmNSl7cmV0dXJueydtZXRob2QnOl8weGM5NDQyYygweDE2OCksJ3ZlcnNpb24nOl8weDJlZmIzMiwnYXJncyc6W3sndHMnOl8weDVlMzVhMiwnc2Vzc2lvbic6XzB4Y2E1ZmJhLCdhcmdzJzpbeyd0eXBlJzpfMHhjOTQ0MmMoMHgyMWQpLCdlcnJvcic6XzB4OWQzZWY1JiZfMHg5ZDNlZjVbXzB4Yzk0NDJjKDB4MWExKV19XSwnaWQnOl8weDU2NzAwYywnY29udGV4dCc6XzB4NDZlY2IzfV19O31maW5hbGx5e3RyeXtpZihfMHgxYWQ4MmImJl8weDU2OGYwMCl7bGV0IF8weDM4MzM4ZT1fMHg1YjY4OWQoKTtfMHgxYWQ4MmJbJ2NvdW50J10rKyxfMHgxYWQ4MmJbJ3RpbWUnXSs9XzB4MjMyZDBkKF8weDU2OGYwMCxfMHgzODMzOGUpLF8weDFhZDgyYlsndHMnXT1fMHgzODMzOGUsXzB4MmRiYmI3WydoaXRzJ11bJ2NvdW50J10rKyxfMHgyZGJiYjdbJ2hpdHMnXVtfMHhjOTQ0MmMoMHgxOWEpXSs9XzB4MjMyZDBkKF8weDU2OGYwMCxfMHgzODMzOGUpLF8weDJkYmJiN1tfMHhjOTQ0MmMoMHgxOGYpXVsndHMnXT1fMHgzODMzOGUsKF8weDFhZDgyYlsnY291bnQnXT4weDMyfHxfMHgxYWQ4MmJbXzB4Yzk0NDJjKDB4MTlhKV0+MHg2NCkmJihfMHgxYWQ4MmJbXzB4Yzk0NDJjKDB4MWJiKV09ITB4MCksKF8weDJkYmJiN1tfMHhjOTQ0MmMoMHgxOGYpXVtfMHhjOTQ0MmMoMHgxYmEpXT4weDNlOHx8XzB4MmRiYmI3W18weGM5NDQyYygweDE4ZildW18weGM5NDQyYygweDE5YSldPjB4MTJjKSYmKF8weDJkYmJiN1tfMHhjOTQ0MmMoMHgxOGYpXVtfMHhjOTQ0MmMoMHgxYmIpXT0hMHgwKTt9fWNhdGNoe319fXJldHVybiBfMHhhNzEzZDc7fSgoXzB4OTBjMzdhLF8weDFkNzQ4ZCxfMHgyN2YxODQsXzB4MWMzZTQxLF8weDE3NTJiOSxfMHgxNWM0YmUsXzB4NDNhYjZjLF8weDVlMDM1NyxfMHgzODU4NmMsXzB4MTNlOWFlLF8weDg5ODJjMSk9Pnt2YXIgXzB4NTkzMTEyPV8weDMxZTQ4NjtpZihfMHg5MGMzN2FbJ19jb25zb2xlX25pbmphJ10pcmV0dXJuIF8weDkwYzM3YVtfMHg1OTMxMTIoMHgyMjMpXTtpZighSChfMHg5MGMzN2EsXzB4NWUwMzU3LF8weDE3NTJiOSkpcmV0dXJuIF8weDkwYzM3YVtfMHg1OTMxMTIoMHgyMjMpXT17J2NvbnNvbGVMb2cnOigpPT57fSwnY29uc29sZVRyYWNlJzooKT0+e30sJ2NvbnNvbGVUaW1lJzooKT0+e30sJ2NvbnNvbGVUaW1lRW5kJzooKT0+e30sJ2F1dG9Mb2cnOigpPT57fSwnYXV0b0xvZ01hbnknOigpPT57fSwnYXV0b1RyYWNlTWFueSc6KCk9Pnt9LCdjb3ZlcmFnZSc6KCk9Pnt9LCdhdXRvVHJhY2UnOigpPT57fSwnYXV0b1RpbWUnOigpPT57fSwnYXV0b1RpbWVFbmQnOigpPT57fX0sXzB4OTBjMzdhW18weDU5MzExMigweDIyMyldO2xldCBfMHg0MDk3ZTY9QihfMHg5MGMzN2EpLF8weDE4NWFiYT1fMHg0MDk3ZTZbJ2VsYXBzZWQnXSxfMHgyOGVmMWM9XzB4NDA5N2U2W18weDU5MzExMigweDE3NyldLF8weDM0ZTRjMz1fMHg0MDk3ZTZbXzB4NTkzMTEyKDB4MjJiKV0sXzB4NDQzYzU5PXsnaGl0cyc6e30sJ3RzJzp7fX0sXzB4NTVhYmNjPVgoXzB4OTBjMzdhLF8weDM4NTg2YyxfMHg0NDNjNTksXzB4MTVjNGJlKSxfMHhhOGUxNT1fMHg0Y2Y4OTQ9PntfMHg0NDNjNTlbJ3RzJ11bXzB4NGNmODk0XT1fMHgyOGVmMWMoKTt9LF8weDFmYjNmNj0oXzB4NTI2NGMzLF8weDViYzFkYyk9Pnt2YXIgXzB4MzAzYTNkPV8weDU5MzExMjtsZXQgXzB4MmI1ZjQyPV8weDQ0M2M1OVsndHMnXVtfMHg1YmMxZGNdO2lmKGRlbGV0ZSBfMHg0NDNjNTlbJ3RzJ11bXzB4NWJjMWRjXSxfMHgyYjVmNDIpe2xldCBfMHgyMjdhND1fMHgxODVhYmEoXzB4MmI1ZjQyLF8weDI4ZWYxYygpKTtfMHg0ZTE1OGUoXzB4NTVhYmNjKF8weDMwM2EzZCgweDE5YSksXzB4NTI2NGMzLF8weDM0ZTRjMygpLF8weDE4NGI0OCxbXzB4MjI3YTRdLF8weDViYzFkYykpO319LF8weDNkN2ZhMT1fMHgzYzVhNjI9Pnt2YXIgXzB4NDdhZjMzPV8weDU5MzExMixfMHgzZWUwNzI7cmV0dXJuIF8weDE3NTJiOT09PV8weDQ3YWYzMygweDIyYykmJl8weDkwYzM3YVsnb3JpZ2luJ10mJigoXzB4M2VlMDcyPV8weDNjNWE2Mj09bnVsbD92b2lkIDB4MDpfMHgzYzVhNjJbJ2FyZ3MnXSk9PW51bGw/dm9pZCAweDA6XzB4M2VlMDcyW18weDQ3YWYzMygweDFiYyldKSYmKF8weDNjNWE2MlsnYXJncyddWzB4MF1bXzB4NDdhZjMzKDB4MWQwKV09XzB4OTBjMzdhW18weDQ3YWYzMygweDFkMCldKSxfMHgzYzVhNjI7fTtfMHg5MGMzN2FbJ19jb25zb2xlX25pbmphJ109eydjb25zb2xlTG9nJzooXzB4NWEzNTJlLF8weDQ4MzVkYSk9Pnt2YXIgXzB4NDU0YzAxPV8weDU5MzExMjtfMHg5MGMzN2FbXzB4NDU0YzAxKDB4MWRmKV1bXzB4NDU0YzAxKDB4MTY4KV1bXzB4NDU0YzAxKDB4MWM5KV0hPT1fMHg0NTRjMDEoMHgxOWYpJiZfMHg0ZTE1OGUoXzB4NTVhYmNjKF8weDQ1NGMwMSgweDE2OCksXzB4NWEzNTJlLF8weDM0ZTRjMygpLF8weDE4NGI0OCxfMHg0ODM1ZGEpKTt9LCdjb25zb2xlVHJhY2UnOihfMHgyZDQ1MTMsXzB4NGU3OTE5KT0+e3ZhciBfMHgxZGY5OWY9XzB4NTkzMTEyLF8weDFjMGM1OCxfMHgxNTFlN2E7XzB4OTBjMzdhW18weDFkZjk5ZigweDFkZildW18weDFkZjk5ZigweDE2OCldW18weDFkZjk5ZigweDFjOSldIT09J2Rpc2FibGVkVHJhY2UnJiYoKF8weDE1MWU3YT0oXzB4MWMwYzU4PV8weDkwYzM3YVsncHJvY2VzcyddKT09bnVsbD92b2lkIDB4MDpfMHgxYzBjNThbXzB4MWRmOTlmKDB4MTUyKV0pIT1udWxsJiZfMHgxNTFlN2FbXzB4MWRmOTlmKDB4MjE0KV0mJihfMHg5MGMzN2FbXzB4MWRmOTlmKDB4MThlKV09ITB4MCksXzB4NGUxNThlKF8weDNkN2ZhMShfMHg1NWFiY2MoXzB4MWRmOTlmKDB4MTRiKSxfMHgyZDQ1MTMsXzB4MzRlNGMzKCksXzB4MTg0YjQ4LF8weDRlNzkxOSkpKSk7fSwnY29uc29sZUVycm9yJzooXzB4MjEwNTY3LF8weDMwYTAyNSk9Pnt2YXIgXzB4M2Q2Y2ZjPV8weDU5MzExMjtfMHg5MGMzN2FbXzB4M2Q2Y2ZjKDB4MThlKV09ITB4MCxfMHg0ZTE1OGUoXzB4M2Q3ZmExKF8weDU1YWJjYygnZXJyb3InLF8weDIxMDU2NyxfMHgzNGU0YzMoKSxfMHgxODRiNDgsXzB4MzBhMDI1KSkpO30sJ2NvbnNvbGVUaW1lJzpfMHgxOGI4ZDk9PntfMHhhOGUxNShfMHgxOGI4ZDkpO30sJ2NvbnNvbGVUaW1lRW5kJzooXzB4M2NmNzc4LF8weDU5Mjc3Nik9PntfMHgxZmIzZjYoXzB4NTkyNzc2LF8weDNjZjc3OCk7fSwnYXV0b0xvZyc6KF8weDJlZjc2ZixfMHgzOTkxNjApPT57dmFyIF8weDQ5YjNhNT1fMHg1OTMxMTI7XzB4NGUxNThlKF8weDU1YWJjYyhfMHg0OWIzYTUoMHgxNjgpLF8weDM5OTE2MCxfMHgzNGU0YzMoKSxfMHgxODRiNDgsW18weDJlZjc2Zl0pKTt9LCdhdXRvTG9nTWFueSc6KF8weDRiMDhjYixfMHg0ZTdkZTQpPT57dmFyIF8weDE4NTg0Yj1fMHg1OTMxMTI7XzB4NGUxNThlKF8weDU1YWJjYyhfMHgxODU4NGIoMHgxNjgpLF8weDRiMDhjYixfMHgzNGU0YzMoKSxfMHgxODRiNDgsXzB4NGU3ZGU0KSk7fSwnYXV0b1RyYWNlJzooXzB4M2I2OWYwLF8weDFkN2ExOSk9Pnt2YXIgXzB4MzdlZDI1PV8weDU5MzExMjtfMHg0ZTE1OGUoXzB4M2Q3ZmExKF8weDU1YWJjYyhfMHgzN2VkMjUoMHgxNGIpLF8weDFkN2ExOSxfMHgzNGU0YzMoKSxfMHgxODRiNDgsW18weDNiNjlmMF0pKSk7fSwnYXV0b1RyYWNlTWFueSc6KF8weDQ3OWMzNCxfMHgxOWEyYWIpPT57XzB4NGUxNThlKF8weDNkN2ZhMShfMHg1NWFiY2MoJ3RyYWNlJyxfMHg0NzljMzQsXzB4MzRlNGMzKCksXzB4MTg0YjQ4LF8weDE5YTJhYikpKTt9LCdhdXRvVGltZSc6KF8weDM3ZjgwMyxfMHgxNzFjMjQsXzB4NDI3NTg4KT0+e18weGE4ZTE1KF8weDQyNzU4OCk7fSwnYXV0b1RpbWVFbmQnOihfMHhhZTQ3ZmMsXzB4MmE5MDQyLF8weDNiZTYwMyk9PntfMHgxZmIzZjYoXzB4MmE5MDQyLF8weDNiZTYwMyk7fSwnY292ZXJhZ2UnOl8weDM5ZTc3NT0+e18weDRlMTU4ZSh7J21ldGhvZCc6J2NvdmVyYWdlJywndmVyc2lvbic6XzB4MTVjNGJlLCdhcmdzJzpbeydpZCc6XzB4MzllNzc1fV19KTt9fTtsZXQgXzB4NGUxNThlPXEoXzB4OTBjMzdhLF8weDFkNzQ4ZCxfMHgyN2YxODQsXzB4MWMzZTQxLF8weDE3NTJiOSxfMHgxM2U5YWUsXzB4ODk4MmMxKSxfMHgxODRiNDg9XzB4OTBjMzdhW18weDU5MzExMigweDE3NildO3JldHVybiBfMHg5MGMzN2FbXzB4NTkzMTEyKDB4MjIzKV07fSkoZ2xvYmFsVGhpcywnMTI3LjAuMC4xJyxfMHgzMWU0ODYoMHgxYjIpLF8weDMxZTQ4NigweDIwMyksXzB4MzFlNDg2KDB4MWQ3KSxfMHgzMWU0ODYoMHgyMDcpLCcxNzM3NzE4NDk3MzAzJyxfMHgzMWU0ODYoMHgyMjIpLF8weDMxZTQ4NigweDFiNyksJycsXzB4MzFlNDg2KDB4MTUxKSk7XCIpO1xufVxuY2F0Y2ggKGUpIHsgfSB9XG47IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBvb19vbyhpLCAuLi52KSB7IHRyeSB7XG4gICAgb29fY20oKS5jb25zb2xlTG9nKGksIHYpO1xufVxuY2F0Y2ggKGUpIHsgfSByZXR1cm4gdjsgfVxuO1xub29fb287IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBvb190cihpLCAuLi52KSB7IHRyeSB7XG4gICAgb29fY20oKS5jb25zb2xlVHJhY2UoaSwgdik7XG59XG5jYXRjaCAoZSkgeyB9IHJldHVybiB2OyB9XG47XG5vb190cjsgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIG9vX3R4KGksIC4uLnYpIHsgdHJ5IHtcbiAgICBvb19jbSgpLmNvbnNvbGVFcnJvcihpLCB2KTtcbn1cbmNhdGNoIChlKSB7IH0gcmV0dXJuIHY7IH1cbjtcbm9vX3R4OyAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gb29fdHModikgeyB0cnkge1xuICAgIG9vX2NtKCkuY29uc29sZVRpbWUodik7XG59XG5jYXRjaCAoZSkgeyB9IHJldHVybiB2OyB9XG47XG5vb190czsgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIG9vX3RlKHYsIGkpIHsgdHJ5IHtcbiAgICBvb19jbSgpLmNvbnNvbGVUaW1lRW5kKHYsIGkpO1xufVxuY2F0Y2ggKGUpIHsgfSByZXR1cm4gdjsgfVxuO1xub29fdGU7IC8qZXNsaW50IHVuaWNvcm4vbm8tYWJ1c2l2ZS1lc2xpbnQtZGlzYWJsZTosZXNsaW50LWNvbW1lbnRzL2Rpc2FibGUtZW5hYmxlLXBhaXI6LGVzbGludC1jb21tZW50cy9uby11bmxpbWl0ZWQtZGlzYWJsZTosZXNsaW50LWNvbW1lbnRzL25vLWFnZ3JlZ2F0aW5nLWVuYWJsZTosZXNsaW50LWNvbW1lbnRzL25vLWR1cGxpY2F0ZS1kaXNhYmxlOixlc2xpbnQtY29tbWVudHMvbm8tdW51c2VkLWRpc2FibGU6LGVzbGludC1jb21tZW50cy9uby11bnVzZWQtZW5hYmxlOiwqL1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19pbXBvcnREZWZhdWx0ID0gKHRoaXMgJiYgdGhpcy5fX2ltcG9ydERlZmF1bHQpIHx8IGZ1bmN0aW9uIChtb2QpIHtcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jb25zdCBheGlvc18xID0gX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJheGlvc1wiKSk7XG5jb25zdCBqcXVlcnlfMSA9IF9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwianF1ZXJ5XCIpKTtcbnJlcXVpcmUoXCJzZWxlY3QyXCIpO1xuY29uc3QgRHluYW1pY0ZpZWxkXzEgPSByZXF1aXJlKFwiLi9EeW5hbWljRmllbGRcIik7XG5jb25zdCBkeW5hbWljRmllbGQgPSBuZXcgRHluYW1pY0ZpZWxkXzEuRHluYW1pY0ZpZWxkKCk7XG5jbGFzcyBGb3JtQnVpbGRlciB7XG4gICAgLy8gYWRkcyBuZXcgY29sbGVjdGlvbiBvZiBzdWItZWxlbWVudFxuICAgIGFkZEZvcm0oZXYpIHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXYudGFyZ2V0O1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdmb3JtX3R5cGUnKVxuICAgICAgICAgICAgPyAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoYC5jb2xsZWN0aW9uLWNvbnRhaW5lcltmb3JtX3R5cGUgPSckeygwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2Zvcm1fdHlwZScpfSddYClcbiAgICAgICAgICAgIDogKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuY29sbGVjdGlvbi1jb250YWluZXInKTtcbiAgICAgICAgY29uc3QgY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdjaGlsZF9jb3VudCcpXG4gICAgICAgICAgICA/IHBhcnNlSW50KCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2NoaWxkX2NvdW50JykpICsgMVxuICAgICAgICAgICAgOiAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5wYXJlbnQoKS5maW5kKCcuZm9ybS1jaGlsZC1ib2R5JykubGVuZ3RoO1xuICAgICAgICBjb25zdCBwYXJlbnRfY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdwYXJlbnRfY291bnQnKVxuICAgICAgICAgICAgPyBwYXJzZUludCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdwYXJlbnRfY291bnQnKSlcbiAgICAgICAgICAgIDogKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkucGFyZW50cygnLm11bHRpLWZvcm0nKS5pbmRleCgpIC0gMTtcbiAgICAgICAgY29uc3Qgd3JhcHBlcl9wYXJlbnRfY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCd3cmFwcGVkX3BhcmVudF9jb3VudCcpXG4gICAgICAgICAgICA/IHBhcnNlSW50KCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ3dyYXBwZWRfcGFyZW50X2NvdW50JykpXG4gICAgICAgICAgICA6ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnBhcmVudHMoJy53cmFwcGVkLWNoaWxkLWJvZHknKS5pbmRleCgpIC0gMTtcbiAgICAgICAgbGV0IHByb3RvID0gY29udGFpbmVyXG4gICAgICAgICAgICAuZGF0YSgncHJvdG90eXBlJylcbiAgICAgICAgICAgIC5yZXBsYWNlKC9fX1BBUkVOVF9OQU1FX18vZywgcGFyZW50X2NvdW50KTtcbiAgICAgICAgaWYgKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2hhc19jaGlsZF9jb2xsZWN0aW9uJykpIHtcbiAgICAgICAgICAgIHByb3RvID0gcHJvdG8ucmVwbGFjZSgvX19XUkFQUEVSX05BTUVfXy9nLCBjb3VudCk7XG4gICAgICAgICAgICBwcm90byA9IHByb3RvLnJlcGxhY2UoL19fTkFNRV9fL2csIDApO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHJvdG8gPSBwcm90by5yZXBsYWNlKC9fX05BTUVfXy9nLCBjb3VudCk7XG4gICAgICAgICAgICBwcm90byA9IHByb3RvLnJlcGxhY2UoL19fV1JBUFBFUl9OQU1FX18vZywgd3JhcHBlcl9wYXJlbnRfY291bnQpO1xuICAgICAgICB9XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5hcHBlbmQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHByb3RvKSk7XG4gICAgICAgIGlmICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdoYXNfY2hpbGRfY29sbGVjdGlvbicpKSB7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KVxuICAgICAgICAgICAgICAgIC5wcmV2KCcuc3ViZWxlbWVudCcpXG4gICAgICAgICAgICAgICAgLmNoaWxkcmVuKCcud3JhcHBlZC1jaGlsZC1ib2R5JylcbiAgICAgICAgICAgICAgICAubGFzdCgpXG4gICAgICAgICAgICAgICAgLmZpbmQoJy5hZGRfdG9fY29sbGVjdGlvbicpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ3dyYXBwZWRfcGFyZW50X2NvdW50JywgY291bnQpO1xuICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldClcbiAgICAgICAgICAgICAgICAucHJldignLnN1YmVsZW1lbnQnKVxuICAgICAgICAgICAgICAgIC5jaGlsZHJlbignLndyYXBwZWQtY2hpbGQtYm9keScpXG4gICAgICAgICAgICAgICAgLmxhc3QoKVxuICAgICAgICAgICAgICAgIC5maW5kKCcuYWRkX3RvX2NvbGxlY3Rpb24nKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdwYXJlbnRfY291bnQnLCBwYXJlbnRfY291bnQpO1xuICAgICAgICB9XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpXG4gICAgICAgICAgICAucHJldigpXG4gICAgICAgICAgICAuZmluZCgnLndyYXBwZWQtY2hpbGQtYm9keScpXG4gICAgICAgICAgICAubGFzdCgpXG4gICAgICAgICAgICAuZmluZCgnLmFkZF90b19jb2xsZWN0aW9uJylcbiAgICAgICAgICAgIC5hdHRyKCd3cmFwcGVyX3BhcmVudF9jb3VudCcsIHdyYXBwZXJfcGFyZW50X2NvdW50ICE9PSBudWxsICYmIHdyYXBwZXJfcGFyZW50X2NvdW50ICE9PSB2b2lkIDAgPyB3cmFwcGVyX3BhcmVudF9jb3VudCA6IDApO1xuICAgICAgICBpZiAoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkuYXR0cignZm9ybV90eXBlJykpIHtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5sYXN0KCkuZmluZCgnLnNlbGVjdDInKS5zZWxlY3QyKHtcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBhbiBvcHRpb24nLFxuICAgICAgICAgICAgICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCcuc3ViLWF0dHJpYnV0ZScpXG4gICAgICAgICAgICAgICAgLndyYXBBbGwoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCc8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1ncm91cCBmbGV4IGZsZXgtd3JhcCBzdWItYXR0cmlidXRlLXdyYXBwZXJcIj48L2Rpdj4nKSk7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KVxuICAgICAgICAgICAgICAgIC5wcmV2KCcuc3ViZWxlbWVudCcpXG4gICAgICAgICAgICAgICAgLmNoaWxkcmVuKCcud3JhcHBlZC1jaGlsZC1ib2R5JylcbiAgICAgICAgICAgICAgICAubGFzdCgpXG4gICAgICAgICAgICAgICAgLmZpbmQoJy5zdWItYXR0cmlidXRlJylcbiAgICAgICAgICAgICAgICAud3JhcEFsbCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJzxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLWdyb3VwIGZsZXggZmxleC13cmFwIHN1Yi1hdHRyaWJ1dGUtd3JhcHBlciBtdC02XCI+PC9kaXY+JykpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldClcbiAgICAgICAgICAgICAgICAucGFyZW50KClcbiAgICAgICAgICAgICAgICAuZmluZCgnLmZvcm0tY2hpbGQtYm9keScpXG4gICAgICAgICAgICAgICAgLmxhc3QoKVxuICAgICAgICAgICAgICAgIC5maW5kKCcuc2VsZWN0MicpXG4gICAgICAgICAgICAgICAgLnNlbGVjdDIoe1xuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IGFuIG9wdGlvbicsXG4gICAgICAgICAgICAgICAgYWxsb3dDbGVhcjogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2NoaWxkX2NvdW50JywgY291bnQpO1xuICAgICAgICBkeW5hbWljRmllbGQuYWlkVHlwZVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnNlY3RvclZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICB9XG4gICAgLy8gYWRkcyBwYXJlbnQgY29sbGVjdGlvblxuICAgIGFkZFBhcmVudEZvcm0oZXYpIHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXYudGFyZ2V0O1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdmb3JtX3R5cGUnKVxuICAgICAgICAgICAgPyAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoYC5wYXJlbnQtY29sbGVjdGlvbltmb3JtX3R5cGUgPSckeygwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2Zvcm1fdHlwZScpfSddYClcbiAgICAgICAgICAgIDogKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcucGFyZW50LWNvbGxlY3Rpb24nKTtcbiAgICAgICAgY29uc3QgY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdwYXJlbnRfY291bnQnKVxuICAgICAgICAgICAgPyBwYXJzZUludCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdwYXJlbnRfY291bnQnKSkgKyAxXG4gICAgICAgICAgICA6ICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5wcmV2KCkuZmluZCgnLm11bHRpLWZvcm0nKS5sZW5ndGhcbiAgICAgICAgICAgICAgICA/ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5maW5kKCcubXVsdGktZm9ybScpLmxlbmd0aFxuICAgICAgICAgICAgICAgIDogKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkucHJldigpLmZpbmQoJy53cmFwcGVkLWNoaWxkLWJvZHknKS5sZW5ndGgpICsgMTtcbiAgICAgICAgbGV0IHByb3RvID0gY29udGFpbmVyLmRhdGEoJ3Byb3RvdHlwZScpLnJlcGxhY2UoL19fUEFSRU5UX05BTUVfXy9nLCBjb3VudCk7XG4gICAgICAgIHByb3RvID0gcHJvdG8ucmVwbGFjZSgvX19OQU1FX18vZywgMCk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5hcHBlbmQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHByb3RvKSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5maW5kKCcubXVsdGktZm9ybScpLmxhc3QoKS5maW5kKCcuc2VsZWN0MicpLnNlbGVjdDIoe1xuICAgICAgICAgICAgcGxhY2Vob2xkZXI6ICdTZWxlY3QgYW4gb3B0aW9uJyxcbiAgICAgICAgICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KVxuICAgICAgICAgICAgLnByZXYoKVxuICAgICAgICAgICAgLmZpbmQoJy5tdWx0aS1mb3JtJylcbiAgICAgICAgICAgIC5sYXN0KClcbiAgICAgICAgICAgIC5maW5kKCcuYWRkX3RvX2NvbGxlY3Rpb24nKVxuICAgICAgICAgICAgLmF0dHIoJ3BhcmVudF9jb3VudCcsIGNvdW50KTtcbiAgICAgICAgdGhpcy5hZGRXcmFwcGVyT25BZGQodGFyZ2V0KTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkuYXR0cigncGFyZW50X2NvdW50JywgY291bnQpO1xuICAgICAgICBkeW5hbWljRmllbGQuaHVtYW5pdGFyaWFuU2NvcGVIaWRlVm9jYWJ1bGFyeVVyaSgpO1xuICAgICAgICBkeW5hbWljRmllbGQuY291bnRyeUJ1ZGdldEhpZGVDb2RlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnNlY3RvclZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnJlY2lwaWVudFZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnBvbGljeVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnRhZ1ZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnRyYW5zYWN0aW9uQWlkVHlwZVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLmluZGljYXRvclJlZmVyZW5jZUhpZGVGaWVsZFVyaSgpO1xuICAgIH1cbiAgICAvLyBkZWxldGVzIGNvbGxlY3Rpb25cbiAgICBkZWxldGVGb3JtKGV2KSB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGV2LnRhcmdldDtcbiAgICAgICAgY29uc3QgY29sbGVjdGlvbkxlbmd0aCA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLm11bHRpLWZvcm0nKS5sZW5ndGhcbiAgICAgICAgICAgID8gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkuY2xvc2VzdCgnLnN1YmVsZW1lbnQnKS5maW5kKCcuZm9ybS1jaGlsZC1ib2R5JykubGVuZ3RoXG4gICAgICAgICAgICA6ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmZvcm0tY2hpbGQtYm9keScpLmxlbmd0aDtcbiAgICAgICAgY29uc3QgY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5hZGRfdG9fY29sbGVjdGlvbicpLmF0dHIoJ2NoaWxkX2NvdW50JylcbiAgICAgICAgICAgID8gcGFyc2VJbnQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuYWRkX3RvX2NvbGxlY3Rpb24nKS5hdHRyKCdjaGlsZF9jb3VudCcpKSArIDFcbiAgICAgICAgICAgIDogY29sbGVjdGlvbkxlbmd0aDtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuYWRkX3RvX2NvbGxlY3Rpb24nKS5hdHRyKCdjaGlsZF9jb3VudCcsIGNvdW50KTtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb25MZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBjb25zdCB0ZyA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmNsb3Nlc3QoJy5mb3JtLWNoaWxkLWJvZHknKTtcbiAgICAgICAgICAgIHRnLm5leHQoJy5lcnJvcicpLnJlbW92ZSgpO1xuICAgICAgICAgICAgdGcucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gZGVsZXRlcyBwYXJlbnQgY29sbGVjdGlvblxuICAgIGRlbGV0ZVBhcmVudEZvcm0oZXYpIHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXYudGFyZ2V0O1xuICAgICAgICBjb25zdCBjb2xsZWN0aW9uTGVuZ3RoID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuc3ViZWxlbWVudCcpLmxlbmd0aDtcbiAgICAgICAgY29uc3QgY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5hZGRfdG9fcGFyZW50JykuYXR0cignY2hpbGRfY291bnQnKVxuICAgICAgICAgICAgPyBwYXJzZUludCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5hZGRfdG9fcGFyZW50JykuYXR0cignY2hpbGRfY291bnQnKSkgKyAxXG4gICAgICAgICAgICA6IGNvbGxlY3Rpb25MZW5ndGg7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmFkZF90b19wYXJlbnQnKS5hdHRyKCdjaGlsZF9jb3VudCcsIGNvdW50KTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuYWRkX3RvX3BhcmVudCcpLmF0dHIoJ3BhcmVudF9jb3VudCcsIGNvdW50KTtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb25MZW5ndGggPiAyKSB7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5wYXJlbnQoKS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvL2FkZCB3cmFwcGVyIGRpdiBhcm91bmQgdGhlIGF0dHJpYnV0ZXNcbiAgICBhZGRXcmFwcGVyKCkge1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5tdWx0aS1mb3JtJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgnLmF0dHJpYnV0ZScpXG4gICAgICAgICAgICAgICAgLndyYXBBbGwoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCc8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1ncm91cCBmbGV4IGZsZXgtd3JhcCBhdHRyaWJ1dGUtd3JhcHBlciBtYi00XCI+PC9kaXY+JykpO1xuICAgICAgICB9KTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuc3ViZWxlbWVudCcpXG4gICAgICAgICAgICAuZmluZCgnLndyYXBwZWQtY2hpbGQtYm9keScpXG4gICAgICAgICAgICAuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgnLnN1Yi1hdHRyaWJ1dGUnKVxuICAgICAgICAgICAgICAgIC53cmFwQWxsKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtZ3JvdXAgZmxleCBmbGV4LXdyYXAgc3ViLWF0dHJpYnV0ZS13cmFwcGVyIG1iLTRcIj48L2Rpdj4nKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBmb3JtRmllbGQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2Zvcm0+LmZvcm0tZmllbGQnKTtcbiAgICAgICAgaWYgKGZvcm1GaWVsZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBmb3JtRmllbGQud3JhcEFsbCgnPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtZ3JvdXAtb3V0ZXIgZ3JpZCB4bDpncmlkLWNvbHMtMiBtYi02IC1teC0zIGdhcC15LTZcIj48L2Rpdj4nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRXcmFwcGVyT25BZGQodGFyZ2V0KSB7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpXG4gICAgICAgICAgICAucHJldigpXG4gICAgICAgICAgICAuZmluZCgnLm11bHRpLWZvcm0nKVxuICAgICAgICAgICAgLmxhc3QoKVxuICAgICAgICAgICAgLmZpbmQoJy5hdHRyaWJ1dGUnKVxuICAgICAgICAgICAgLndyYXBBbGwoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCc8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1ncm91cCBncmlkIHhsOmdyaWQtY29scy0yIGF0dHJpYnV0ZS13cmFwcGVyIG1iLTRcIj48L2Rpdj4nKSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpXG4gICAgICAgICAgICAucHJldigpXG4gICAgICAgICAgICAuZmluZCgnLm11bHRpLWZvcm0nKVxuICAgICAgICAgICAgLmxhc3QoKVxuICAgICAgICAgICAgLmZpbmQoJy5zdWJlbGVtZW50JylcbiAgICAgICAgICAgIC5maW5kKCcud3JhcHBlZC1jaGlsZC1ib2R5JylcbiAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCcuc3ViLWF0dHJpYnV0ZScpXG4gICAgICAgICAgICAgICAgLndyYXBBbGwoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCc8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1ncm91cCBmbGV4IGZsZXgtd3JhcCBzdWItYXR0cmlidXRlLXdyYXBwZXIgbWItNFwiPjwvZGl2PicpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHRleHRBcmVhSGVpZ2h0KGV2KSB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGV2LnRhcmdldDtcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gdGFyZ2V0LnNjcm9sbEhlaWdodDtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkuY3NzKCdoZWlnaHQnLCBoZWlnaHQpO1xuICAgIH1cbiAgICBhZGRUb0NvbGxlY3Rpb24oKSB7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdjbGljaycsICcuYWRkX3RvX2NvbGxlY3Rpb24nLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoZXZlbnQudGFyZ2V0KS5oYXNDbGFzcygnYWRkLWljb24nKSkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KShldmVudC50YXJnZXQpXG4gICAgICAgICAgICAgICAgICAgIC5wYXJlbnQoJ2J1dHRvbicpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjbGljaycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRGb3JtKGV2ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZURlbGV0ZVBhcmVudEJ1dHRvbnMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmFkZF90b19wYXJlbnQnKS5vbignY2xpY2snLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoZXZlbnQudGFyZ2V0KS5oYXNDbGFzcygnYWRkLWljb24nKSkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KShldmVudC50YXJnZXQpXG4gICAgICAgICAgICAgICAgICAgIC5wYXJlbnQoJ2J1dHRvbicpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjbGljaycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRQYXJlbnRGb3JtKGV2ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZURlbGV0ZVBhcmVudEJ1dHRvbnMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRlbGV0ZUNvbGxlY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IGRlbGV0ZUNvbmZpcm1hdGlvbiA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmRlbGV0ZS1jb25maXJtYXRpb24nKSwgY2FuY2VsUG9wdXAgPSAnLmNhbmNlbC1wb3B1cCcsIGRlbGV0ZUNvbmZpcm0gPSAnLmRlbGV0ZS1jb25maXJtJztcbiAgICAgICAgbGV0IGRlbGV0ZUluZGV4ID0ge30sIGNoaWxkT3JQYXJlbnQgPSAnJztcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ2NsaWNrJywgJy5kZWxldGUnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGRlbGV0ZUNvbmZpcm1hdGlvbi5mYWRlSW4oKTtcbiAgICAgICAgICAgIGRlbGV0ZUluZGV4ID0gZXZlbnQ7XG4gICAgICAgICAgICBjaGlsZE9yUGFyZW50ID0gJ2NoaWxkJztcbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdjbGljaycsIGNhbmNlbFBvcHVwLCAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGVDb25maXJtYXRpb24uZmFkZU91dCgpO1xuICAgICAgICAgICAgZGVsZXRlSW5kZXggPSB7fTtcbiAgICAgICAgICAgIGNoaWxkT3JQYXJlbnQgPSAnJztcbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdjbGljaycsIGRlbGV0ZUNvbmZpcm0sICgpID0+IHtcbiAgICAgICAgICAgIGlmIChjaGlsZE9yUGFyZW50ID09PSAnY2hpbGQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVGb3JtKGRlbGV0ZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkT3JQYXJlbnQgPT09ICdwYXJlbnQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVQYXJlbnRGb3JtKGRlbGV0ZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZUNvbmZpcm1hdGlvbi5mYWRlT3V0KCk7XG4gICAgICAgICAgICBkZWxldGVJbmRleCA9IHt9O1xuICAgICAgICAgICAgY2hpbGRPclBhcmVudCA9ICcnO1xuICAgICAgICB9KTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ21vdXNlZW50ZXInLCAnLmRlbGV0ZS1wYXJlbnQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnRcbiAgICAgICAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc3QgZGVsZXRlQnV0dG9uID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGV2ZW50LnRhcmdldCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4gICAgICAgICAgICAvL0B0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IG11bHRpRm9ybSA9IGRlbGV0ZUJ1dHRvbi5jbG9zZXN0KCcubXVsdGktZm9ybSwgLndyYXBwZWQtY2hpbGQtYm9keScpO1xuICAgICAgICAgICAgbXVsdGlGb3JtLmNzcyh7XG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJyNGRkY4RjcnLFxuICAgICAgICAgICAgICAgIG91dGxpbmU6ICcycHggc29saWQgI0YxOUJBMCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdtb3VzZWxlYXZlJywgJy5kZWxldGUtcGFyZW50JywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4gICAgICAgICAgICAvL0B0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IGRlbGV0ZUJ1dHRvbiA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KShldmVudC50YXJnZXQpO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudFxuICAgICAgICAgICAgLy9AdHMtaWdub3JlXG4gICAgICAgICAgICBjb25zdCBtdWx0aUZvcm0gPSBkZWxldGVCdXR0b24uY2xvc2VzdCgnLm11bHRpLWZvcm0sIC53cmFwcGVkLWNoaWxkLWJvZHknKTtcbiAgICAgICAgICAgIG11bHRpRm9ybS5jc3Moe1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICcnLFxuICAgICAgICAgICAgICAgIG91dGxpbmU6ICcnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2JvZHknKS5vbignY2xpY2snLCAnLmRlbGV0ZS1wYXJlbnQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGRlbGV0ZUNvbmZpcm1hdGlvbi5mYWRlSW4oKTtcbiAgICAgICAgICAgIGRlbGV0ZUluZGV4ID0gZXZlbnQ7XG4gICAgICAgICAgICBjaGlsZE9yUGFyZW50ID0gJ3BhcmVudCc7XG4gICAgICAgIH0pO1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5zZWxlY3QyJykuc2VsZWN0Mih7XG4gICAgICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBhbiBvcHRpb24nLFxuICAgICAgICAgICAgYWxsb3dDbGVhcjogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHVwZGF0ZSBmb3JtYXQgb24gY2hhbmdlIG9mIGRvY3VtZW50IGxpbmtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ2NoYW5nZScsICdpbnB1dFtpZCo9XCJbdXJsXVwiXScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gKChfYSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJycpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBjb25zdCBkb2N1bWVudCA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgLmZpbmQoJ2lucHV0W2lkKj1cIltkb2N1bWVudF1cIl0nKVxuICAgICAgICAgICAgICAgIC52YWwoKTtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IGAvbWltZXR5cGU/dXJsPSR7ZmlsZVBhdGh9JnR5cGU9dXJsYDtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS5jbG9zZXN0KCcuZm9ybS1maWVsZCcpLmZpbmQoJy50ZXh0LWRhbmdlcicpLnJlbW92ZSgpO1xuICAgICAgICAgICAgaWYgKGZpbGVQYXRoICE9PSAnJykge1xuICAgICAgICAgICAgICAgIGF4aW9zXzEuZGVmYXVsdC5nZXQodXJsKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXQgPSByZXNwb25zZS5kYXRhLmRhdGEubWltZXR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maW5kKCdzZWxlY3RbaWQqPVwiW2Zvcm1hdF1cIl0nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWwoZm9ybWF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS5jbG9zZXN0KCcuZm9ybS1maWVsZCcpLmZpbmQoJy50ZXh0LWRhbmdlcicpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKFwiPGRpdiBjbGFzcz0ndGV4dC1kYW5nZXIgZXJyb3InPlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5kYXRhLm1lc3NhZ2UgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ3NlbGVjdFtpZCo9XCJbZm9ybWF0XVwiXScpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ2lucHV0W2lkKj1cIltkb2N1bWVudF1cIl0nKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFkb2N1bWVudCB8fCBkb2N1bWVudCA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ3NlbGVjdFtpZCo9XCJbZm9ybWF0XVwiXScpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdjaGFuZ2UnLCAnaW5wdXRbaWQqPVwiW2RvY3VtZW50XVwiXScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gKChfYSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJycpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBgL21pbWV0eXBlP3VybD0ke2ZpbGVQYXRofSYmdHlwZT1kb2N1bWVudGA7XG4gICAgICAgICAgICBjb25zdCBmaWxlVXJsID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpXG4gICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAuZmluZCgnaW5wdXRbaWQqPVwiW3VybF1cIl0nKVxuICAgICAgICAgICAgICAgIC52YWwoKTtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS5jbG9zZXN0KCcuZm9ybS1maWVsZCcpLmZpbmQoJy50ZXh0LWRhbmdlcicpLnJlbW92ZSgpO1xuICAgICAgICAgICAgaWYgKGZpbGVQYXRoICE9PSAnJykge1xuICAgICAgICAgICAgICAgIGF4aW9zXzEuZGVmYXVsdC5nZXQodXJsKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXQgPSByZXNwb25zZS5kYXRhLmRhdGEubWltZXR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maW5kKCdzZWxlY3RbaWQqPVwiW2Zvcm1hdF1cIl0nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWwoZm9ybWF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ3NlbGVjdFtpZCo9XCJbZm9ybWF0XVwiXScpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ2lucHV0W2lkKj1cIlt1cmxdXCJdJylcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWZpbGVVcmwgfHwgZmlsZVVybCA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ3NlbGVjdFtpZCo9XCJbZm9ybWF0XVwiXScpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGhhbmRsZURlbGV0ZVBhcmVudEJ1dHRvbnMoKSB7XG4gICAgICAgIGNvbnN0IGRlbGV0ZUJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZGVsZXRlLXBhcmVudC1zZWxlY3RvcicpO1xuICAgICAgICBjb25zdCBjaGFuZ2VEZWxldGVCdXR0b25Jbm5lckh0bWwgPSAoYnV0dG9uKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbml0aWFsVGV4dCA9IGVzY2FwZUh0bWwoYnV0dG9uLnRleHRDb250ZW50KTtcbiAgICAgICAgICAgIGJ1dHRvbi5pbm5lckhUTUwgPSBgXG4gICAgICAgICA8c3ZnIGNsYXNzPVwidGV4dC1bMXJlbV0gbWItMC41XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICAgICA8cGF0aCBkPVwiTTYuNjY2NjcgMTJDNi44NDM0OCAxMiA3LjAxMzA1IDExLjkyOTggNy4xMzgwNyAxMS44MDQ3QzcuMjYzMSAxMS42Nzk3IDcuMzMzMzMgMTEuNTEwMSA3LjMzMzMzIDExLjMzMzNWNy4zMzMzNEM3LjMzMzMzIDcuMTU2NTMgNy4yNjMxIDYuOTg2OTYgNy4xMzgwNyA2Ljg2MTkzQzcuMDEzMDUgNi43MzY5MSA2Ljg0MzQ4IDYuNjY2NjcgNi42NjY2NyA2LjY2NjY3QzYuNDg5ODYgNi42NjY2NyA2LjMyMDI5IDYuNzM2OTEgNi4xOTUyNiA2Ljg2MTkzQzYuMDcwMjQgNi45ODY5NiA2IDcuMTU2NTMgNiA3LjMzMzM0VjExLjMzMzNDNiAxMS41MTAxIDYuMDcwMjQgMTEuNjc5NyA2LjE5NTI2IDExLjgwNDdDNi4zMjAyOSAxMS45Mjk4IDYuNDg5ODYgMTIgNi42NjY2NyAxMlpNMTMuMzMzMyA0SDEwLjY2NjdWMy4zMzMzNEMxMC42NjY3IDIuODAyOSAxMC40NTYgMi4yOTQyIDEwLjA4MDkgMS45MTkxMkM5LjcwNTgxIDEuNTQ0MDUgOS4xOTcxIDEuMzMzMzQgOC42NjY2NyAxLjMzMzM0SDcuMzMzMzNDNi44MDI5IDEuMzMzMzQgNi4yOTQxOSAxLjU0NDA1IDUuOTE5MTIgMS45MTkxMkM1LjU0NDA1IDIuMjk0MiA1LjMzMzMzIDIuODAyOSA1LjMzMzMzIDMuMzMzMzRWNEgyLjY2NjY3QzIuNDg5ODYgNCAyLjMyMDI5IDQuMDcwMjQgMi4xOTUyNiA0LjE5NTI2QzIuMDcwMjQgNC4zMjAyOSAyIDQuNDg5ODYgMiA0LjY2NjY3QzIgNC44NDM0OCAyLjA3MDI0IDUuMDEzMDUgMi4xOTUyNiA1LjEzODA3QzIuMzIwMjkgNS4yNjMxIDIuNDg5ODYgNS4zMzMzNCAyLjY2NjY3IDUuMzMzMzRIMy4zMzMzM1YxMi42NjY3QzMuMzMzMzMgMTMuMTk3MSAzLjU0NDA1IDEzLjcwNTggMy45MTkxMiAxNC4wODA5QzQuMjk0MTkgMTQuNDU2IDQuODAyOSAxNC42NjY3IDUuMzMzMzMgMTQuNjY2N0gxMC42NjY3QzExLjE5NzEgMTQuNjY2NyAxMS43MDU4IDE0LjQ1NiAxMi4wODA5IDE0LjA4MDlDMTIuNDU2IDEzLjcwNTggMTIuNjY2NyAxMy4xOTcxIDEyLjY2NjcgMTIuNjY2N1Y1LjMzMzM0SDEzLjMzMzNDMTMuNTEwMSA1LjMzMzM0IDEzLjY3OTcgNS4yNjMxIDEzLjgwNDcgNS4xMzgwN0MxMy45Mjk4IDUuMDEzMDUgMTQgNC44NDM0OCAxNCA0LjY2NjY3QzE0IDQuNDg5ODYgMTMuOTI5OCA0LjMyMDI5IDEzLjgwNDcgNC4xOTUyNkMxMy42Nzk3IDQuMDcwMjQgMTMuNTEwMSA0IDEzLjMzMzMgNFpNNi42NjY2NyAzLjMzMzM0QzYuNjY2NjcgMy4xNTY1MiA2LjczNjkgMi45ODY5NiA2Ljg2MTkzIDIuODYxOTNDNi45ODY5NSAyLjczNjkxIDcuMTU2NTIgMi42NjY2NyA3LjMzMzMzIDIuNjY2NjdIOC42NjY2N0M4Ljg0MzQ4IDIuNjY2NjcgOS4wMTMwNSAyLjczNjkxIDkuMTM4MDcgMi44NjE5M0M5LjI2MzEgMi45ODY5NiA5LjMzMzMzIDMuMTU2NTIgOS4zMzMzMyAzLjMzMzM0VjRINi42NjY2N1YzLjMzMzM0Wk0xMS4zMzMzIDEyLjY2NjdDMTEuMzMzMyAxMi44NDM1IDExLjI2MzEgMTMuMDEzMSAxMS4xMzgxIDEzLjEzODFDMTEuMDEzIDEzLjI2MzEgMTAuODQzNSAxMy4zMzMzIDEwLjY2NjcgMTMuMzMzM0g1LjMzMzMzQzUuMTU2NTIgMTMuMzMzMyA0Ljk4Njk1IDEzLjI2MzEgNC44NjE5MyAxMy4xMzgxQzQuNzM2OSAxMy4wMTMxIDQuNjY2NjcgMTIuODQzNSA0LjY2NjY3IDEyLjY2NjdWNS4zMzMzNEgxMS4zMzMzVjEyLjY2NjdaTTkuMzMzMzMgMTJDOS41MTAxNCAxMiA5LjY3OTcxIDExLjkyOTggOS44MDQ3NCAxMS44MDQ3QzkuOTI5NzYgMTEuNjc5NyAxMCAxMS41MTAxIDEwIDExLjMzMzNWNy4zMzMzNEMxMCA3LjE1NjUzIDkuOTI5NzYgNi45ODY5NiA5LjgwNDc0IDYuODYxOTNDOS42Nzk3MSA2LjczNjkxIDkuNTEwMTQgNi42NjY2NyA5LjMzMzMzIDYuNjY2NjdDOS4xNTY1MiA2LjY2NjY3IDguOTg2OTUgNi43MzY5MSA4Ljg2MTkzIDYuODYxOTNDOC43MzY5MSA2Ljk4Njk2IDguNjY2NjcgNy4xNTY1MyA4LjY2NjY3IDcuMzMzMzRWMTEuMzMzM0M4LjY2NjY3IDExLjUxMDEgOC43MzY5MSAxMS42Nzk3IDguODYxOTMgMTEuODA0N0M4Ljk4Njk1IDExLjkyOTggOS4xNTY1MiAxMiA5LjMzMzMzIDEyWlwiIGZpbGw9XCIjRTM0RDVCXCIvPlxuICAgICAgICAgPC9zdmc+XG4gICAgICAgICAke2luaXRpYWxUZXh0fVxuICAgICAgYDtcbiAgICAgICAgfTtcbiAgICAgICAgZGVsZXRlQnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgICAgICAgIGNoYW5nZURlbGV0ZUJ1dHRvbklubmVySHRtbChidXR0b24pO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4oMCwganF1ZXJ5XzEuZGVmYXVsdCkoZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGZvcm1CdWlsZGVyID0gbmV3IEZvcm1CdWlsZGVyKCk7XG4gICAgZm9ybUJ1aWxkZXIuYWRkV3JhcHBlcigpO1xuICAgIGR5bmFtaWNGaWVsZC5oaWRlU2hvd0Zvcm1GaWVsZHMoKTtcbiAgICBkeW5hbWljRmllbGQudXBkYXRlQWN0aXZpdHlJZGVudGlmaWVyKCk7XG4gICAgZm9ybUJ1aWxkZXIuYWRkVG9Db2xsZWN0aW9uKCk7XG4gICAgZm9ybUJ1aWxkZXIuZGVsZXRlQ29sbGVjdGlvbigpO1xuICAgIC8qKlxuICAgICAqIFRleHQgYXJlYSBoZWlnaHQgb24gdHlwaW5nXG4gICAgICovXG4gICAgY29uc3QgdGV4dEFyZWFUYXJnZXQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3RleHRhcmVhLmZvcm1fX2lucHV0Jyk7XG4gICAgaWYgKHRleHRBcmVhVGFyZ2V0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ2lucHV0JywgJ3RleHRhcmVhLmZvcm1fX2lucHV0JywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBmb3JtQnVpbGRlci50ZXh0QXJlYUhlaWdodChldmVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2JvZHknKS5vbignc2VsZWN0MjpvcGVuJywgJy5zZWxlY3QyJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBzZWxlY3Rfc2VhcmNoID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjdDItc2VhcmNoX19maWVsZCcpO1xuICAgICAgICBpZiAoc2VsZWN0X3NlYXJjaCkge1xuICAgICAgICAgICAgc2VsZWN0X3NlYXJjaC5mb2N1cygpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgLyoqXG4gICAgICogY2hlY2tzIHJlZ2lzdHJhdGlvbiBhZ2VuY3ksIGNvdW50cnkgYW5kIHJlZ2lzdHJhdGlvbiBudW1iZXIgdG8gZGVkdWNlIGlkZW50aWZpZXJcbiAgICAgKi9cbiAgICB1cGRhdGVSZWdpc3RyYXRpb25BZ2VuY3koKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pemF0aW9uX2NvdW50cnknKSk7XG4gICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pc2F0aW9uX2lkZW50aWZpZXInKS5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpO1xuICAgIGZ1bmN0aW9uIHVwZGF0ZVJlZ2lzdHJhdGlvbkFnZW5jeShjb3VudHJ5KSB7XG4gICAgICAgIGNvbnN0IGVuZHBvaW50ID0gY291bnRyeS52YWwoKVxuICAgICAgICAgICAgPyAnL29yZ2FuaXNhdGlvbi9hZ2VuY3kvJyArIGNvdW50cnkudmFsKClcbiAgICAgICAgICAgIDogJy9vcmdhbmlzYXRpb24vYWdlbmN5Lyc7XG4gICAgICAgIGpxdWVyeV8xLmRlZmF1bHQuYWpheCh7IHVybDogZW5kcG9pbnQgfSkudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRfdmFsID0gKF9hID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pemF0aW9uX3JlZ2lzdHJhdGlvbl9hZ2VuY3knKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJyc7XG4gICAgICAgICAgICBsZXQgdmFsID0gZmFsc2U7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJyNvcmdhbml6YXRpb25fcmVnaXN0cmF0aW9uX2FnZW5jeScpLmVtcHR5KCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGRhdGEgaW4gcmVzcG9uc2UuZGF0YSkge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBjdXJyZW50X3ZhbCkge1xuICAgICAgICAgICAgICAgICAgICB2YWwgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJyNvcmdhbml6YXRpb25fcmVnaXN0cmF0aW9uX2FnZW5jeScpXG4gICAgICAgICAgICAgICAgICAgIC5hcHBlbmQobmV3IE9wdGlvbihyZXNwb25zZS5kYXRhW2RhdGFdLCBkYXRhLCB0cnVlLCB0cnVlKSlcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pemF0aW9uX3JlZ2lzdHJhdGlvbl9hZ2VuY3knKVxuICAgICAgICAgICAgICAgIC52YWwodmFsID8gY3VycmVudF92YWwgOiAnJylcbiAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2JvZHknKS5vbignc2VsZWN0MjpzZWxlY3QnLCAnI29yZ2FuaXphdGlvbl9jb3VudHJ5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICB1cGRhdGVSZWdpc3RyYXRpb25BZ2VuY3koKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpKTtcbiAgICB9KTtcbiAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2JvZHknKS5vbignc2VsZWN0MjpjbGVhcicsICcjb3JnYW5pemF0aW9uX2NvdW50cnknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHVwZGF0ZVJlZ2lzdHJhdGlvbkFnZW5jeSgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcykpO1xuICAgIH0pO1xuICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdzZWxlY3QyOnNlbGVjdCcsICcjb3JnYW5pemF0aW9uX3JlZ2lzdHJhdGlvbl9hZ2VuY3knLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGlkZW50aWZpZXIgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcykudmFsKCkgKyAnLScgKyAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJyNyZWdpc3RyYXRpb25fbnVtYmVyJykudmFsKCk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnI29yZ2FuaXNhdGlvbl9pZGVudGlmaWVyJykudmFsKGlkZW50aWZpZXIpO1xuICAgIH0pO1xuICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdzZWxlY3QyOmNsZWFyJywgJyNvcmdhbml6YXRpb25fcmVnaXN0cmF0aW9uX2FnZW5jeScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaWRlbnRpZmllciA9ICctJyArICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnI3JlZ2lzdHJhdGlvbl9udW1iZXInKS52YWwoKTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pc2F0aW9uX2lkZW50aWZpZXInKS52YWwoaWRlbnRpZmllcik7XG4gICAgfSk7XG4gICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ2tleXVwJywgJyNyZWdpc3RyYXRpb25fbnVtYmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpZGVudGlmaWVyID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pemF0aW9uX3JlZ2lzdHJhdGlvbl9hZ2VuY3knKS52YWwoKSArICctJyArICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS52YWwoKTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pc2F0aW9uX2lkZW50aWZpZXInKS52YWwoaWRlbnRpZmllcik7XG4gICAgfSk7XG4gICAgLy8gYWRkIGNsYXNzIHRvIHRpdGxlIG9mIGNvbGxlY3Rpb24gd2hlbiB2YWxpZGF0aW9uIGVycm9yIG9jY3VycyBvbiBjb2xsZWN0aW9uIGxldmVsXG4gICAgY29uc3Qgc3ViZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zdWJlbGVtZW50Jyk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdWJlbGVtZW50Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHRpdGxlID0gc3ViZWxlbWVudFtpXS5xdWVyeVNlbGVjdG9yKCcuY29udHJvbC1sYWJlbCcpO1xuICAgICAgICBjb25zdCBlcnJvckNvbnRhaW5lciA9IHN1YmVsZW1lbnRbaV0ucXVlcnlTZWxlY3RvcignLmNvbGxlY3Rpb25fZXJyb3InKTtcbiAgICAgICAgY29uc3QgY2hpbGRDb3VudCA9IGVycm9yQ29udGFpbmVyID09PSBudWxsIHx8IGVycm9yQ29udGFpbmVyID09PSB2b2lkIDAgPyB2b2lkIDAgOiBlcnJvckNvbnRhaW5lci5jaGlsZEVsZW1lbnRDb3VudDtcbiAgICAgICAgaWYgKGNoaWxkQ291bnQgJiYgY2hpbGRDb3VudCA+IDApIHtcbiAgICAgICAgICAgIHRpdGxlID09PSBudWxsIHx8IHRpdGxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiB0aXRsZS5jbGFzc0xpc3QuYWRkKCdlcnJvci10aXRsZScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEFkZGluZyBjdXJzb3Igbm90IGFsbG93ZWQgdG8gPHNlbGVjdD4gd2hlcmUgZWxlbWVudEpzb25TY2hlbWEgcmVhZF9vbmx5IDogdHJ1ZVxuICAgIGNvbnN0IHJlYWRPbmx5U2VsZWN0cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3NlbGVjdC5jdXJzb3Itbm90LWFsbG93ZWQnKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlYWRPbmx5U2VsZWN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBzZWxlY3QgPSByZWFkT25seVNlbGVjdHNbaV07XG4gICAgICAgIGNvbnN0IHNlbGVjdEVsZW1lbnRQYXJlbnRXcmFwcGVyID0gc2VsZWN0Lm5leHRTaWJsaW5nO1xuICAgICAgICBjb25zdCBzZWxlY3RFbGVtZW50UGFyZW50ID0gc2VsZWN0RWxlbWVudFBhcmVudFdyYXBwZXIgPT09IG51bGwgfHwgc2VsZWN0RWxlbWVudFBhcmVudFdyYXBwZXIgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHNlbGVjdEVsZW1lbnRQYXJlbnRXcmFwcGVyLmZpcnN0Q2hpbGQ7XG4gICAgICAgIGNvbnN0IHNlbGVjdEVsZW1lbnQgPSBzZWxlY3RFbGVtZW50UGFyZW50ID09PSBudWxsIHx8IHNlbGVjdEVsZW1lbnRQYXJlbnQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHNlbGVjdEVsZW1lbnRQYXJlbnQuZmlyc3RDaGlsZDtcbiAgICAgICAgaWYgKHNlbGVjdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gJ25vdC1hbGxvd2VkJztcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBkZWxldGVCdXR0b25zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmRlbGV0ZS1wYXJlbnQtc2VsZWN0b3InKTtcbiAgICBmdW5jdGlvbiBjaGFuZ2VEZWxldGVCdXR0b25Jbm5lckh0bWwoYnV0dG9uKSB7XG4gICAgICAgIGNvbnN0IGluaXRpYWxUZXh0ID0gZXNjYXBlSHRtbChidXR0b24udGV4dENvbnRlbnQpO1xuICAgICAgICBidXR0b24uaW5uZXJIVE1MID0gYFxuICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgIDxwYXRoIGQ9XCJNNi42NjY2NyAxMkM2Ljg0MzQ4IDEyIDcuMDEzMDUgMTEuOTI5OCA3LjEzODA3IDExLjgwNDdDNy4yNjMxIDExLjY3OTcgNy4zMzMzMyAxMS41MTAxIDcuMzMzMzMgMTEuMzMzM1Y3LjMzMzM0QzcuMzMzMzMgNy4xNTY1MyA3LjI2MzEgNi45ODY5NiA3LjEzODA3IDYuODYxOTNDNy4wMTMwNSA2LjczNjkxIDYuODQzNDggNi42NjY2NyA2LjY2NjY3IDYuNjY2NjdDNi40ODk4NiA2LjY2NjY3IDYuMzIwMjkgNi43MzY5MSA2LjE5NTI2IDYuODYxOTNDNi4wNzAyNCA2Ljk4Njk2IDYgNy4xNTY1MyA2IDcuMzMzMzRWMTEuMzMzM0M2IDExLjUxMDEgNi4wNzAyNCAxMS42Nzk3IDYuMTk1MjYgMTEuODA0N0M2LjMyMDI5IDExLjkyOTggNi40ODk4NiAxMiA2LjY2NjY3IDEyWk0xMy4zMzMzIDRIMTAuNjY2N1YzLjMzMzM0QzEwLjY2NjcgMi44MDI5IDEwLjQ1NiAyLjI5NDIgMTAuMDgwOSAxLjkxOTEyQzkuNzA1ODEgMS41NDQwNSA5LjE5NzEgMS4zMzMzNCA4LjY2NjY3IDEuMzMzMzRINy4zMzMzM0M2LjgwMjkgMS4zMzMzNCA2LjI5NDE5IDEuNTQ0MDUgNS45MTkxMiAxLjkxOTEyQzUuNTQ0MDUgMi4yOTQyIDUuMzMzMzMgMi44MDI5IDUuMzMzMzMgMy4zMzMzNFY0SDIuNjY2NjdDMi40ODk4NiA0IDIuMzIwMjkgNC4wNzAyNCAyLjE5NTI2IDQuMTk1MjZDMi4wNzAyNCA0LjMyMDI5IDIgNC40ODk4NiAyIDQuNjY2NjdDMiA0Ljg0MzQ4IDIuMDcwMjQgNS4wMTMwNSAyLjE5NTI2IDUuMTM4MDdDMi4zMjAyOSA1LjI2MzEgMi40ODk4NiA1LjMzMzM0IDIuNjY2NjcgNS4zMzMzNEgzLjMzMzMzVjEyLjY2NjdDMy4zMzMzMyAxMy4xOTcxIDMuNTQ0MDUgMTMuNzA1OCAzLjkxOTEyIDE0LjA4MDlDNC4yOTQxOSAxNC40NTYgNC44MDI5IDE0LjY2NjcgNS4zMzMzMyAxNC42NjY3SDEwLjY2NjdDMTEuMTk3MSAxNC42NjY3IDExLjcwNTggMTQuNDU2IDEyLjA4MDkgMTQuMDgwOUMxMi40NTYgMTMuNzA1OCAxMi42NjY3IDEzLjE5NzEgMTIuNjY2NyAxMi42NjY3VjUuMzMzMzRIMTMuMzMzM0MxMy41MTAxIDUuMzMzMzQgMTMuNjc5NyA1LjI2MzEgMTMuODA0NyA1LjEzODA3QzEzLjkyOTggNS4wMTMwNSAxNCA0Ljg0MzQ4IDE0IDQuNjY2NjdDMTQgNC40ODk4NiAxMy45Mjk4IDQuMzIwMjkgMTMuODA0NyA0LjE5NTI2QzEzLjY3OTcgNC4wNzAyNCAxMy41MTAxIDQgMTMuMzMzMyA0Wk02LjY2NjY3IDMuMzMzMzRDNi42NjY2NyAzLjE1NjUyIDYuNzM2OSAyLjk4Njk2IDYuODYxOTMgMi44NjE5M0M2Ljk4Njk1IDIuNzM2OTEgNy4xNTY1MiAyLjY2NjY3IDcuMzMzMzMgMi42NjY2N0g4LjY2NjY3QzguODQzNDggMi42NjY2NyA5LjAxMzA1IDIuNzM2OTEgOS4xMzgwNyAyLjg2MTkzQzkuMjYzMSAyLjk4Njk2IDkuMzMzMzMgMy4xNTY1MiA5LjMzMzMzIDMuMzMzMzRWNEg2LjY2NjY3VjMuMzMzMzRaTTExLjMzMzMgMTIuNjY2N0MxMS4zMzMzIDEyLjg0MzUgMTEuMjYzMSAxMy4wMTMxIDExLjEzODEgMTMuMTM4MUMxMS4wMTMgMTMuMjYzMSAxMC44NDM1IDEzLjMzMzMgMTAuNjY2NyAxMy4zMzMzSDUuMzMzMzNDNS4xNTY1MiAxMy4zMzMzIDQuOTg2OTUgMTMuMjYzMSA0Ljg2MTkzIDEzLjEzODFDNC43MzY5IDEzLjAxMzEgNC42NjY2NyAxMi44NDM1IDQuNjY2NjcgMTIuNjY2N1Y1LjMzMzM0SDExLjMzMzNWMTIuNjY2N1pNOS4zMzMzMyAxMkM5LjUxMDE0IDEyIDkuNjc5NzEgMTEuOTI5OCA5LjgwNDc0IDExLjgwNDdDOS45Mjk3NiAxMS42Nzk3IDEwIDExLjUxMDEgMTAgMTEuMzMzM1Y3LjMzMzM0QzEwIDcuMTU2NTMgOS45Mjk3NiA2Ljk4Njk2IDkuODA0NzQgNi44NjE5M0M5LjY3OTcxIDYuNzM2OTEgOS41MTAxNCA2LjY2NjY3IDkuMzMzMzMgNi42NjY2N0M5LjE1NjUyIDYuNjY2NjcgOC45ODY5NSA2LjczNjkxIDguODYxOTMgNi44NjE5M0M4LjczNjkxIDYuOTg2OTYgOC42NjY2NyA3LjE1NjUzIDguNjY2NjcgNy4zMzMzNFYxMS4zMzMzQzguNjY2NjcgMTEuNTEwMSA4LjczNjkxIDExLjY3OTcgOC44NjE5MyAxMS44MDQ3QzguOTg2OTUgMTEuOTI5OCA5LjE1NjUyIDEyIDkuMzMzMzMgMTJaXCIgZmlsbD1cIiNFMzRENUJcIi8+XG4gICAgICA8L3N2Zz5cbiAgICAgICR7aW5pdGlhbFRleHR9YDtcbiAgICB9XG4gICAgZGVsZXRlQnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IGNoYW5nZURlbGV0ZUJ1dHRvbklubmVySHRtbChidXR0b24pKTtcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnNMaXN0KSA9PiB7XG4gICAgICAgIG11dGF0aW9uc0xpc3QuZm9yRWFjaCgobXV0YXRpb24pID0+IHtcbiAgICAgICAgICAgIGlmIChtdXRhdGlvbi5hZGRlZE5vZGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBtdXRhdGlvbi5hZGRlZE5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS5tYXRjaGVzKCcuZGVsZXRlLWl0ZW0tc2VsZWN0b3InKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZURlbGV0ZUJ1dHRvbklubmVySHRtbChub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0RlbGV0ZUJ1dHRvbnMgPSBub2RlLnF1ZXJ5U2VsZWN0b3JBbGwoJy5kZWxldGUtaXRlbS1zZWxlY3RvcicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RlbGV0ZUJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiBjaGFuZ2VEZWxldGVCdXR0b25Jbm5lckh0bWwoYnV0dG9uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudC5ib2R5LCB7XG4gICAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICAgICAgc3VidHJlZTogdHJ1ZSxcbiAgICB9KTtcbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGRvZXMgdHdvIG1haW4gdGhpbmdzOlxuICAgICAqXG4gICAgICogMS4gQWRkcyBhIGNsaWNrIGV2ZW50IGxpc3RlbmVyIHRvIHRoZSBidXR0b24gdG8gY29udHJvbCB0aGUgY29sbGFwc2libGUgZmxvdzpcbiAgICAgKiAgICAtIEl0IGZpbmRzIHRoZSBjbG9zZXN0IDxsYWJlbD4gZWxlbWVudCByZWxhdGVkIHRvIHRoZSBidXR0b24uXG4gICAgICogICAgLSBXaXRoaW4gdGhhdCA8bGFiZWw+LCBpdCBsb29rcyBmb3IgYW4gZWxlbWVudCB3aXRoIHRoZSBjbGFzcyAnb3B0aW9uYWwtdGV4dCcuIElmIGl0IGZpbmRzICdvcHRpb25hbC10ZXh0JywgaXQgdG9nZ2xlcyBob3cgdGhhdCB0ZXh0IGlzIGRpc3BsYXllZCAoZWl0aGVyIHdpdGggYnJhY2tldHMgb3IgYW4gaWNvbikuXG4gICAgICogICAgLSBJdCBhbHNvIGxvY2F0ZXMgdGhlIG5lYXJlc3QgcGFyZW50IGVsZW1lbnQgd2l0aCB0aGUgY2xhc3NlcyAnc3ViZWxlbWVudCByb3VuZGVkLXQtc20nLiBJZiB0aGF0IHBhcmVudCBzdWJlbGVtZW50IGV4aXN0cywgaXQgdG9nZ2xlcyBpdHMgc3RhdGUgdG8gZWl0aGVyIGNvbGxhcHNlIG9yIGV4cGFuZCB0aGUgZm9ybSBzZWN0aW9uLlxuICAgICAqICAgIC0gRmluYWxseSwgaXQgcm90YXRlcyB0aGUgY29sbGFwc2UgYnV0dG9uIGVhY2ggdGltZSBpdOKAmXMgY2xpY2tlZC5cbiAgICAgKlxuICAgICAqIDIuIEl0IHRyaWdnZXJzIHRoZSBidXR0b24gY2xpY2sgZXZlbnQgaWYgdGhlIHN1YmVsZW1lbnQgaXMgb3B0aW9uYWwgdXNpbmcgdGhlIGZsYWc6IHRoaXNCdXR0b25CZWxvbmdzVG9PcHRpb25hbEZvcm0uXG4gICAgICogICAgVGhpcyBlbnN1cmVzIG9wdGlvbmFsIGZvcm1zIHN0YXJ0IG9mZiBjb2xsYXBzZWQgYnkgZGVmYXVsdCB3aGVuIHJlbmRlcmVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGJ1dHRvbiAtIFRoZSBidXR0b24gZWxlbWVudCB0aGF0IG1hbmFnZXMgdGhlIGNvbGxhcHNpYmxlIGZvcm0gc2VjdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhdHRhY2hDb2xsYXBzYWJsZUJ1dHRvbkV2ZW50cyhidXR0b24pIHtcbiAgICAgICAgY29uc3QgbGFiZWwgPSBnZXRDbG9zZXN0TGFiZWxEb20oYnV0dG9uKTtcbiAgICAgICAgY29uc3Qgb3B0aW9uYWxMYWJlbCA9IGxhYmVsID8gZ2V0T3B0aW9uYWxUZXh0RG9tKGxhYmVsKSA6IG51bGw7XG4gICAgICAgIGNvbnN0IHN1YmVsZW1lbnQgPSBsYWJlbCA/IGdldENsb3Nlc3RQYXJlbnRTdWJlbGVtZW50RG9tKGxhYmVsKSA6IG51bGw7XG4gICAgICAgIGNvbnN0IHRoaXNCdXR0b25CZWxvbmdzVG9PcHRpb25hbEZvcm0gPSBvcHRpb25hbExhYmVsICE9PSBudWxsO1xuICAgICAgICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAob3B0aW9uYWxMYWJlbCkge1xuICAgICAgICAgICAgICAgIHRvZ2dsZU9wdGlvbmFsVGV4dChvcHRpb25hbExhYmVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzdWJlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdG9nZ2xlQWNjb3JkaW9uSXRlbXMoc3ViZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidXR0b24uY2xhc3NMaXN0LnRvZ2dsZSgncm90YXRlLTE4MCcpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXNCdXR0b25CZWxvbmdzVG9PcHRpb25hbEZvcm0gJiYgIWVycm9yTWVzc2FnZUV4aXN0cyhzdWJlbGVtZW50KSkge1xuICAgICAgICAgICAgYnV0dG9uLmNsaWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYW55IGVycm9yIG1lc3NhZ2UgZXhpc3RzIGluIHRoZSBzdWJlbGVtZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIHN1YmVsZW1lbnRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcnJvck1lc3NhZ2VFeGlzdHMoc3ViZWxlbWVudCkge1xuICAgICAgICBjb25zdCBlcnJvckRpdnMgPSBzdWJlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5lcnJvcicpO1xuICAgICAgICBjb25zdCBlcnJvclRleHRzID0gc3ViZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudGV4dC1kYW5nZXItZXJyb3InKTtcbiAgICAgICAgZm9yIChjb25zdCBkaXYgb2YgZXJyb3JEaXZzKSB7XG4gICAgICAgICAgICBpZiAoZGl2LnRleHRDb250ZW50LnRyaW0oKSAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGRpdiBvZiBlcnJvclRleHRzKSB7XG4gICAgICAgICAgICBpZiAoZGl2LnRleHRDb250ZW50LnRyaW0oKSAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgY2xvc2VzdCA8bGFiZWw+IGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYnV0dG9uXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0Q2xvc2VzdExhYmVsRG9tKGJ1dHRvbikge1xuICAgICAgICByZXR1cm4gYnV0dG9uLmNsb3Nlc3QoJ2xhYmVsJyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgY2xvc2VzdCBlbGVtZW50IHdpdGggY2xhc3MgJ29wdGlvbmFsLXRleHQnLlxuICAgICAqXG4gICAgICogQHBhcmFtIGxhYmVsXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0T3B0aW9uYWxUZXh0RG9tKGxhYmVsKSB7XG4gICAgICAgIHJldHVybiBsYWJlbC5xdWVyeVNlbGVjdG9yKCcub3B0aW9uYWwtdGV4dCcpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBmaXJzdCBOdGggcGFyZW50IHRoYXQgaGFzIGNsYXNzICdzdWJlbGVtZW50Jy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBsYWJlbFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldENsb3Nlc3RQYXJlbnRTdWJlbGVtZW50RG9tKGxhYmVsKSB7XG4gICAgICAgIHJldHVybiBsYWJlbC5jbG9zZXN0KCcuc3ViZWxlbWVudC5yb3VuZGVkLXQtc20nKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVG9nZ2xlcyB3aGF0IGlzIHJlbmRlcmVkIG9uIG9wdGlvbmFsIHRleHQuIChkb3Qgb3IgYnJhY2tldClcbiAgICAgKlxuICAgICAqIEBwYXJhbSBvcHRpb25hbExhYmVsXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9nZ2xlT3B0aW9uYWxUZXh0KG9wdGlvbmFsTGFiZWwpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uYWxMYWJlbFdpdGhTdmcgPSAnPHN2ZyB2aWV3Qm94PVwiMCAwIDE2IDE4XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+PHBhdGggZD1cIk02IDlhMS44NyAxLjg3IDAgMSAwIDMuNzQgMEExLjg3IDEuODcgMCAwIDAgNiA5WlwiIGZpbGw9XCIjNjg3OTdFXCI+PC9wYXRoPjwvc3ZnPjxzcGFuPk9wdGlvbmFsPC9zcGFuPic7XG4gICAgICAgIGNvbnN0IG9wdGlvbmFsTGFiZWxXaXRoQnJhY2tldHMgPSAnPHNwYW4+KCBPcHRpb25hbCApPC9zcGFuPic7XG4gICAgICAgIGNvbnN0IHN2Z0V4aXN0cyA9IG9wdGlvbmFsTGFiZWwucXVlcnlTZWxlY3Rvcignc3ZnJykgIT09IG51bGw7XG4gICAgICAgIGlmIChzdmdFeGlzdHMpIHtcbiAgICAgICAgICAgIG9wdGlvbmFsTGFiZWwuaW5uZXJIVE1MID0gb3B0aW9uYWxMYWJlbFdpdGhCcmFja2V0cztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG9wdGlvbmFsTGFiZWwuaW5uZXJIVE1MID0gb3B0aW9uYWxMYWJlbFdpdGhTdmc7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVG9nZ2xlcyBjb2xsYXBzZWQgc3RhdGUuIChleHBhbmQgb3IgY29sbGFwc2VkKVxuICAgICAqXG4gICAgICogS2V5IGNvbnNpZGVyYXRpb25zOlxuICAgICAqIDEuIFRoZSBcIkFkZCBBZGRpdGlvbmFsXCIgYnV0dG9uIGNhbiBiZSBlaXRoZXIgaW5zaWRlIG9yIG91dHNpZGUgdGhlIHN1YmVsZW1lbnQuXG4gICAgICogMi4gV2hlbiB0aGUgYnV0dG9uIGlzIG91dHNpZGUsIGl0IHdpbGwgYWx3YXlzIGJlIHRoZSBpbW1lZGlhdGUgc2libGluZyB0byB0aGUgc3ViZWxlbWVudC5cbiAgICAgKiAzLiBUaGUgY29sbGFwc2UgbWVjaGFuaXNtIGlzIGhhbmRsZWQgYnkgYWRqdXN0aW5nIHRoZSBtYXggaGVpZ2h0IHRvIGdpdmUgdGhlIGlsbHVzaW9uIG9mIHNsaWRpbmcgdXAuXG4gICAgICogNC4gSWYgdGhlIGJ1dHRvbiBpcyBvdXRzaWRlIHRoZSBzdWJlbGVtZW50LCB0aGUgc2xpZGUtdXAgZWZmZWN0IHdpbGwgbm90IGFmZmVjdCB0aGUgYnV0dG9uLlxuICAgICAqICAgIFRoZXJlZm9yZSwgd2UgdG9nZ2xlIHRoZSAnZGlzcGxheS1ub25lJyBjbGFzcyB0byBjb250cm9sIGl0cyB2aXNpYmlsaXR5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHN1YmVsZW1lbnRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b2dnbGVBY2NvcmRpb25JdGVtcyhzdWJlbGVtZW50KSB7XG4gICAgICAgIGZ1bmN0aW9uIGlzQWRkQWRkaXRpb25hbEJ1dHRvbk91dHNpZGUoc3ViZWxlbWVudCkge1xuICAgICAgICAgICAgY29uc3QgbmV4dFNpYmxpbmcgPSBzdWJlbGVtZW50Lm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgICAgIGlmIChuZXh0U2libGluZyAmJiBuZXh0U2libGluZy50YWdOYW1lID09PSAnQlVUVE9OJykge1xuICAgICAgICAgICAgICAgIHJldHVybiAobmV4dFNpYmxpbmcuY2xhc3NMaXN0LmNvbnRhaW5zKCdhZGRfbW9yZScpICYmXG4gICAgICAgICAgICAgICAgICAgIG5leHRTaWJsaW5nLmNsYXNzTGlzdC5jb250YWlucygnYnV0dG9uJykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhpZGVhYmxlU3ViZWxlbWVudHMgPSBbLi4uc3ViZWxlbWVudC5jaGlsZHJlbl0uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudGFnTmFtZSAhPT0gJ0xBQkVMJyk7XG4gICAgICAgIGxldCBvdXRzaWRlQnV0dG9uID0gbnVsbDtcbiAgICAgICAgY29uc3QgaGFzQWRkQWRkaXRpb25hbEJ1dHRvbk91dHNpZGUgPSBpc0FkZEFkZGl0aW9uYWxCdXR0b25PdXRzaWRlKHN1YmVsZW1lbnQpO1xuICAgICAgICBpZiAoaGFzQWRkQWRkaXRpb25hbEJ1dHRvbk91dHNpZGUpIHtcbiAgICAgICAgICAgIG91dHNpZGVCdXR0b24gPSBzdWJlbGVtZW50Lm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgICAgIGlmIChvdXRzaWRlQnV0dG9uKSB7XG4gICAgICAgICAgICAgICAgb3V0c2lkZUJ1dHRvbi5jbGFzc0xpc3QudG9nZ2xlKCdkaXNwbGF5LW5vbmUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBoaWRlYWJsZVN1YmVsZW1lbnRzLmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgICAgICAgICBpZiAoaGFzQWRkQWRkaXRpb25hbEJ1dHRvbk91dHNpZGUgJiYgb3V0c2lkZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgIHN1YmVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZSgnbWItNicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNoaWxkLmNsYXNzTGlzdC5jb250YWlucygnaGVpZ2h0LWhpZGUnKSkge1xuICAgICAgICAgICAgICAgIGNoaWxkLmNsYXNzTGlzdC5yZW1vdmUoJ2hlaWdodC1oaWRlJyk7XG4gICAgICAgICAgICAgICAgY2hpbGQuY2xhc3NMaXN0LmFkZCgnaGVpZ2h0LXNob3cnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNoaWxkLmNsYXNzTGlzdC5yZW1vdmUoJ2hlaWdodC1zaG93Jyk7XG4gICAgICAgICAgICAgICAgY2hpbGQuY2xhc3NMaXN0LmFkZCgnaGVpZ2h0LWhpZGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gaGFuZGxlcyB0aGUgZm9ybXMgcmVuZGVyZWQgb24gaW5pdGlhbCBwYWdlIGxvYWQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXR0YWNoSW5pdGlhbENvbGxhcHNhYmxlQnV0dG9uRXZlbnRzKCkge1xuICAgICAgICBjb25zdCBhbGxDb2xsYXBzYWJsZUJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuY29sbGFwc2FibGUtYnV0dG9uJyk7XG4gICAgICAgIGFsbENvbGxhcHNhYmxlQnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IGF0dGFjaENvbGxhcHNhYmxlQnV0dG9uRXZlbnRzKGJ1dHRvbikpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGhhbmRsZXMgdGhlIGZvcm1zIHJlbmRlcmVkIG9uIGNsaWNraW5nICdBREQgQURESVRJT05BTCBYJyBidXR0b24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gb2JzZXJ2ZU5ld0NvbGxhcHNhYmxlQnV0dG9ucygpIHtcbiAgICAgICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigobXV0YXRpb25zTGlzdCkgPT4ge1xuICAgICAgICAgICAgbXV0YXRpb25zTGlzdC5mb3JFYWNoKChtdXRhdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChtdXRhdGlvbi50eXBlID09PSAnY2hpbGRMaXN0Jykge1xuICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbi5hZGRlZE5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdDb2xsYXBzYWJsZUJ1dHRvbnMgPSBub2RlLnF1ZXJ5U2VsZWN0b3JBbGwoJy5jb2xsYXBzYWJsZS1idXR0b24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdDb2xsYXBzYWJsZUJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiBhdHRhY2hDb2xsYXBzYWJsZUJ1dHRvbkV2ZW50cyhidXR0b24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBvYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LmJvZHksIHsgY2hpbGRMaXN0OiB0cnVlLCBzdWJ0cmVlOiB0cnVlIH0pO1xuICAgIH1cbiAgICBhdHRhY2hJbml0aWFsQ29sbGFwc2FibGVCdXR0b25FdmVudHMoKTtcbiAgICBvYnNlcnZlTmV3Q29sbGFwc2FibGVCdXR0b25zKCk7XG59KTtcbmZ1bmN0aW9uIGVzY2FwZUh0bWwodW5zYWZlKSB7XG4gICAgcmV0dXJuIHVuc2FmZVxuICAgICAgICAucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgICAgICAucmVwbGFjZSgvPC9nLCAnJmx0OycpXG4gICAgICAgIC5yZXBsYWNlKC8+L2csICcmZ3Q7JylcbiAgICAgICAgLnJlcGxhY2UoL1wiL2csICcmcXVvdDsnKVxuICAgICAgICAucmVwbGFjZSgvJy9nLCAnJiMwMzk7Jyk7XG59XG4vKlxuICpcbiAqIEhlbHAgVGV4dCBPcGVuIENsb3NlIEhhbmRsZXJzIFN0YXJ0XG4gKlxuICovXG4oMCwganF1ZXJ5XzEuZGVmYXVsdCkoZG9jdW1lbnQpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmICghKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGV2ZW50LnRhcmdldCkuY2xvc2VzdCgnLmhlbHAnKS5sZW5ndGgpIHtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuaGVscF9fdGV4dCcpLnJlbW92ZUF0dHIoJ3N0eWxlJyk7XG4gICAgfVxufSk7XG4oMCwganF1ZXJ5XzEuZGVmYXVsdCkoZG9jdW1lbnQpLm9uKCdjbGljaycsICcuaGVscCcsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIC8qIGVzbGludC1kaXNhYmxlICovIGNvbnNvbGUubG9nKC4uLm9vX29vKGAxNjg1OTIwMDEwXzg0NF8yXzg0NF8yMl80YCwgJ0hlbGxvJykpO1xuICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmhlbHBfX3RleHQnKS5yZW1vdmVBdHRyKCdzdHlsZScpO1xuICAgIGNvbnN0IGhlbHBUZXh0ID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpLmZpbmQoJy5oZWxwX190ZXh0Jyk7XG4gICAgaWYgKGhlbHBUZXh0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgaGVscFRleHQuY3NzKHtcbiAgICAgICAgICAgIG9wYWNpdHk6ICcxJyxcbiAgICAgICAgICAgIHZpc2liaWxpdHk6ICd2aXNpYmxlJyxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlmICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoZXZlbnQudGFyZ2V0KS5jbG9zZXN0KCcuY2xvc2UtaGVscCcpLmxlbmd0aCkge1xuICAgICAgICBjbG9zZUhlbHBUZXh0KGhlbHBUZXh0KTtcbiAgICB9XG59KTtcbigwLCBqcXVlcnlfMS5kZWZhdWx0KShkb2N1bWVudCkub24oJ2tleWRvd24nLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5oZWxwX190ZXh0JykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjbG9zZUhlbHBUZXh0KCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn0pO1xuLyoqXG4gKiBDbG9zZXMgdGhlIGhlbHAgdGV4dCB0b29sdGlwIGJ5IHNldHRpbmcgaXRzIENTUyBwcm9wZXJ0aWVzIHRvIG1ha2UgaXQgaW52aXNpYmxlIGFuZCBub24taW50ZXJhY3RpdmUuXG4gKiBBZnRlciBhIGRlbGF5LCBpdCByZW1vdmVzIHRoZSBpbmxpbmUgc3R5bGVzIHRvIHJlc2V0IHRoZSBlbGVtZW50J3Mgc3RhdGUuXG4gKlxuICogQHBhcmFtIGhlbHBUZXh0IC0gVGhlIGpRdWVyeSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSB0b29sdGlwIGVsZW1lbnQgdG8gYmUgY2xvc2VkLlxuICovXG5mdW5jdGlvbiBjbG9zZUhlbHBUZXh0KGhlbHBUZXh0KSB7XG4gICAgaGVscFRleHQuY3NzKHtcbiAgICAgICAgJ3BvaW50ZXItZXZlbnRzJzogJ25vbmUnLFxuICAgICAgICBvcGFjaXR5OiAnMCcsXG4gICAgICAgIHZpc2liaWxpdHk6ICdpbnZpc2libGUnLFxuICAgIH0pO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBoZWxwVGV4dC5yZW1vdmVBdHRyKCdzdHlsZScpO1xuICAgIH0sIDEwMDApO1xufVxuLypcbiAqXG4gKiBIZWxwIFRleHQgT3BlbiBDbG9zZSBIYW5kbGVycyBFbmRcbiAqXG4gKi9cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIC8qIGM4IGlnbm9yZSBzdGFydCAqLyAvKiBlc2xpbnQtZGlzYWJsZSAqLyA7XG5mdW5jdGlvbiBvb19jbSgpIHsgdHJ5IHtcbiAgICByZXR1cm4gKDAsIGV2YWwpKFwiZ2xvYmFsVGhpcy5fY29uc29sZV9uaW5qYVwiKSB8fCAoMCwgZXZhbCkoXCIvKiBodHRwczovL2dpdGh1Yi5jb20vd2FsbGFieWpzL2NvbnNvbGUtbmluamEjaG93LWRvZXMtaXQtd29yayAqLyd1c2Ugc3RyaWN0Jzt2YXIgXzB4MzFlNDg2PV8weDMzYjI7ZnVuY3Rpb24gXzB4MzNiMihfMHgyZDE2MTUsXzB4MjljY2I0KXt2YXIgXzB4MzRlOWYzPV8weDM0ZTkoKTtyZXR1cm4gXzB4MzNiMj1mdW5jdGlvbihfMHgzM2IyM2IsXzB4MzkzYTc0KXtfMHgzM2IyM2I9XzB4MzNiMjNiLTB4MTQ1O3ZhciBfMHg0MTI3MmQ9XzB4MzRlOWYzW18weDMzYjIzYl07cmV0dXJuIF8weDQxMjcyZDt9LF8weDMzYjIoXzB4MmQxNjE1LF8weDI5Y2NiNCk7fWZ1bmN0aW9uIF8weDM0ZTkoKXt2YXIgXzB4MTcwNGYyPVsnZXhwSWQnLCdzZXR0ZXInLCdub2RlTW9kdWxlcycsJ2luZGV4JywnX2FkZE9iamVjdFByb3BlcnR5JywndHJhY2UnLCdIVE1MQWxsQ29sbGVjdGlvbicsJ3NvcnRQcm9wcycsJ2RhdGUnLCdfaXNVbmRlZmluZWQnLCdyZXBsYWNlJywnMScsJ3ZlcnNpb25zJywnX3Byb3BlcnR5TmFtZScsJ19hZGRQcm9wZXJ0eScsJ19kaXNwb3NlV2Vic29ja2V0JywnYXV0b0V4cGFuZFByb3BlcnR5Q291bnQnLCdfaW5OZXh0RWRnZScsJ2xvZ2dlclxcXFx4MjBmYWlsZWRcXFxceDIwdG9cXFxceDIwY29ubmVjdFxcXFx4MjB0b1xcXFx4MjBob3N0Jywnc2xpY2UnLCdsb2NhdGlvbicsJ2RlZmluZVByb3BlcnR5JywnX2tleVN0clJlZ0V4cCcsJ3N5bWJvbCcsJ1tvYmplY3RcXFxceDIwU2V0XScsJ19wXycsJ1tvYmplY3RcXFxceDIwQXJyYXldJywncHJvY2VzcycsJ3Byb3BzJywnX3NlbmRFcnJvck1lc3NhZ2UnLCdzdHJpbmcnLCdudWxsJywnb2JqZWN0JywnX2dldE93blByb3BlcnR5RGVzY3JpcHRvcicsJ2xvZycsJ19hZGRpdGlvbmFsTWV0YWRhdGEnLCdiaW5kJywncGVyZm9ybWFuY2UnLCcyOTEwTnlWQ1FEJywnbGV2ZWwnLCdpbmNsdWRlcycsJ2VsYXBzZWQnLCdfY29ubmVjdFRvSG9zdE5vdycsJ2NhbGwnLCdwdXNoJywnZnVuY3Rpb24nLCd0b3RhbFN0ckxlbmd0aCcsJ2hydGltZScsJ19jb25zb2xlX25pbmphX3Nlc3Npb24nLCd0aW1lU3RhbXAnLCdmcm9tQ2hhckNvZGUnLCdhdXRvRXhwYW5kTWF4RGVwdGgnLCd3czovLycsJ19udW1iZXJSZWdFeHAnLCdQT1NJVElWRV9JTkZJTklUWScsJ19zZXROb2RlRXhwcmVzc2lvblBhdGgnLCdudW1iZXInLCdqb2luJywnY2FwcGVkUHJvcHMnLCdvbm1lc3NhZ2UnLCdiaWdpbnQnLCdfaXNQcmltaXRpdmVXcmFwcGVyVHlwZScsJ3RoZW4nLCdfc29ydFByb3BzJywnZW52Jywnbm9GdW5jdGlvbnMnLCdfcXVvdGVkUmVnRXhwJywnbG9nZ2VyXFxcXHgyMGZhaWxlZFxcXFx4MjB0b1xcXFx4MjBjb25uZWN0XFxcXHgyMHRvXFxcXHgyMGhvc3QsXFxcXHgyMHNlZVxcXFx4MjAnLCdjb25jYXQnLCdlbmRzV2l0aCcsJ3BlcmZfaG9va3MnLCdhbGxTdHJMZW5ndGgnLCdfbmluamFJZ25vcmVOZXh0RXJyb3InLCdoaXRzJywnaXNFeHByZXNzaW9uVG9FdmFsdWF0ZScsJ19hZGRMb2FkTm9kZScsJ2FzdHJvJywnX3NvY2tldCcsJ190cmVlTm9kZVByb3BlcnRpZXNCZWZvcmVGdWxsVmFsdWUnLCdwcm90b3R5cGUnLCdfb2JqZWN0VG9TdHJpbmcnLCdfd3MnLCc4Mzc0NDc4UHRjYWpqJywnY2FwcGVkJywndGltZScsJzgxNDYwZ25Nc2FDJywnQ29uc29sZVxcXFx4MjBOaW5qYVxcXFx4MjBmYWlsZWRcXFxceDIwdG9cXFxceDIwc2VuZFxcXFx4MjBsb2dzLFxcXFx4MjByZWZyZXNoaW5nXFxcXHgyMHRoZVxcXFx4MjBwYWdlXFxcXHgyMG1heVxcXFx4MjBoZWxwO1xcXFx4MjBhbHNvXFxcXHgyMHNlZVxcXFx4MjAnLCd0ZXN0JywnX3dlYlNvY2tldEVycm9yRG9jc0xpbmsnLCdkaXNhYmxlZExvZycsJ3N1YnN0cicsJ21lc3NhZ2UnLCdORUdBVElWRV9JTkZJTklUWScsJ2NvbnN0cnVjdG9yJywnY3VycmVudCcsJ3N0ckxlbmd0aCcsJ2F1dG9FeHBhbmRQcmV2aW91c09iamVjdHMnLCcyNjk1ODgwenpieGhYJywndXJsJywncm9vdEV4cHJlc3Npb24nLCd2YWx1ZScsJ21ldGhvZCcsJ3R5cGUnLCdvbmVycm9yJywnX3NldE5vZGVQZXJtaXNzaW9ucycsJ3RvU3RyaW5nJywnX19lcycrJ01vZHVsZScsJ3BhdGgnLCczMzQ1MycsJ19tYXhDb25uZWN0QXR0ZW1wdENvdW50JywnX1dlYlNvY2tldENsYXNzJywnMTI5NkVwbU1sdScsJ2VsZW1lbnRzJywnJywnRXJyb3InLCdfcF9sZW5ndGgnLCdjb3VudCcsJ3JlZHVjZUxpbWl0cycsJ2xlbmd0aCcsJ1tvYmplY3RcXFxceDIwTWFwXScsJ19pc05lZ2F0aXZlWmVybycsJ19nZXRPd25Qcm9wZXJ0eU5hbWVzJywnX3RyZWVOb2RlUHJvcGVydGllc0FmdGVyRnVsbFZhbHVlJywnX3Byb3BlcnR5JywnZGVmYXVsdCcsJ19pc1ByaW1pdGl2ZVR5cGUnLCdfYmxhY2tsaXN0ZWRQcm9wZXJ0eScsJ1NldCcsJ3ZhbHVlT2YnLCdnZXQnLCdwYXRoVG9GaWxlVVJMJywnbmFtZScsJ0NvbnNvbGVcXFxceDIwTmluamFcXFxceDIwZmFpbGVkXFxcXHgyMHRvXFxcXHgyMHNlbmRcXFxceDIwbG9ncyxcXFxceDIwcmVzdGFydGluZ1xcXFx4MjB0aGVcXFxceDIwcHJvY2Vzc1xcXFx4MjBtYXlcXFxceDIwaGVscDtcXFxceDIwYWxzb1xcXFx4MjBzZWVcXFxceDIwJywnbmVnYXRpdmVJbmZpbml0eScsJ2VudW1lcmFibGUnLCdjYXBwZWRFbGVtZW50cycsJ1xcXFx4MjBzZXJ2ZXInLCdTeW1ib2wnLCdvcmlnaW4nLCdvbmNsb3NlJywncmVhZHlTdGF0ZScsJ3dhcm4nLCdfc2V0Tm9kZUV4cGFuZGFibGVTdGF0ZScsJ2NhdGNoJywnY2xvc2UnLCd3ZWJwYWNrJywnaG9zdCcsJ3Bvc2l0aXZlSW5maW5pdHknLCdfY29ubmVjdEF0dGVtcHRDb3VudCcsJ01hcCcsJ19kYXRlVG9TdHJpbmcnLCdmb3JFYWNoJywnb25vcGVuJywnY29uc29sZScsJ19hZGRGdW5jdGlvbnNOb2RlJywnd3MvaW5kZXguanMnLCdnZXRXZWJTb2NrZXRDbGFzcycsJ3Jvb3RfZXhwX2lkJywnc3RhY2snLCdfcF9uYW1lJywnYXJyYXknLCdfYXR0ZW1wdFRvUmVjb25uZWN0U2hvcnRseScsJzExNjIydW1md1h5JywnYm9vbGVhbicsJzQyNjU2a2pnWkpaJywndW5kZWZpbmVkJywnX3R5cGUnLCd0b1VwcGVyQ2FzZScsJ3NldCcsJ2F1dG9FeHBhbmQnLCdfc2V0Tm9kZUxhYmVsJywnZ2V0dGVyJywnX2FsbG93ZWRUb0Nvbm5lY3RPblNlbmQnLCdtYXAnLCdfaW5Ccm93c2VyJywnX3Byb2Nlc3NUcmVlTm9kZVJlc3VsdCcsJ19jb25uZWN0ZWQnLCdwYXJlbnQnLCdwYXJzZScsJ2FyZ3MnLCdzdHJpbmdpZnknLCdkYXRhJywnX2dldE93blByb3BlcnR5U3ltYm9scycsJ3VucmVmJywnX1N5bWJvbCcsJ05FWFRfUlVOVElNRScsJ2hvc3RuYW1lJywnX3VuZGVmaW5lZCcsJ3RvTG93ZXJDYXNlJyxcXFwiL2hvbWUvZmx1ZmZ5Ly52c2NvZGUvZXh0ZW5zaW9ucy93YWxsYWJ5anMuY29uc29sZS1uaW5qYS0xLjAuMzgyL25vZGVfbW9kdWxlc1xcXCIsJ1N0cmluZycsJ1JlZ0V4cCcsJ19XZWJTb2NrZXQnLCcxLjAuMCcsJ21hdGNoJywnX2Nvbm5lY3RpbmcnLCdnZXRPd25Qcm9wZXJ0eVN5bWJvbHMnLCdnbG9iYWwnLCdlcnJvcicsJ19pc01hcCcsJzE5ODE1ODFXT2lDWHUnLCdfaXNBcnJheScsJ2V4cHJlc3Npb25zVG9FdmFsdWF0ZScsJ2RlcHRoJywnZXZlbnRSZWNlaXZlZENhbGxiYWNrJywnX2FsbG93ZWRUb1NlbmQnLCdub2RlJywnZG9ja2VyaXplZEFwcCcsJ3Vuc2hpZnQnLCdhdXRvRXhwYW5kTGltaXQnLCdnZXRPd25Qcm9wZXJ0eU5hbWVzJywnX2NsZWFuTm9kZScsJ19yZWNvbm5lY3RUaW1lb3V0JywnX3JlZ0V4cFRvU3RyaW5nJywnc3RhY2tUcmFjZUxpbWl0JywndW5rbm93bicsJ3NlcmlhbGl6ZScsJ2VkZ2UnLCdwb3J0JywnX0hUTUxBbGxDb2xsZWN0aW9uJyxbXFxcImxvY2FsaG9zdFxcXCIsXFxcIjEyNy4wLjAuMVxcXCIsXFxcImV4YW1wbGUuY3lwcmVzcy5pb1xcXCIsXFxcImZsdWZmeVxcXCIsXFxcIjE5Mi4xNjguMTAuMTc2XFxcIl0sJ19jb25zb2xlX25pbmphJywnX2lzU2V0JywncmVtaXgnLCdfaGFzTWFwT25JdHNQYXRoJywnc2VlXFxcXHgyMGh0dHBzOi8vdGlueXVybC5jb20vMnZ0OGp4endcXFxceDIwZm9yXFxcXHgyMG1vcmVcXFxceDIwaW5mby4nLCdcXFxceDIwYnJvd3NlcicsJ2ZhaWxlZFxcXFx4MjB0b1xcXFx4MjBmaW5kXFxcXHgyMGFuZFxcXFx4MjBsb2FkXFxcXHgyMFdlYlNvY2tldCcsJ3NvbWUnLCdub3cnLCduZXh0LmpzJywnX2NvbnNvbGVOaW5qYUFsbG93ZWRUb1N0YXJ0JywnNTc0NjAwb3BhV3F6Jywnc2VuZCcsJ19jYXBJZlN0cmluZyddO18weDM0ZTk9ZnVuY3Rpb24oKXtyZXR1cm4gXzB4MTcwNGYyO307cmV0dXJuIF8weDM0ZTkoKTt9KGZ1bmN0aW9uKF8weDQ5ZTcxOSxfMHgyYjRiYzgpe3ZhciBfMHhlYzYzMGM9XzB4MzNiMixfMHg1MWYzYzI9XzB4NDllNzE5KCk7d2hpbGUoISFbXSl7dHJ5e3ZhciBfMHgzYmM5MmM9cGFyc2VJbnQoXzB4ZWM2MzBjKDB4MTliKSkvMHgxKy1wYXJzZUludChfMHhlYzYzMGMoMHgyMmUpKS8weDIrcGFyc2VJbnQoXzB4ZWM2MzBjKDB4MjBlKSkvMHgzKy1wYXJzZUludChfMHhlYzYzMGMoMHgxYTcpKS8weDQrLXBhcnNlSW50KF8weGVjNjMwYygweDE2YykpLzB4NSoocGFyc2VJbnQoXzB4ZWM2MzBjKDB4MWU4KSkvMHg2KStwYXJzZUludChfMHhlYzYzMGMoMHgxOTgpKS8weDcrcGFyc2VJbnQoXzB4ZWM2MzBjKDB4MWVhKSkvMHg4KihwYXJzZUludChfMHhlYzYzMGMoMHgxYjUpKS8weDkpO2lmKF8weDNiYzkyYz09PV8weDJiNGJjOClicmVhaztlbHNlIF8weDUxZjNjMlsncHVzaCddKF8weDUxZjNjMlsnc2hpZnQnXSgpKTt9Y2F0Y2goXzB4MjI4NjllKXtfMHg1MWYzYzJbJ3B1c2gnXShfMHg1MWYzYzJbJ3NoaWZ0J10oKSk7fX19KF8weDM0ZTksMHg5NmM0OSkpO3ZhciBLPU9iamVjdFsnY3JlYXRlJ10sUT1PYmplY3RbXzB4MzFlNDg2KDB4MTViKV0sRz1PYmplY3RbJ2dldE93blByb3BlcnR5RGVzY3JpcHRvciddLGVlPU9iamVjdFtfMHgzMWU0ODYoMHgyMTgpXSx0ZT1PYmplY3RbJ2dldFByb3RvdHlwZU9mJ10sbmU9T2JqZWN0Wydwcm90b3R5cGUnXVsnaGFzT3duUHJvcGVydHknXSxyZT0oXzB4Mjg5Y2YwLF8weDE3MzIzYyxfMHgxMmQ2M2MsXzB4MWU5YjZkKT0+e3ZhciBfMHgzNzQyZGE9XzB4MzFlNDg2O2lmKF8weDE3MzIzYyYmdHlwZW9mIF8weDE3MzIzYz09XzB4Mzc0MmRhKDB4MTY2KXx8dHlwZW9mIF8weDE3MzIzYz09XzB4Mzc0MmRhKDB4MTczKSl7Zm9yKGxldCBfMHgzMGM4ZTkgb2YgZWUoXzB4MTczMjNjKSkhbmVbXzB4Mzc0MmRhKDB4MTcxKV0oXzB4Mjg5Y2YwLF8weDMwYzhlOSkmJl8weDMwYzhlOSE9PV8weDEyZDYzYyYmUShfMHgyODljZjAsXzB4MzBjOGU5LHsnZ2V0JzooKT0+XzB4MTczMjNjW18weDMwYzhlOV0sJ2VudW1lcmFibGUnOiEoXzB4MWU5YjZkPUcoXzB4MTczMjNjLF8weDMwYzhlOSkpfHxfMHgxZTliNmRbXzB4Mzc0MmRhKDB4MWNjKV19KTt9cmV0dXJuIF8weDI4OWNmMDt9LFY9KF8weDRkNDNiMyxfMHgyOGM2OTksXzB4M2U0ZWJjKT0+KF8weDNlNGViYz1fMHg0ZDQzYjMhPW51bGw/Syh0ZShfMHg0ZDQzYjMpKTp7fSxyZShfMHgyOGM2OTl8fCFfMHg0ZDQzYjN8fCFfMHg0ZDQzYjNbXzB4MzFlNDg2KDB4MWIwKV0/UShfMHgzZTRlYmMsXzB4MzFlNDg2KDB4MWMyKSx7J3ZhbHVlJzpfMHg0ZDQzYjMsJ2VudW1lcmFibGUnOiEweDB9KTpfMHgzZTRlYmMsXzB4NGQ0M2IzKSksWj1jbGFzc3tjb25zdHJ1Y3RvcihfMHgxOTBhYTgsXzB4NDhiNTE5LF8weDFmMWRkZCxfMHgyYTQ5ZjgsXzB4ZGQ0NDhhLF8weDI2YmFlZSl7dmFyIF8weGNkMzkzMT1fMHgzMWU0ODYsXzB4MjkxMWM1LF8weDE5NTM4YyxfMHgzZTdiMjQsXzB4MTcwNTcxO3RoaXNbJ2dsb2JhbCddPV8weDE5MGFhOCx0aGlzWydob3N0J109XzB4NDhiNTE5LHRoaXNbXzB4Y2QzOTMxKDB4MjIwKV09XzB4MWYxZGRkLHRoaXNbXzB4Y2QzOTMxKDB4MTQ4KV09XzB4MmE0OWY4LHRoaXNbJ2RvY2tlcml6ZWRBcHAnXT1fMHhkZDQ0OGEsdGhpc1snZXZlbnRSZWNlaXZlZENhbGxiYWNrJ109XzB4MjZiYWVlLHRoaXNbJ19hbGxvd2VkVG9TZW5kJ109ITB4MCx0aGlzWydfYWxsb3dlZFRvQ29ubmVjdE9uU2VuZCddPSEweDAsdGhpc1snX2Nvbm5lY3RlZCddPSEweDEsdGhpc1tfMHhjZDM5MzEoMHgyMDkpXT0hMHgxLHRoaXNbXzB4Y2QzOTMxKDB4MTU3KV09KChfMHgxOTUzOGM9KF8weDI5MTFjNT1fMHgxOTBhYThbJ3Byb2Nlc3MnXSk9PW51bGw/dm9pZCAweDA6XzB4MjkxMWM1WydlbnYnXSk9PW51bGw/dm9pZCAweDA6XzB4MTk1MzhjWydORVhUX1JVTlRJTUUnXSk9PT0nZWRnZScsdGhpc1tfMHhjZDM5MzEoMHgxZjQpXT0hKChfMHgxNzA1NzE9KF8weDNlN2IyND10aGlzW18weGNkMzkzMSgweDIwYildW18weGNkMzkzMSgweDE2MSldKT09bnVsbD92b2lkIDB4MDpfMHgzZTdiMjRbXzB4Y2QzOTMxKDB4MTUyKV0pIT1udWxsJiZfMHgxNzA1NzFbXzB4Y2QzOTMxKDB4MjE0KV0pJiYhdGhpc1tfMHhjZDM5MzEoMHgxNTcpXSx0aGlzW18weGNkMzkzMSgweDFiNCldPW51bGwsdGhpc1tfMHhjZDM5MzEoMHgxZGEpXT0weDAsdGhpc1tfMHhjZDM5MzEoMHgxYjMpXT0weDE0LHRoaXNbJ193ZWJTb2NrZXRFcnJvckRvY3NMaW5rJ109J2h0dHBzOi8vdGlueXVybC5jb20vMzd4OGI3OXQnLHRoaXNbXzB4Y2QzOTMxKDB4MTYzKV09KHRoaXNbXzB4Y2QzOTMxKDB4MWY0KV0/XzB4Y2QzOTMxKDB4MTljKTpfMHhjZDM5MzEoMHgxY2EpKSt0aGlzW18weGNkMzkzMSgweDE5ZSldO31hc3luY1tfMHgzMWU0ODYoMHgxZTIpXSgpe3ZhciBfMHgzNDA5YTk9XzB4MzFlNDg2LF8weDJiM2Y4NixfMHg0NDgwMzA7aWYodGhpc1tfMHgzNDA5YTkoMHgxYjQpXSlyZXR1cm4gdGhpc1tfMHgzNDA5YTkoMHgxYjQpXTtsZXQgXzB4NTI4NjM2O2lmKHRoaXNbJ19pbkJyb3dzZXInXXx8dGhpc1tfMHgzNDA5YTkoMHgxNTcpXSlfMHg1Mjg2MzY9dGhpc1tfMHgzNDA5YTkoMHgyMGIpXVsnV2ViU29ja2V0J107ZWxzZXtpZigoXzB4MmIzZjg2PXRoaXNbXzB4MzQwOWE5KDB4MjBiKV1bJ3Byb2Nlc3MnXSkhPW51bGwmJl8weDJiM2Y4NltfMHgzNDA5YTkoMHgyMDYpXSlfMHg1Mjg2MzY9KF8weDQ0ODAzMD10aGlzWydnbG9iYWwnXVsncHJvY2VzcyddKT09bnVsbD92b2lkIDB4MDpfMHg0NDgwMzBbXzB4MzQwOWE5KDB4MjA2KV07ZWxzZSB0cnl7bGV0IF8weDEwODhiND1hd2FpdCBpbXBvcnQoXzB4MzQwOWE5KDB4MWIxKSk7XzB4NTI4NjM2PShhd2FpdCBpbXBvcnQoKGF3YWl0IGltcG9ydChfMHgzNDA5YTkoMHgxYTgpKSlbXzB4MzQwOWE5KDB4MWM4KV0oXzB4MTA4OGI0W18weDM0MDlhOSgweDE3ZildKHRoaXNbXzB4MzQwOWE5KDB4MTQ4KV0sXzB4MzQwOWE5KDB4MWUxKSkpW18weDM0MDlhOSgweDFhZildKCkpKVsnZGVmYXVsdCddO31jYXRjaHt0cnl7XzB4NTI4NjM2PXJlcXVpcmUocmVxdWlyZSgncGF0aCcpW18weDM0MDlhOSgweDE3ZildKHRoaXNbJ25vZGVNb2R1bGVzJ10sJ3dzJykpO31jYXRjaHt0aHJvdyBuZXcgRXJyb3IoXzB4MzQwOWE5KDB4MjI5KSk7fX19cmV0dXJuIHRoaXNbXzB4MzQwOWE5KDB4MWI0KV09XzB4NTI4NjM2LF8weDUyODYzNjt9W18weDMxZTQ4NigweDE3MCldKCl7dmFyIF8weDI5YTgyNT1fMHgzMWU0ODY7dGhpc1snX2Nvbm5lY3RpbmcnXXx8dGhpc1snX2Nvbm5lY3RlZCddfHx0aGlzW18weDI5YTgyNSgweDFkYSldPj10aGlzW18weDI5YTgyNSgweDFiMyldfHwodGhpc1tfMHgyOWE4MjUoMHgxZjIpXT0hMHgxLHRoaXNbXzB4MjlhODI1KDB4MjA5KV09ITB4MCx0aGlzW18weDI5YTgyNSgweDFkYSldKyssdGhpc1tfMHgyOWE4MjUoMHgxOTcpXT1uZXcgUHJvbWlzZSgoXzB4MWYyYzQ4LF8weDViMDJmOCk9Pnt2YXIgXzB4NDEzY2E5PV8weDI5YTgyNTt0aGlzW18weDQxM2NhOSgweDFlMildKClbXzB4NDEzY2E5KDB4MTg0KV0oXzB4NGU5ZmI4PT57dmFyIF8weDIzMWZkOT1fMHg0MTNjYTk7bGV0IF8weDE1YmE4YT1uZXcgXzB4NGU5ZmI4KF8weDIzMWZkOSgweDE3YSkrKCF0aGlzWydfaW5Ccm93c2VyJ10mJnRoaXNbXzB4MjMxZmQ5KDB4MjE1KV0/J2dhdGV3YXkuZG9ja2VyLmludGVybmFsJzp0aGlzW18weDIzMWZkOSgweDFkOCldKSsnOicrdGhpc1tfMHgyMzFmZDkoMHgyMjApXSk7XzB4MTViYThhWydvbmVycm9yJ109KCk9Pnt2YXIgXzB4NDhkNDE4PV8weDIzMWZkOTt0aGlzW18weDQ4ZDQxOCgweDIxMyldPSEweDEsdGhpc1tfMHg0OGQ0MTgoMHgxNTUpXShfMHgxNWJhOGEpLHRoaXNbXzB4NDhkNDE4KDB4MWU3KV0oKSxfMHg1YjAyZjgobmV3IEVycm9yKCdsb2dnZXJcXFxceDIwd2Vic29ja2V0XFxcXHgyMGVycm9yJykpO30sXzB4MTViYThhWydvbm9wZW4nXT0oKT0+e3ZhciBfMHgzZWQ2MTE9XzB4MjMxZmQ5O3RoaXNbXzB4M2VkNjExKDB4MWY0KV18fF8weDE1YmE4YVtfMHgzZWQ2MTEoMHgxOTMpXSYmXzB4MTViYThhWydfc29ja2V0J11bXzB4M2VkNjExKDB4MWZkKV0mJl8weDE1YmE4YVtfMHgzZWQ2MTEoMHgxOTMpXVtfMHgzZWQ2MTEoMHgxZmQpXSgpLF8weDFmMmM0OChfMHgxNWJhOGEpO30sXzB4MTViYThhW18weDIzMWZkOSgweDFkMSldPSgpPT57dmFyIF8weDg2OTYyNj1fMHgyMzFmZDk7dGhpc1tfMHg4Njk2MjYoMHgxZjIpXT0hMHgwLHRoaXNbXzB4ODY5NjI2KDB4MTU1KV0oXzB4MTViYThhKSx0aGlzW18weDg2OTYyNigweDFlNyldKCk7fSxfMHgxNWJhOGFbXzB4MjMxZmQ5KDB4MTgxKV09XzB4M2Q4YWNlPT57dmFyIF8weDEyMjNiYT1fMHgyMzFmZDk7dHJ5e2lmKCEoXzB4M2Q4YWNlIT1udWxsJiZfMHgzZDhhY2VbJ2RhdGEnXSl8fCF0aGlzW18weDEyMjNiYSgweDIxMildKXJldHVybjtsZXQgXzB4NTJmMzg9SlNPTltfMHgxMjIzYmEoMHgxZjgpXShfMHgzZDhhY2VbXzB4MTIyM2JhKDB4MWZiKV0pO3RoaXNbJ2V2ZW50UmVjZWl2ZWRDYWxsYmFjayddKF8weDUyZjM4W18weDEyMjNiYSgweDFhYildLF8weDUyZjM4W18weDEyMjNiYSgweDFmOSldLHRoaXNbXzB4MTIyM2JhKDB4MjBiKV0sdGhpc1tfMHgxMjIzYmEoMHgxZjQpXSk7fWNhdGNoe319O30pWyd0aGVuJ10oXzB4MjEzNzQwPT4odGhpc1tfMHg0MTNjYTkoMHgxZjYpXT0hMHgwLHRoaXNbXzB4NDEzY2E5KDB4MjA5KV09ITB4MSx0aGlzW18weDQxM2NhOSgweDFmMildPSEweDEsdGhpc1snX2FsbG93ZWRUb1NlbmQnXT0hMHgwLHRoaXNbXzB4NDEzY2E5KDB4MWRhKV09MHgwLF8weDIxMzc0MCkpW18weDQxM2NhOSgweDFkNSldKF8weDI0NDg3Nj0+KHRoaXNbXzB4NDEzY2E5KDB4MWY2KV09ITB4MSx0aGlzW18weDQxM2NhOSgweDIwOSldPSEweDEsY29uc29sZVtfMHg0MTNjYTkoMHgxZDMpXShfMHg0MTNjYTkoMHgxODkpK3RoaXNbXzB4NDEzY2E5KDB4MTllKV0pLF8weDViMDJmOChuZXcgRXJyb3IoJ2ZhaWxlZFxcXFx4MjB0b1xcXFx4MjBjb25uZWN0XFxcXHgyMHRvXFxcXHgyMGhvc3Q6XFxcXHgyMCcrKF8weDI0NDg3NiYmXzB4MjQ0ODc2WydtZXNzYWdlJ10pKSkpKTt9KSk7fVtfMHgzMWU0ODYoMHgxNTUpXShfMHgzOGNkMWYpe3ZhciBfMHgyMjZiYWY9XzB4MzFlNDg2O3RoaXNbXzB4MjI2YmFmKDB4MWY2KV09ITB4MSx0aGlzW18weDIyNmJhZigweDIwOSldPSEweDE7dHJ5e18weDM4Y2QxZltfMHgyMjZiYWYoMHgxZDEpXT1udWxsLF8weDM4Y2QxZltfMHgyMjZiYWYoMHgxYWQpXT1udWxsLF8weDM4Y2QxZltfMHgyMjZiYWYoMHgxZGUpXT1udWxsO31jYXRjaHt9dHJ5e18weDM4Y2QxZltfMHgyMjZiYWYoMHgxZDIpXTwweDImJl8weDM4Y2QxZltfMHgyMjZiYWYoMHgxZDYpXSgpO31jYXRjaHt9fVtfMHgzMWU0ODYoMHgxZTcpXSgpe3ZhciBfMHg1MzVlNzM9XzB4MzFlNDg2O2NsZWFyVGltZW91dCh0aGlzW18weDUzNWU3MygweDIxYSldKSwhKHRoaXNbJ19jb25uZWN0QXR0ZW1wdENvdW50J10+PXRoaXNbJ19tYXhDb25uZWN0QXR0ZW1wdENvdW50J10pJiYodGhpc1snX3JlY29ubmVjdFRpbWVvdXQnXT1zZXRUaW1lb3V0KCgpPT57dmFyIF8weDQ2NTE0Mj1fMHg1MzVlNzMsXzB4MTRjZDVhO3RoaXNbXzB4NDY1MTQyKDB4MWY2KV18fHRoaXNbXzB4NDY1MTQyKDB4MjA5KV18fCh0aGlzWydfY29ubmVjdFRvSG9zdE5vdyddKCksKF8weDE0Y2Q1YT10aGlzW18weDQ2NTE0MigweDE5NyldKT09bnVsbHx8XzB4MTRjZDVhWydjYXRjaCddKCgpPT50aGlzW18weDQ2NTE0MigweDFlNyldKCkpKTt9LDB4MWY0KSx0aGlzW18weDUzNWU3MygweDIxYSldW18weDUzNWU3MygweDFmZCldJiZ0aGlzW18weDUzNWU3MygweDIxYSldWyd1bnJlZiddKCkpO31hc3luY1tfMHgzMWU0ODYoMHgyMmYpXShfMHg1ZjI3YTIpe3ZhciBfMHgzNDI5YTQ9XzB4MzFlNDg2O3RyeXtpZighdGhpc1tfMHgzNDI5YTQoMHgyMTMpXSlyZXR1cm47dGhpc1tfMHgzNDI5YTQoMHgxZjIpXSYmdGhpc1tfMHgzNDI5YTQoMHgxNzApXSgpLChhd2FpdCB0aGlzWydfd3MnXSlbXzB4MzQyOWE0KDB4MjJmKV0oSlNPTltfMHgzNDI5YTQoMHgxZmEpXShfMHg1ZjI3YTIpKTt9Y2F0Y2goXzB4NWFmZWM2KXtjb25zb2xlW18weDM0MjlhNCgweDFkMyldKHRoaXNbXzB4MzQyOWE0KDB4MTYzKV0rJzpcXFxceDIwJysoXzB4NWFmZWM2JiZfMHg1YWZlYzZbXzB4MzQyOWE0KDB4MWExKV0pKSx0aGlzWydfYWxsb3dlZFRvU2VuZCddPSEweDEsdGhpc1tfMHgzNDI5YTQoMHgxZTcpXSgpO319fTtmdW5jdGlvbiBxKF8weDQyOTg2ZCxfMHgyMDNhMzgsXzB4MzA5MjdhLF8weDFiOTU5NCxfMHgyNTBiYmUsXzB4MmUyNTZmLF8weDMwMWIyMixfMHgzZjdjMjY9aWUpe3ZhciBfMHgzNzMxMzE9XzB4MzFlNDg2O2xldCBfMHgzZDA5NGU9XzB4MzA5MjdhWydzcGxpdCddKCcsJylbXzB4MzczMTMxKDB4MWYzKV0oXzB4NTM0NTQ2PT57dmFyIF8weDUzZjY1MT1fMHgzNzMxMzEsXzB4NDY5NDM0LF8weDE5NWYyMyxfMHg0YmVhNWYsXzB4MTQ0MmU4O3RyeXtpZighXzB4NDI5ODZkW18weDUzZjY1MSgweDE3NildKXtsZXQgXzB4MjMwM2ViPSgoXzB4MTk1ZjIzPShfMHg0Njk0MzQ9XzB4NDI5ODZkW18weDUzZjY1MSgweDE2MSldKT09bnVsbD92b2lkIDB4MDpfMHg0Njk0MzRbXzB4NTNmNjUxKDB4MTUyKV0pPT1udWxsP3ZvaWQgMHgwOl8weDE5NWYyM1tfMHg1M2Y2NTEoMHgyMTQpXSl8fCgoXzB4MTQ0MmU4PShfMHg0YmVhNWY9XzB4NDI5ODZkW18weDUzZjY1MSgweDE2MSldKT09bnVsbD92b2lkIDB4MDpfMHg0YmVhNWZbXzB4NTNmNjUxKDB4MTg2KV0pPT1udWxsP3ZvaWQgMHgwOl8weDE0NDJlOFtfMHg1M2Y2NTEoMHgxZmYpXSk9PT1fMHg1M2Y2NTEoMHgyMWYpOyhfMHgyNTBiYmU9PT1fMHg1M2Y2NTEoMHgyMmMpfHxfMHgyNTBiYmU9PT1fMHg1M2Y2NTEoMHgyMjUpfHxfMHgyNTBiYmU9PT1fMHg1M2Y2NTEoMHgxOTIpfHxfMHgyNTBiYmU9PT0nYW5ndWxhcicpJiYoXzB4MjUwYmJlKz1fMHgyMzAzZWI/XzB4NTNmNjUxKDB4MWNlKTpfMHg1M2Y2NTEoMHgyMjgpKSxfMHg0Mjk4NmRbJ19jb25zb2xlX25pbmphX3Nlc3Npb24nXT17J2lkJzorbmV3IERhdGUoKSwndG9vbCc6XzB4MjUwYmJlfSxfMHgzMDFiMjImJl8weDI1MGJiZSYmIV8weDIzMDNlYiYmY29uc29sZVtfMHg1M2Y2NTEoMHgxNjgpXSgnJWNcXFxceDIwQ29uc29sZVxcXFx4MjBOaW5qYVxcXFx4MjBleHRlbnNpb25cXFxceDIwaXNcXFxceDIwY29ubmVjdGVkXFxcXHgyMHRvXFxcXHgyMCcrKF8weDI1MGJiZVsnY2hhckF0J10oMHgwKVtfMHg1M2Y2NTEoMHgxZWQpXSgpK18weDI1MGJiZVtfMHg1M2Y2NTEoMHgxYTApXSgweDEpKSsnLCcsJ2JhY2tncm91bmQ6XFxcXHgyMHJnYigzMCwzMCwzMCk7XFxcXHgyMGNvbG9yOlxcXFx4MjByZ2IoMjU1LDIxMyw5MiknLF8weDUzZjY1MSgweDIyNykpO31sZXQgXzB4MjczYjY0PW5ldyBaKF8weDQyOTg2ZCxfMHgyMDNhMzgsXzB4NTM0NTQ2LF8weDFiOTU5NCxfMHgyZTI1NmYsXzB4M2Y3YzI2KTtyZXR1cm4gXzB4MjczYjY0W18weDUzZjY1MSgweDIyZildW18weDUzZjY1MSgweDE2YSldKF8weDI3M2I2NCk7fWNhdGNoKF8weDIwMzRkNil7cmV0dXJuIGNvbnNvbGVbXzB4NTNmNjUxKDB4MWQzKV0oXzB4NTNmNjUxKDB4MTU4KSxfMHgyMDM0ZDYmJl8weDIwMzRkNltfMHg1M2Y2NTEoMHgxYTEpXSksKCk9Pnt9O319KTtyZXR1cm4gXzB4NGVlZmE1PT5fMHgzZDA5NGVbXzB4MzczMTMxKDB4MWRkKV0oXzB4M2RhOTFhPT5fMHgzZGE5MWEoXzB4NGVlZmE1KSk7fWZ1bmN0aW9uIGllKF8weDFjNzc1MSxfMHgyMjJjZDAsXzB4MWVlM2UyLF8weDUyZjZhOSl7dmFyIF8weDQ4NjY4MD1fMHgzMWU0ODY7XzB4NTJmNmE5JiZfMHgxYzc3NTE9PT0ncmVsb2FkJyYmXzB4MWVlM2UyW18weDQ4NjY4MCgweDE1YSldWydyZWxvYWQnXSgpO31mdW5jdGlvbiBCKF8weGY2MjA4ZCl7dmFyIF8weDUyMDFlZj1fMHgzMWU0ODYsXzB4NGM4Y2Y5LF8weDNjNzRkZTtsZXQgXzB4M2E4MWEzPWZ1bmN0aW9uKF8weDRmNTZkNyxfMHg0N2FhNDgpe3JldHVybiBfMHg0N2FhNDgtXzB4NGY1NmQ3O30sXzB4NGUzNjY1O2lmKF8weGY2MjA4ZFsncGVyZm9ybWFuY2UnXSlfMHg0ZTM2NjU9ZnVuY3Rpb24oKXt2YXIgXzB4MTIwNTJmPV8weDMzYjI7cmV0dXJuIF8weGY2MjA4ZFtfMHgxMjA1MmYoMHgxNmIpXVtfMHgxMjA1MmYoMHgyMmIpXSgpO307ZWxzZXtpZihfMHhmNjIwOGRbXzB4NTIwMWVmKDB4MTYxKV0mJl8weGY2MjA4ZFsncHJvY2VzcyddW18weDUyMDFlZigweDE3NSldJiYoKF8weDNjNzRkZT0oXzB4NGM4Y2Y5PV8weGY2MjA4ZFtfMHg1MjAxZWYoMHgxNjEpXSk9PW51bGw/dm9pZCAweDA6XzB4NGM4Y2Y5W18weDUyMDFlZigweDE4NildKT09bnVsbD92b2lkIDB4MDpfMHgzYzc0ZGVbXzB4NTIwMWVmKDB4MWZmKV0pIT09J2VkZ2UnKV8weDRlMzY2NT1mdW5jdGlvbigpe3ZhciBfMHg1NGM1YTA9XzB4NTIwMWVmO3JldHVybiBfMHhmNjIwOGRbXzB4NTRjNWEwKDB4MTYxKV1bXzB4NTRjNWEwKDB4MTc1KV0oKTt9LF8weDNhODFhMz1mdW5jdGlvbihfMHg0NjliYWIsXzB4MTliNWI0KXtyZXR1cm4gMHgzZTgqKF8weDE5YjViNFsweDBdLV8weDQ2OWJhYlsweDBdKSsoXzB4MTliNWI0WzB4MV0tXzB4NDY5YmFiWzB4MV0pLzB4ZjQyNDA7fTtlbHNlIHRyeXtsZXQge3BlcmZvcm1hbmNlOl8weDQyMGJlN309cmVxdWlyZShfMHg1MjAxZWYoMHgxOGMpKTtfMHg0ZTM2NjU9ZnVuY3Rpb24oKXtyZXR1cm4gXzB4NDIwYmU3Wydub3cnXSgpO307fWNhdGNoe18weDRlMzY2NT1mdW5jdGlvbigpe3JldHVybituZXcgRGF0ZSgpO307fX1yZXR1cm57J2VsYXBzZWQnOl8weDNhODFhMywndGltZVN0YW1wJzpfMHg0ZTM2NjUsJ25vdyc6KCk9PkRhdGVbJ25vdyddKCl9O31mdW5jdGlvbiBIKF8weDE2MDFmNixfMHg0NTljZDEsXzB4NDdiMmIwKXt2YXIgXzB4NDNhNzUwPV8weDMxZTQ4NixfMHgyMDA4ZGMsXzB4NDA0MTZmLF8weDE5MGRlZixfMHg1YmJmMjQsXzB4NTVhYTg1O2lmKF8weDE2MDFmNltfMHg0M2E3NTAoMHgyMmQpXSE9PXZvaWQgMHgwKXJldHVybiBfMHgxNjAxZjZbXzB4NDNhNzUwKDB4MjJkKV07bGV0IF8weDIwZGM5ND0oKF8weDQwNDE2Zj0oXzB4MjAwOGRjPV8weDE2MDFmNltfMHg0M2E3NTAoMHgxNjEpXSk9PW51bGw/dm9pZCAweDA6XzB4MjAwOGRjW18weDQzYTc1MCgweDE1MildKT09bnVsbD92b2lkIDB4MDpfMHg0MDQxNmZbJ25vZGUnXSl8fCgoXzB4NWJiZjI0PShfMHgxOTBkZWY9XzB4MTYwMWY2W18weDQzYTc1MCgweDE2MSldKT09bnVsbD92b2lkIDB4MDpfMHgxOTBkZWZbXzB4NDNhNzUwKDB4MTg2KV0pPT1udWxsP3ZvaWQgMHgwOl8weDViYmYyNFtfMHg0M2E3NTAoMHgxZmYpXSk9PT0nZWRnZSc7ZnVuY3Rpb24gXzB4ZjMxNGNjKF8weDNhMWU5OCl7dmFyIF8weDJiZTM0ND1fMHg0M2E3NTA7aWYoXzB4M2ExZTk4WydzdGFydHNXaXRoJ10oJy8nKSYmXzB4M2ExZTk4W18weDJiZTM0NCgweDE4YildKCcvJykpe2xldCBfMHgxNGM5MGM9bmV3IFJlZ0V4cChfMHgzYTFlOThbXzB4MmJlMzQ0KDB4MTU5KV0oMHgxLC0weDEpKTtyZXR1cm4gXzB4NTAyOGIyPT5fMHgxNGM5MGNbXzB4MmJlMzQ0KDB4MTlkKV0oXzB4NTAyOGIyKTt9ZWxzZXtpZihfMHgzYTFlOThbXzB4MmJlMzQ0KDB4MTZlKV0oJyonKXx8XzB4M2ExZTk4W18weDJiZTM0NCgweDE2ZSldKCc/Jykpe2xldCBfMHgyODY3ZWU9bmV3IFJlZ0V4cCgnXicrXzB4M2ExZTk4W18weDJiZTM0NCgweDE1MCldKC9cXFxcLi9nLFN0cmluZ1tfMHgyYmUzNDQoMHgxNzgpXSgweDVjKSsnLicpWydyZXBsYWNlJ10oL1xcXFwqL2csJy4qJylbXzB4MmJlMzQ0KDB4MTUwKV0oL1xcXFw/L2csJy4nKStTdHJpbmdbXzB4MmJlMzQ0KDB4MTc4KV0oMHgyNCkpO3JldHVybiBfMHhhMDcxNmM9Pl8weDI4NjdlZVsndGVzdCddKF8weGEwNzE2Yyk7fWVsc2UgcmV0dXJuIF8weDRiYTA2YT0+XzB4NGJhMDZhPT09XzB4M2ExZTk4O319bGV0IF8weDUzYzg5MD1fMHg0NTljZDFbJ21hcCddKF8weGYzMTRjYyk7cmV0dXJuIF8weDE2MDFmNltfMHg0M2E3NTAoMHgyMmQpXT1fMHgyMGRjOTR8fCFfMHg0NTljZDEsIV8weDE2MDFmNlsnX2NvbnNvbGVOaW5qYUFsbG93ZWRUb1N0YXJ0J10mJigoXzB4NTVhYTg1PV8weDE2MDFmNlsnbG9jYXRpb24nXSk9PW51bGw/dm9pZCAweDA6XzB4NTVhYTg1W18weDQzYTc1MCgweDIwMCldKSYmKF8weDE2MDFmNltfMHg0M2E3NTAoMHgyMmQpXT1fMHg1M2M4OTBbXzB4NDNhNzUwKDB4MjJhKV0oXzB4NDE2NjI1PT5fMHg0MTY2MjUoXzB4MTYwMWY2Wydsb2NhdGlvbiddWydob3N0bmFtZSddKSkpLF8weDE2MDFmNltfMHg0M2E3NTAoMHgyMmQpXTt9ZnVuY3Rpb24gWChfMHg0MjZkNWYsXzB4NThiZDkzLF8weDJkYmJiNyxfMHgyZWZiMzIpe3ZhciBfMHgxMjc3MzU9XzB4MzFlNDg2O18weDQyNmQ1Zj1fMHg0MjZkNWYsXzB4NThiZDkzPV8weDU4YmQ5MyxfMHgyZGJiYjc9XzB4MmRiYmI3LF8weDJlZmIzMj1fMHgyZWZiMzI7bGV0IF8weGJiZjUyZj1CKF8weDQyNmQ1ZiksXzB4MjMyZDBkPV8weGJiZjUyZltfMHgxMjc3MzUoMHgxNmYpXSxfMHg1YjY4OWQ9XzB4YmJmNTJmW18weDEyNzczNSgweDE3NyldO2NsYXNzIF8weDJlMGQzY3tjb25zdHJ1Y3Rvcigpe3ZhciBfMHg1NDIxYjk9XzB4MTI3NzM1O3RoaXNbXzB4NTQyMWI5KDB4MTVjKV09L14oPyEoPzpkb3xpZnxpbnxmb3J8bGV0fG5ld3x0cnl8dmFyfGNhc2V8ZWxzZXxlbnVtfGV2YWx8ZmFsc2V8bnVsbHx0aGlzfHRydWV8dm9pZHx3aXRofGJyZWFrfGNhdGNofGNsYXNzfGNvbnN0fHN1cGVyfHRocm93fHdoaWxlfHlpZWxkfGRlbGV0ZXxleHBvcnR8aW1wb3J0fHB1YmxpY3xyZXR1cm58c3RhdGljfHN3aXRjaHx0eXBlb2Z8ZGVmYXVsdHxleHRlbmRzfGZpbmFsbHl8cGFja2FnZXxwcml2YXRlfGNvbnRpbnVlfGRlYnVnZ2VyfGZ1bmN0aW9ufGFyZ3VtZW50c3xpbnRlcmZhY2V8cHJvdGVjdGVkfGltcGxlbWVudHN8aW5zdGFuY2VvZikkKVtfJGEtekEtWlxcXFx4QTAtXFxcXHVGRkZGXVtfJGEtekEtWjAtOVxcXFx4QTAtXFxcXHVGRkZGXSokLyx0aGlzW18weDU0MjFiOSgweDE3YildPS9eKDB8WzEtOV1bMC05XSopJC8sdGhpc1tfMHg1NDIxYjkoMHgxODgpXT0vJyhbXlxcXFxcXFxcJ118XFxcXFxcXFwnKSonLyx0aGlzWydfdW5kZWZpbmVkJ109XzB4NDI2ZDVmW18weDU0MjFiOSgweDFlYildLHRoaXNbXzB4NTQyMWI5KDB4MjIxKV09XzB4NDI2ZDVmW18weDU0MjFiOSgweDE0YyldLHRoaXNbXzB4NTQyMWI5KDB4MTY3KV09T2JqZWN0WydnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3InXSx0aGlzW18weDU0MjFiOSgweDFiZildPU9iamVjdFtfMHg1NDIxYjkoMHgyMTgpXSx0aGlzWydfU3ltYm9sJ109XzB4NDI2ZDVmW18weDU0MjFiOSgweDFjZildLHRoaXNbXzB4NTQyMWI5KDB4MjFiKV09UmVnRXhwW18weDU0MjFiOSgweDE5NSldWyd0b1N0cmluZyddLHRoaXNbXzB4NTQyMWI5KDB4MWRjKV09RGF0ZVtfMHg1NDIxYjkoMHgxOTUpXVsndG9TdHJpbmcnXTt9WydzZXJpYWxpemUnXShfMHg1MTUwYjIsXzB4ZDQwYTRiLF8weDFjNzkwMCxfMHg0MTk2ZDcpe3ZhciBfMHgyYzdkMDQ9XzB4MTI3NzM1LF8weDM4ZTk0YT10aGlzLF8weDg3OWQ5OD1fMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MWVmKV07ZnVuY3Rpb24gXzB4ODAxZTQ1KF8weDRiZjY0MyxfMHg0MDZlOTMsXzB4MzAzZjJkKXt2YXIgXzB4NDU3ODA5PV8weDJjN2QwNDtfMHg0MDZlOTNbJ3R5cGUnXT0ndW5rbm93bicsXzB4NDA2ZTkzW18weDQ1NzgwOSgweDIwYyldPV8weDRiZjY0M1tfMHg0NTc4MDkoMHgxYTEpXSxfMHgxMjI5YjI9XzB4MzAzZjJkW18weDQ1NzgwOSgweDIxNCldW18weDQ1NzgwOSgweDFhNCldLF8weDMwM2YyZFtfMHg0NTc4MDkoMHgyMTQpXVtfMHg0NTc4MDkoMHgxYTQpXT1fMHg0MDZlOTMsXzB4MzhlOTRhWydfdHJlZU5vZGVQcm9wZXJ0aWVzQmVmb3JlRnVsbFZhbHVlJ10oXzB4NDA2ZTkzLF8weDMwM2YyZCk7fXRyeXtfMHgxYzc5MDBbJ2xldmVsJ10rKyxfMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MWVmKV0mJl8weDFjNzkwMFtfMHgyYzdkMDQoMHgxYTYpXVtfMHgyYzdkMDQoMHgxNzIpXShfMHhkNDBhNGIpO3ZhciBfMHg1ZDhhMTYsXzB4NTE2YjIwLF8weDI1YjkwMixfMHgyMThmNTUsXzB4NWQxZTRiPVtdLF8weDczNTI0ND1bXSxfMHg0ZjE1ZmUsXzB4MmVhN2FlPXRoaXNbXzB4MmM3ZDA0KDB4MWVjKV0oXzB4ZDQwYTRiKSxfMHgzOTdjN2U9XzB4MmVhN2FlPT09XzB4MmM3ZDA0KDB4MWU2KSxfMHgyMjNlNzc9ITB4MSxfMHgyZWYzNGI9XzB4MmVhN2FlPT09XzB4MmM3ZDA0KDB4MTczKSxfMHgxYjE4YmM9dGhpc1snX2lzUHJpbWl0aXZlVHlwZSddKF8weDJlYTdhZSksXzB4NWM0ZmRkPXRoaXNbXzB4MmM3ZDA0KDB4MTgzKV0oXzB4MmVhN2FlKSxfMHgxMWExNWQ9XzB4MWIxOGJjfHxfMHg1YzRmZGQsXzB4NTAzYTJkPXt9LF8weDUzOWVkMz0weDAsXzB4NDEyZWRhPSEweDEsXzB4MTIyOWIyLF8weDEyOTc3Nj0vXigoWzEtOV17MX1bMC05XSopfDApJC87aWYoXzB4MWM3OTAwW18weDJjN2QwNCgweDIxMSldKXtpZihfMHgzOTdjN2Upe2lmKF8weDUxNmIyMD1fMHhkNDBhNGJbJ2xlbmd0aCddLF8weDUxNmIyMD5fMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MWI2KV0pe2ZvcihfMHgyNWI5MDI9MHgwLF8weDIxOGY1NT1fMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MWI2KV0sXzB4NWQ4YTE2PV8weDI1YjkwMjtfMHg1ZDhhMTY8XzB4MjE4ZjU1O18weDVkOGExNisrKV8weDczNTI0NFsncHVzaCddKF8weDM4ZTk0YVtfMHgyYzdkMDQoMHgxNTQpXShfMHg1ZDFlNGIsXzB4ZDQwYTRiLF8weDJlYTdhZSxfMHg1ZDhhMTYsXzB4MWM3OTAwKSk7XzB4NTE1MGIyW18weDJjN2QwNCgweDFjZCldPSEweDA7fWVsc2V7Zm9yKF8weDI1YjkwMj0weDAsXzB4MjE4ZjU1PV8weDUxNmIyMCxfMHg1ZDhhMTY9XzB4MjViOTAyO18weDVkOGExNjxfMHgyMThmNTU7XzB4NWQ4YTE2KyspXzB4NzM1MjQ0W18weDJjN2QwNCgweDE3MildKF8weDM4ZTk0YVtfMHgyYzdkMDQoMHgxNTQpXShfMHg1ZDFlNGIsXzB4ZDQwYTRiLF8weDJlYTdhZSxfMHg1ZDhhMTYsXzB4MWM3OTAwKSk7fV8weDFjNzkwMFsnYXV0b0V4cGFuZFByb3BlcnR5Q291bnQnXSs9XzB4NzM1MjQ0W18weDJjN2QwNCgweDFiYyldO31pZighKF8weDJlYTdhZT09PV8weDJjN2QwNCgweDE2NSl8fF8weDJlYTdhZT09PSd1bmRlZmluZWQnKSYmIV8weDFiMThiYyYmXzB4MmVhN2FlIT09XzB4MmM3ZDA0KDB4MjA0KSYmXzB4MmVhN2FlIT09J0J1ZmZlcicmJl8weDJlYTdhZSE9PV8weDJjN2QwNCgweDE4Mikpe3ZhciBfMHgzZWZhMmQ9XzB4NDE5NmQ3W18weDJjN2QwNCgweDE2MildfHxfMHgxYzc5MDBbJ3Byb3BzJ107aWYodGhpc1tfMHgyYzdkMDQoMHgyMjQpXShfMHhkNDBhNGIpPyhfMHg1ZDhhMTY9MHgwLF8weGQ0MGE0YlsnZm9yRWFjaCddKGZ1bmN0aW9uKF8weDIwY2Y1ZSl7dmFyIF8weDMwMTBhND1fMHgyYzdkMDQ7aWYoXzB4NTM5ZWQzKyssXzB4MWM3OTAwW18weDMwMTBhNCgweDE1NildKyssXzB4NTM5ZWQzPl8weDNlZmEyZCl7XzB4NDEyZWRhPSEweDA7cmV0dXJuO31pZighXzB4MWM3OTAwW18weDMwMTBhNCgweDE5MCldJiZfMHgxYzc5MDBbXzB4MzAxMGE0KDB4MWVmKV0mJl8weDFjNzkwMFtfMHgzMDEwYTQoMHgxNTYpXT5fMHgxYzc5MDBbJ2F1dG9FeHBhbmRMaW1pdCddKXtfMHg0MTJlZGE9ITB4MDtyZXR1cm47fV8weDczNTI0NFtfMHgzMDEwYTQoMHgxNzIpXShfMHgzOGU5NGFbXzB4MzAxMGE0KDB4MTU0KV0oXzB4NWQxZTRiLF8weGQ0MGE0YixfMHgzMDEwYTQoMHgxYzUpLF8weDVkOGExNisrLF8weDFjNzkwMCxmdW5jdGlvbihfMHg1MTFmNzgpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBfMHg1MTFmNzg7fTt9KF8weDIwY2Y1ZSkpKTt9KSk6dGhpc1tfMHgyYzdkMDQoMHgyMGQpXShfMHhkNDBhNGIpJiZfMHhkNDBhNGJbXzB4MmM3ZDA0KDB4MWRkKV0oZnVuY3Rpb24oXzB4MThjMzkwLF8weDQwMDRmNSl7dmFyIF8weDQzNmE0Mz1fMHgyYzdkMDQ7aWYoXzB4NTM5ZWQzKyssXzB4MWM3OTAwW18weDQzNmE0MygweDE1NildKyssXzB4NTM5ZWQzPl8weDNlZmEyZCl7XzB4NDEyZWRhPSEweDA7cmV0dXJuO31pZighXzB4MWM3OTAwWydpc0V4cHJlc3Npb25Ub0V2YWx1YXRlJ10mJl8weDFjNzkwMFtfMHg0MzZhNDMoMHgxZWYpXSYmXzB4MWM3OTAwW18weDQzNmE0MygweDE1NildPl8weDFjNzkwMFtfMHg0MzZhNDMoMHgyMTcpXSl7XzB4NDEyZWRhPSEweDA7cmV0dXJuO312YXIgXzB4NGE4ZjFjPV8weDQwMDRmNVtfMHg0MzZhNDMoMHgxYWYpXSgpO18weDRhOGYxY1tfMHg0MzZhNDMoMHgxYmMpXT4weDY0JiYoXzB4NGE4ZjFjPV8weDRhOGYxY1tfMHg0MzZhNDMoMHgxNTkpXSgweDAsMHg2NCkrJy4uLicpLF8weDczNTI0NFtfMHg0MzZhNDMoMHgxNzIpXShfMHgzOGU5NGFbJ19hZGRQcm9wZXJ0eSddKF8weDVkMWU0YixfMHhkNDBhNGIsXzB4NDM2YTQzKDB4MWRiKSxfMHg0YThmMWMsXzB4MWM3OTAwLGZ1bmN0aW9uKF8weDFiZGEzYyl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIF8weDFiZGEzYzt9O30oXzB4MThjMzkwKSkpO30pLCFfMHgyMjNlNzcpe3RyeXtmb3IoXzB4NGYxNWZlIGluIF8weGQ0MGE0YilpZighKF8weDM5N2M3ZSYmXzB4MTI5Nzc2W18weDJjN2QwNCgweDE5ZCldKF8weDRmMTVmZSkpJiYhdGhpc1snX2JsYWNrbGlzdGVkUHJvcGVydHknXShfMHhkNDBhNGIsXzB4NGYxNWZlLF8weDFjNzkwMCkpe2lmKF8weDUzOWVkMysrLF8weDFjNzkwMFtfMHgyYzdkMDQoMHgxNTYpXSsrLF8weDUzOWVkMz5fMHgzZWZhMmQpe18weDQxMmVkYT0hMHgwO2JyZWFrO31pZighXzB4MWM3OTAwW18weDJjN2QwNCgweDE5MCldJiZfMHgxYzc5MDBbJ2F1dG9FeHBhbmQnXSYmXzB4MWM3OTAwW18weDJjN2QwNCgweDE1NildPl8weDFjNzkwMFtfMHgyYzdkMDQoMHgyMTcpXSl7XzB4NDEyZWRhPSEweDA7YnJlYWs7fV8weDczNTI0NFtfMHgyYzdkMDQoMHgxNzIpXShfMHgzOGU5NGFbXzB4MmM3ZDA0KDB4MTRhKV0oXzB4NWQxZTRiLF8weDUwM2EyZCxfMHhkNDBhNGIsXzB4MmVhN2FlLF8weDRmMTVmZSxfMHgxYzc5MDApKTt9fWNhdGNoe31pZihfMHg1MDNhMmRbXzB4MmM3ZDA0KDB4MWI5KV09ITB4MCxfMHgyZWYzNGImJihfMHg1MDNhMmRbXzB4MmM3ZDA0KDB4MWU1KV09ITB4MCksIV8weDQxMmVkYSl7dmFyIF8weDNlYWJiOT1bXVtfMHgyYzdkMDQoMHgxOGEpXSh0aGlzWydfZ2V0T3duUHJvcGVydHlOYW1lcyddKF8weGQ0MGE0YikpW18weDJjN2QwNCgweDE4YSldKHRoaXNbXzB4MmM3ZDA0KDB4MWZjKV0oXzB4ZDQwYTRiKSk7Zm9yKF8weDVkOGExNj0weDAsXzB4NTE2YjIwPV8weDNlYWJiOVtfMHgyYzdkMDQoMHgxYmMpXTtfMHg1ZDhhMTY8XzB4NTE2YjIwO18weDVkOGExNisrKWlmKF8weDRmMTVmZT1fMHgzZWFiYjlbXzB4NWQ4YTE2XSwhKF8weDM5N2M3ZSYmXzB4MTI5Nzc2W18weDJjN2QwNCgweDE5ZCldKF8weDRmMTVmZVsndG9TdHJpbmcnXSgpKSkmJiF0aGlzWydfYmxhY2tsaXN0ZWRQcm9wZXJ0eSddKF8weGQ0MGE0YixfMHg0ZjE1ZmUsXzB4MWM3OTAwKSYmIV8weDUwM2EyZFsnX3BfJytfMHg0ZjE1ZmVbXzB4MmM3ZDA0KDB4MWFmKV0oKV0pe2lmKF8weDUzOWVkMysrLF8weDFjNzkwMFtfMHgyYzdkMDQoMHgxNTYpXSsrLF8weDUzOWVkMz5fMHgzZWZhMmQpe18weDQxMmVkYT0hMHgwO2JyZWFrO31pZighXzB4MWM3OTAwW18weDJjN2QwNCgweDE5MCldJiZfMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MWVmKV0mJl8weDFjNzkwMFtfMHgyYzdkMDQoMHgxNTYpXT5fMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MjE3KV0pe18weDQxMmVkYT0hMHgwO2JyZWFrO31fMHg3MzUyNDRbXzB4MmM3ZDA0KDB4MTcyKV0oXzB4MzhlOTRhW18weDJjN2QwNCgweDE0YSldKF8weDVkMWU0YixfMHg1MDNhMmQsXzB4ZDQwYTRiLF8weDJlYTdhZSxfMHg0ZjE1ZmUsXzB4MWM3OTAwKSk7fX19fX1pZihfMHg1MTUwYjJbXzB4MmM3ZDA0KDB4MWFjKV09XzB4MmVhN2FlLF8weDExYTE1ZD8oXzB4NTE1MGIyWyd2YWx1ZSddPV8weGQ0MGE0YltfMHgyYzdkMDQoMHgxYzYpXSgpLHRoaXNbXzB4MmM3ZDA0KDB4MTQ1KV0oXzB4MmVhN2FlLF8weDUxNTBiMixfMHgxYzc5MDAsXzB4NDE5NmQ3KSk6XzB4MmVhN2FlPT09XzB4MmM3ZDA0KDB4MTRlKT9fMHg1MTUwYjJbJ3ZhbHVlJ109dGhpc1tfMHgyYzdkMDQoMHgxZGMpXVsnY2FsbCddKF8weGQ0MGE0Yik6XzB4MmVhN2FlPT09XzB4MmM3ZDA0KDB4MTgyKT9fMHg1MTUwYjJbXzB4MmM3ZDA0KDB4MWFhKV09XzB4ZDQwYTRiW18weDJjN2QwNCgweDFhZildKCk6XzB4MmVhN2FlPT09XzB4MmM3ZDA0KDB4MjA1KT9fMHg1MTUwYjJbJ3ZhbHVlJ109dGhpc1tfMHgyYzdkMDQoMHgyMWIpXVtfMHgyYzdkMDQoMHgxNzEpXShfMHhkNDBhNGIpOl8weDJlYTdhZT09PV8weDJjN2QwNCgweDE1ZCkmJnRoaXNbXzB4MmM3ZDA0KDB4MWZlKV0/XzB4NTE1MGIyW18weDJjN2QwNCgweDFhYSldPXRoaXNbXzB4MmM3ZDA0KDB4MWZlKV1bXzB4MmM3ZDA0KDB4MTk1KV1bJ3RvU3RyaW5nJ11bXzB4MmM3ZDA0KDB4MTcxKV0oXzB4ZDQwYTRiKTohXzB4MWM3OTAwW18weDJjN2QwNCgweDIxMSldJiYhKF8weDJlYTdhZT09PV8weDJjN2QwNCgweDE2NSl8fF8weDJlYTdhZT09PV8weDJjN2QwNCgweDFlYikpJiYoZGVsZXRlIF8weDUxNTBiMlsndmFsdWUnXSxfMHg1MTUwYjJbXzB4MmM3ZDA0KDB4MTk5KV09ITB4MCksXzB4NDEyZWRhJiYoXzB4NTE1MGIyW18weDJjN2QwNCgweDE4MCldPSEweDApLF8weDEyMjliMj1fMHgxYzc5MDBbXzB4MmM3ZDA0KDB4MjE0KV1bXzB4MmM3ZDA0KDB4MWE0KV0sXzB4MWM3OTAwW18weDJjN2QwNCgweDIxNCldW18weDJjN2QwNCgweDFhNCldPV8weDUxNTBiMix0aGlzW18weDJjN2QwNCgweDE5NCldKF8weDUxNTBiMixfMHgxYzc5MDApLF8weDczNTI0NFsnbGVuZ3RoJ10pe2ZvcihfMHg1ZDhhMTY9MHgwLF8weDUxNmIyMD1fMHg3MzUyNDRbXzB4MmM3ZDA0KDB4MWJjKV07XzB4NWQ4YTE2PF8weDUxNmIyMDtfMHg1ZDhhMTYrKylfMHg3MzUyNDRbXzB4NWQ4YTE2XShfMHg1ZDhhMTYpO31fMHg1ZDFlNGJbXzB4MmM3ZDA0KDB4MWJjKV0mJihfMHg1MTUwYjJbXzB4MmM3ZDA0KDB4MTYyKV09XzB4NWQxZTRiKTt9Y2F0Y2goXzB4OGM5ODk0KXtfMHg4MDFlNDUoXzB4OGM5ODk0LF8weDUxNTBiMixfMHgxYzc5MDApO31yZXR1cm4gdGhpc1tfMHgyYzdkMDQoMHgxNjkpXShfMHhkNDBhNGIsXzB4NTE1MGIyKSx0aGlzW18weDJjN2QwNCgweDFjMCldKF8weDUxNTBiMixfMHgxYzc5MDApLF8weDFjNzkwMFtfMHgyYzdkMDQoMHgyMTQpXVtfMHgyYzdkMDQoMHgxYTQpXT1fMHgxMjI5YjIsXzB4MWM3OTAwW18weDJjN2QwNCgweDE2ZCldLS0sXzB4MWM3OTAwWydhdXRvRXhwYW5kJ109XzB4ODc5ZDk4LF8weDFjNzkwMFtfMHgyYzdkMDQoMHgxZWYpXSYmXzB4MWM3OTAwW18weDJjN2QwNCgweDFhNildWydwb3AnXSgpLF8weDUxNTBiMjt9W18weDEyNzczNSgweDFmYyldKF8weDJjNTdlMil7dmFyIF8weDUwN2Q3Nz1fMHgxMjc3MzU7cmV0dXJuIE9iamVjdFtfMHg1MDdkNzcoMHgyMGEpXT9PYmplY3RbXzB4NTA3ZDc3KDB4MjBhKV0oXzB4MmM1N2UyKTpbXTt9W18weDEyNzczNSgweDIyNCldKF8weDFhZDFmMil7dmFyIF8weDNiMzM3OT1fMHgxMjc3MzU7cmV0dXJuISEoXzB4MWFkMWYyJiZfMHg0MjZkNWZbXzB4M2IzMzc5KDB4MWM1KV0mJnRoaXNbXzB4M2IzMzc5KDB4MTk2KV0oXzB4MWFkMWYyKT09PV8weDNiMzM3OSgweDE1ZSkmJl8weDFhZDFmMlsnZm9yRWFjaCddKTt9W18weDEyNzczNSgweDFjNCldKF8weDFhMGEwZixfMHg0YTgwYjgsXzB4NGY2NGZlKXt2YXIgXzB4NWI4OTc1PV8weDEyNzczNTtyZXR1cm4gXzB4NGY2NGZlWydub0Z1bmN0aW9ucyddP3R5cGVvZiBfMHgxYTBhMGZbXzB4NGE4MGI4XT09XzB4NWI4OTc1KDB4MTczKTohMHgxO31bXzB4MTI3NzM1KDB4MWVjKV0oXzB4NTI5M2UzKXt2YXIgXzB4MTE3MjhhPV8weDEyNzczNSxfMHgxNjEyMzc9Jyc7cmV0dXJuIF8weDE2MTIzNz10eXBlb2YgXzB4NTI5M2UzLF8weDE2MTIzNz09PV8weDExNzI4YSgweDE2Nik/dGhpc1tfMHgxMTcyOGEoMHgxOTYpXShfMHg1MjkzZTMpPT09XzB4MTE3MjhhKDB4MTYwKT9fMHgxNjEyMzc9XzB4MTE3MjhhKDB4MWU2KTp0aGlzW18weDExNzI4YSgweDE5NildKF8weDUyOTNlMyk9PT0nW29iamVjdFxcXFx4MjBEYXRlXSc/XzB4MTYxMjM3PSdkYXRlJzp0aGlzW18weDExNzI4YSgweDE5NildKF8weDUyOTNlMyk9PT0nW29iamVjdFxcXFx4MjBCaWdJbnRdJz9fMHgxNjEyMzc9XzB4MTE3MjhhKDB4MTgyKTpfMHg1MjkzZTM9PT1udWxsP18weDE2MTIzNz1fMHgxMTcyOGEoMHgxNjUpOl8weDUyOTNlM1tfMHgxMTcyOGEoMHgxYTMpXSYmKF8weDE2MTIzNz1fMHg1MjkzZTNbXzB4MTE3MjhhKDB4MWEzKV1bXzB4MTE3MjhhKDB4MWM5KV18fF8weDE2MTIzNyk6XzB4MTYxMjM3PT09XzB4MTE3MjhhKDB4MWViKSYmdGhpc1tfMHgxMTcyOGEoMHgyMjEpXSYmXzB4NTI5M2UzIGluc3RhbmNlb2YgdGhpc1tfMHgxMTcyOGEoMHgyMjEpXSYmKF8weDE2MTIzNz1fMHgxMTcyOGEoMHgxNGMpKSxfMHgxNjEyMzc7fVtfMHgxMjc3MzUoMHgxOTYpXShfMHgzZDEwNjQpe3ZhciBfMHg0MTNkMWY9XzB4MTI3NzM1O3JldHVybiBPYmplY3RbXzB4NDEzZDFmKDB4MTk1KV1bXzB4NDEzZDFmKDB4MWFmKV1bJ2NhbGwnXShfMHgzZDEwNjQpO31bXzB4MTI3NzM1KDB4MWMzKV0oXzB4YWZiNWM0KXt2YXIgXzB4MTA1NTBkPV8weDEyNzczNTtyZXR1cm4gXzB4YWZiNWM0PT09XzB4MTA1NTBkKDB4MWU5KXx8XzB4YWZiNWM0PT09J3N0cmluZyd8fF8weGFmYjVjND09PV8weDEwNTUwZCgweDE3ZSk7fVsnX2lzUHJpbWl0aXZlV3JhcHBlclR5cGUnXShfMHg0MjkwNjIpe3ZhciBfMHg0YjEyNTg9XzB4MTI3NzM1O3JldHVybiBfMHg0MjkwNjI9PT0nQm9vbGVhbid8fF8weDQyOTA2Mj09PV8weDRiMTI1OCgweDIwNCl8fF8weDQyOTA2Mj09PSdOdW1iZXInO31bXzB4MTI3NzM1KDB4MTU0KV0oXzB4MjkxMzRlLF8weDQyYWMzNSxfMHgzOWQ4OTAsXzB4MTcyNTFjLF8weDQ2ZGJjYSxfMHg5ODNmMyl7dmFyIF8weDVkZDY1YT10aGlzO3JldHVybiBmdW5jdGlvbihfMHg0NGViNjkpe3ZhciBfMHgyYmE4ODg9XzB4MzNiMixfMHgyZjY2YWM9XzB4NDZkYmNhW18weDJiYTg4OCgweDIxNCldW18weDJiYTg4OCgweDFhNCldLF8weDQxOWNhZj1fMHg0NmRiY2FbXzB4MmJhODg4KDB4MjE0KV1bXzB4MmJhODg4KDB4MTQ5KV0sXzB4MzI3OTg3PV8weDQ2ZGJjYVtfMHgyYmE4ODgoMHgyMTQpXVtfMHgyYmE4ODgoMHgxZjcpXTtfMHg0NmRiY2FbXzB4MmJhODg4KDB4MjE0KV1bXzB4MmJhODg4KDB4MWY3KV09XzB4MmY2NmFjLF8weDQ2ZGJjYVsnbm9kZSddW18weDJiYTg4OCgweDE0OSldPXR5cGVvZiBfMHgxNzI1MWM9PSdudW1iZXInP18weDE3MjUxYzpfMHg0NGViNjksXzB4MjkxMzRlWydwdXNoJ10oXzB4NWRkNjVhWydfcHJvcGVydHknXShfMHg0MmFjMzUsXzB4MzlkODkwLF8weDE3MjUxYyxfMHg0NmRiY2EsXzB4OTgzZjMpKSxfMHg0NmRiY2FbJ25vZGUnXVsncGFyZW50J109XzB4MzI3OTg3LF8weDQ2ZGJjYVtfMHgyYmE4ODgoMHgyMTQpXVtfMHgyYmE4ODgoMHgxNDkpXT1fMHg0MTljYWY7fTt9W18weDEyNzczNSgweDE0YSldKF8weDEwNzlmMCxfMHg0MmZmM2MsXzB4MjhkY2ZjLF8weDE2ODcyZixfMHg0NTllMGYsXzB4M2ZjYTYyLF8weDM1MDY0Myl7dmFyIF8weDcyOGRiZj1fMHgxMjc3MzUsXzB4NDFmMWE3PXRoaXM7cmV0dXJuIF8weDQyZmYzY1snX3BfJytfMHg0NTllMGZbXzB4NzI4ZGJmKDB4MWFmKV0oKV09ITB4MCxmdW5jdGlvbihfMHgzNjc3YWUpe3ZhciBfMHhlY2ZlZDg9XzB4NzI4ZGJmLF8weDRlOWJmYT1fMHgzZmNhNjJbXzB4ZWNmZWQ4KDB4MjE0KV1bXzB4ZWNmZWQ4KDB4MWE0KV0sXzB4MjljNTllPV8weDNmY2E2MltfMHhlY2ZlZDgoMHgyMTQpXVtfMHhlY2ZlZDgoMHgxNDkpXSxfMHgxYTcwZWQ9XzB4M2ZjYTYyWydub2RlJ11bXzB4ZWNmZWQ4KDB4MWY3KV07XzB4M2ZjYTYyWydub2RlJ11bXzB4ZWNmZWQ4KDB4MWY3KV09XzB4NGU5YmZhLF8weDNmY2E2Mlsnbm9kZSddW18weGVjZmVkOCgweDE0OSldPV8weDM2NzdhZSxfMHgxMDc5ZjBbXzB4ZWNmZWQ4KDB4MTcyKV0oXzB4NDFmMWE3W18weGVjZmVkOCgweDFjMSldKF8weDI4ZGNmYyxfMHgxNjg3MmYsXzB4NDU5ZTBmLF8weDNmY2E2MixfMHgzNTA2NDMpKSxfMHgzZmNhNjJbXzB4ZWNmZWQ4KDB4MjE0KV1bXzB4ZWNmZWQ4KDB4MWY3KV09XzB4MWE3MGVkLF8weDNmY2E2MltfMHhlY2ZlZDgoMHgyMTQpXVsnaW5kZXgnXT1fMHgyOWM1OWU7fTt9W18weDEyNzczNSgweDFjMSldKF8weDRiNmIzOSxfMHg0NTQyMzksXzB4NDIwY2ExLF8weDFkNmRkNixfMHhmZGMxZjIpe3ZhciBfMHg0OWY1YTQ9XzB4MTI3NzM1LF8weDIwMTkwNz10aGlzO18weGZkYzFmMnx8KF8weGZkYzFmMj1mdW5jdGlvbihfMHgyZWRhMTgsXzB4M2ZkODg4KXtyZXR1cm4gXzB4MmVkYTE4W18weDNmZDg4OF07fSk7dmFyIF8weDE5OTRhYz1fMHg0MjBjYTFbJ3RvU3RyaW5nJ10oKSxfMHgzMTE1YmU9XzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDIxMCldfHx7fSxfMHg1NzZmNzc9XzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDIxMSldLF8weDI4MDZiYT1fMHgxZDZkZDZbXzB4NDlmNWE0KDB4MTkwKV07dHJ5e3ZhciBfMHg0YjI4Zjg9dGhpc1tfMHg0OWY1YTQoMHgyMGQpXShfMHg0YjZiMzkpLF8weDNiMjM4ND1fMHgxOTk0YWM7XzB4NGIyOGY4JiZfMHgzYjIzODRbMHgwXT09PSdcXFxceDI3JyYmKF8weDNiMjM4ND1fMHgzYjIzODRbJ3N1YnN0ciddKDB4MSxfMHgzYjIzODRbXzB4NDlmNWE0KDB4MWJjKV0tMHgyKSk7dmFyIF8weDMzY2I1Yj1fMHgxZDZkZDZbXzB4NDlmNWE0KDB4MjEwKV09XzB4MzExNWJlW18weDQ5ZjVhNCgweDE1ZikrXzB4M2IyMzg0XTtfMHgzM2NiNWImJihfMHgxZDZkZDZbXzB4NDlmNWE0KDB4MjExKV09XzB4MWQ2ZGQ2WydkZXB0aCddKzB4MSksXzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDE5MCldPSEhXzB4MzNjYjViO3ZhciBfMHg1YzI2Yjk9dHlwZW9mIF8weDQyMGNhMT09XzB4NDlmNWE0KDB4MTVkKSxfMHgzN2Y4ZjE9eyduYW1lJzpfMHg1YzI2Yjl8fF8weDRiMjhmOD9fMHgxOTk0YWM6dGhpc1tfMHg0OWY1YTQoMHgxNTMpXShfMHgxOTk0YWMpfTtpZihfMHg1YzI2YjkmJihfMHgzN2Y4ZjFbJ3N5bWJvbCddPSEweDApLCEoXzB4NDU0MjM5PT09J2FycmF5J3x8XzB4NDU0MjM5PT09XzB4NDlmNWE0KDB4MWI4KSkpe3ZhciBfMHg4ZjI1ZDE9dGhpc1tfMHg0OWY1YTQoMHgxNjcpXShfMHg0YjZiMzksXzB4NDIwY2ExKTtpZihfMHg4ZjI1ZDEmJihfMHg4ZjI1ZDFbXzB4NDlmNWE0KDB4MWVlKV0mJihfMHgzN2Y4ZjFbXzB4NDlmNWE0KDB4MTQ3KV09ITB4MCksXzB4OGYyNWQxW18weDQ5ZjVhNCgweDFjNyldJiYhXzB4MzNjYjViJiYhXzB4MWQ2ZGQ2WydyZXNvbHZlR2V0dGVycyddKSlyZXR1cm4gXzB4MzdmOGYxW18weDQ5ZjVhNCgweDFmMSldPSEweDAsdGhpc1tfMHg0OWY1YTQoMHgxZjUpXShfMHgzN2Y4ZjEsXzB4MWQ2ZGQ2KSxfMHgzN2Y4ZjE7fXZhciBfMHgyY2Q0N2Q7dHJ5e18weDJjZDQ3ZD1fMHhmZGMxZjIoXzB4NGI2YjM5LF8weDQyMGNhMSk7fWNhdGNoKF8weDEyYTAyYyl7cmV0dXJuIF8weDM3ZjhmMT17J25hbWUnOl8weDE5OTRhYywndHlwZSc6XzB4NDlmNWE0KDB4MjFkKSwnZXJyb3InOl8weDEyYTAyY1tfMHg0OWY1YTQoMHgxYTEpXX0sdGhpc1tfMHg0OWY1YTQoMHgxZjUpXShfMHgzN2Y4ZjEsXzB4MWQ2ZGQ2KSxfMHgzN2Y4ZjE7fXZhciBfMHg1OTJiMzQ9dGhpc1tfMHg0OWY1YTQoMHgxZWMpXShfMHgyY2Q0N2QpLF8weDNjYzY5MD10aGlzWydfaXNQcmltaXRpdmVUeXBlJ10oXzB4NTkyYjM0KTtpZihfMHgzN2Y4ZjFbXzB4NDlmNWE0KDB4MWFjKV09XzB4NTkyYjM0LF8weDNjYzY5MCl0aGlzW18weDQ5ZjVhNCgweDFmNSldKF8weDM3ZjhmMSxfMHgxZDZkZDYsXzB4MmNkNDdkLGZ1bmN0aW9uKCl7dmFyIF8weDU2ZjQ3YT1fMHg0OWY1YTQ7XzB4MzdmOGYxW18weDU2ZjQ3YSgweDFhYSldPV8weDJjZDQ3ZFtfMHg1NmY0N2EoMHgxYzYpXSgpLCFfMHgzM2NiNWImJl8weDIwMTkwN1tfMHg1NmY0N2EoMHgxNDUpXShfMHg1OTJiMzQsXzB4MzdmOGYxLF8weDFkNmRkNix7fSk7fSk7ZWxzZXt2YXIgXzB4NGZjNzkyPV8weDFkNmRkNltfMHg0OWY1YTQoMHgxZWYpXSYmXzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDE2ZCldPF8weDFkNmRkNltfMHg0OWY1YTQoMHgxNzkpXSYmXzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDFhNildWydpbmRleE9mJ10oXzB4MmNkNDdkKTwweDAmJl8weDU5MmIzNCE9PV8weDQ5ZjVhNCgweDE3MykmJl8weDFkNmRkNltfMHg0OWY1YTQoMHgxNTYpXTxfMHgxZDZkZDZbJ2F1dG9FeHBhbmRMaW1pdCddO18weDRmYzc5Mnx8XzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDE2ZCldPF8weDU3NmY3N3x8XzB4MzNjYjViPyh0aGlzW18weDQ5ZjVhNCgweDIxZSldKF8weDM3ZjhmMSxfMHgyY2Q0N2QsXzB4MWQ2ZGQ2LF8weDMzY2I1Ynx8e30pLHRoaXNbJ19hZGRpdGlvbmFsTWV0YWRhdGEnXShfMHgyY2Q0N2QsXzB4MzdmOGYxKSk6dGhpc1tfMHg0OWY1YTQoMHgxZjUpXShfMHgzN2Y4ZjEsXzB4MWQ2ZGQ2LF8weDJjZDQ3ZCxmdW5jdGlvbigpe3ZhciBfMHgxYjBiZTE9XzB4NDlmNWE0O18weDU5MmIzND09PV8weDFiMGJlMSgweDE2NSl8fF8weDU5MmIzND09PV8weDFiMGJlMSgweDFlYil8fChkZWxldGUgXzB4MzdmOGYxWyd2YWx1ZSddLF8weDM3ZjhmMVtfMHgxYjBiZTEoMHgxOTkpXT0hMHgwKTt9KTt9cmV0dXJuIF8weDM3ZjhmMTt9ZmluYWxseXtfMHgxZDZkZDZbXzB4NDlmNWE0KDB4MjEwKV09XzB4MzExNWJlLF8weDFkNmRkNltfMHg0OWY1YTQoMHgyMTEpXT1fMHg1NzZmNzcsXzB4MWQ2ZGQ2W18weDQ5ZjVhNCgweDE5MCldPV8weDI4MDZiYTt9fVtfMHgxMjc3MzUoMHgxNDUpXShfMHg0NmY1ZDgsXzB4OTg5Mjk0LF8weDJlMzE2YixfMHgyMzI3MDcpe3ZhciBfMHgyMTEwNDU9XzB4MTI3NzM1LF8weDQ0ODc3OD1fMHgyMzI3MDdbXzB4MjExMDQ1KDB4MWE1KV18fF8weDJlMzE2Ylsnc3RyTGVuZ3RoJ107aWYoKF8weDQ2ZjVkOD09PV8weDIxMTA0NSgweDE2NCl8fF8weDQ2ZjVkOD09PV8weDIxMTA0NSgweDIwNCkpJiZfMHg5ODkyOTRbXzB4MjExMDQ1KDB4MWFhKV0pe2xldCBfMHhlYjNiYjU9XzB4OTg5Mjk0W18weDIxMTA0NSgweDFhYSldWydsZW5ndGgnXTtfMHgyZTMxNmJbXzB4MjExMDQ1KDB4MThkKV0rPV8weGViM2JiNSxfMHgyZTMxNmJbXzB4MjExMDQ1KDB4MThkKV0+XzB4MmUzMTZiW18weDIxMTA0NSgweDE3NCldPyhfMHg5ODkyOTRbXzB4MjExMDQ1KDB4MTk5KV09JycsZGVsZXRlIF8weDk4OTI5NFsndmFsdWUnXSk6XzB4ZWIzYmI1Pl8weDQ0ODc3OCYmKF8weDk4OTI5NFtfMHgyMTEwNDUoMHgxOTkpXT1fMHg5ODkyOTRbXzB4MjExMDQ1KDB4MWFhKV1bJ3N1YnN0ciddKDB4MCxfMHg0NDg3NzgpLGRlbGV0ZSBfMHg5ODkyOTRbJ3ZhbHVlJ10pO319W18weDEyNzczNSgweDIwZCldKF8weDI4YjdkMCl7dmFyIF8weDhhMTg4Nj1fMHgxMjc3MzU7cmV0dXJuISEoXzB4MjhiN2QwJiZfMHg0MjZkNWZbJ01hcCddJiZ0aGlzW18weDhhMTg4NigweDE5NildKF8weDI4YjdkMCk9PT1fMHg4YTE4ODYoMHgxYmQpJiZfMHgyOGI3ZDBbXzB4OGExODg2KDB4MWRkKV0pO31bXzB4MTI3NzM1KDB4MTUzKV0oXzB4MWUxMGNjKXt2YXIgXzB4NGEyZDgwPV8weDEyNzczNTtpZihfMHgxZTEwY2NbXzB4NGEyZDgwKDB4MjA4KV0oL15cXFxcZCskLykpcmV0dXJuIF8weDFlMTBjYzt2YXIgXzB4MzQyZWNhO3RyeXtfMHgzNDJlY2E9SlNPTltfMHg0YTJkODAoMHgxZmEpXSgnJytfMHgxZTEwY2MpO31jYXRjaHtfMHgzNDJlY2E9J1xcXFx4MjInK3RoaXNbXzB4NGEyZDgwKDB4MTk2KV0oXzB4MWUxMGNjKSsnXFxcXHgyMic7fXJldHVybiBfMHgzNDJlY2FbXzB4NGEyZDgwKDB4MjA4KV0oL15cXFwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXFxcIiQvKT9fMHgzNDJlY2E9XzB4MzQyZWNhW18weDRhMmQ4MCgweDFhMCldKDB4MSxfMHgzNDJlY2FbXzB4NGEyZDgwKDB4MWJjKV0tMHgyKTpfMHgzNDJlY2E9XzB4MzQyZWNhW18weDRhMmQ4MCgweDE1MCldKC8nL2csJ1xcXFx4NWNcXFxceDI3JylbXzB4NGEyZDgwKDB4MTUwKV0oL1xcXFxcXFxcXFxcIi9nLCdcXFxceDIyJylbXzB4NGEyZDgwKDB4MTUwKV0oLyheXFxcInxcXFwiJCkvZywnXFxcXHgyNycpLF8weDM0MmVjYTt9W18weDEyNzczNSgweDFmNSldKF8weDMxMTE0MSxfMHg0ZmU4NzQsXzB4NGI0NTZlLF8weDJhMWY4MCl7dmFyIF8weDNjMTY1Nz1fMHgxMjc3MzU7dGhpc1tfMHgzYzE2NTcoMHgxOTQpXShfMHgzMTExNDEsXzB4NGZlODc0KSxfMHgyYTFmODAmJl8weDJhMWY4MCgpLHRoaXNbXzB4M2MxNjU3KDB4MTY5KV0oXzB4NGI0NTZlLF8weDMxMTE0MSksdGhpc1snX3RyZWVOb2RlUHJvcGVydGllc0FmdGVyRnVsbFZhbHVlJ10oXzB4MzExMTQxLF8weDRmZTg3NCk7fVtfMHgxMjc3MzUoMHgxOTQpXShfMHgzZmQ3MGIsXzB4MmQ4YWY5KXt2YXIgXzB4MzZkY2Y0PV8weDEyNzczNTt0aGlzWydfc2V0Tm9kZUlkJ10oXzB4M2ZkNzBiLF8weDJkOGFmOSksdGhpc1snX3NldE5vZGVRdWVyeVBhdGgnXShfMHgzZmQ3MGIsXzB4MmQ4YWY5KSx0aGlzW18weDM2ZGNmNCgweDE3ZCldKF8weDNmZDcwYixfMHgyZDhhZjkpLHRoaXNbXzB4MzZkY2Y0KDB4MWFlKV0oXzB4M2ZkNzBiLF8weDJkOGFmOSk7fVsnX3NldE5vZGVJZCddKF8weDRlMzg1MixfMHg1OTA3ZTgpe31bJ19zZXROb2RlUXVlcnlQYXRoJ10oXzB4MWNjOGI0LF8weDI2ODE5Yil7fVsnX3NldE5vZGVMYWJlbCddKF8weDU2NWNjZixfMHgxOTlhNjQpe31bXzB4MTI3NzM1KDB4MTRmKV0oXzB4MTIwYzYzKXt2YXIgXzB4MjcwOGUyPV8weDEyNzczNTtyZXR1cm4gXzB4MTIwYzYzPT09dGhpc1tfMHgyNzA4ZTIoMHgyMDEpXTt9W18weDEyNzczNSgweDFjMCldKF8weDI2NTNjNyxfMHgyZmUyNjcpe3ZhciBfMHgyZTQxYjQ9XzB4MTI3NzM1O3RoaXNbXzB4MmU0MWI0KDB4MWYwKV0oXzB4MjY1M2M3LF8weDJmZTI2NyksdGhpc1tfMHgyZTQxYjQoMHgxZDQpXShfMHgyNjUzYzcpLF8weDJmZTI2N1tfMHgyZTQxYjQoMHgxNGQpXSYmdGhpc1tfMHgyZTQxYjQoMHgxODUpXShfMHgyNjUzYzcpLHRoaXNbXzB4MmU0MWI0KDB4MWUwKV0oXzB4MjY1M2M3LF8weDJmZTI2NyksdGhpc1tfMHgyZTQxYjQoMHgxOTEpXShfMHgyNjUzYzcsXzB4MmZlMjY3KSx0aGlzW18weDJlNDFiNCgweDIxOSldKF8weDI2NTNjNyk7fVsnX2FkZGl0aW9uYWxNZXRhZGF0YSddKF8weGFhMTQwMixfMHgxZDBlNjkpe3ZhciBfMHgyYjZkYTg9XzB4MTI3NzM1O2xldCBfMHg1NzkwZDU7dHJ5e18weDQyNmQ1ZltfMHgyYjZkYTgoMHgxZGYpXSYmKF8weDU3OTBkNT1fMHg0MjZkNWZbXzB4MmI2ZGE4KDB4MWRmKV1bJ2Vycm9yJ10sXzB4NDI2ZDVmWydjb25zb2xlJ11bXzB4MmI2ZGE4KDB4MjBjKV09ZnVuY3Rpb24oKXt9KSxfMHhhYTE0MDImJnR5cGVvZiBfMHhhYTE0MDJbXzB4MmI2ZGE4KDB4MWJjKV09PV8weDJiNmRhOCgweDE3ZSkmJihfMHgxZDBlNjlbXzB4MmI2ZGE4KDB4MWJjKV09XzB4YWExNDAyWydsZW5ndGgnXSk7fWNhdGNoe31maW5hbGx5e18weDU3OTBkNSYmKF8weDQyNmQ1ZltfMHgyYjZkYTgoMHgxZGYpXVtfMHgyYjZkYTgoMHgyMGMpXT1fMHg1NzkwZDUpO31pZihfMHgxZDBlNjlbJ3R5cGUnXT09PV8weDJiNmRhOCgweDE3ZSl8fF8weDFkMGU2OVtfMHgyYjZkYTgoMHgxYWMpXT09PSdOdW1iZXInKXtpZihpc05hTihfMHgxZDBlNjlbXzB4MmI2ZGE4KDB4MWFhKV0pKV8weDFkMGU2OVsnbmFuJ109ITB4MCxkZWxldGUgXzB4MWQwZTY5W18weDJiNmRhOCgweDFhYSldO2Vsc2Ugc3dpdGNoKF8weDFkMGU2OVtfMHgyYjZkYTgoMHgxYWEpXSl7Y2FzZSBOdW1iZXJbXzB4MmI2ZGE4KDB4MTdjKV06XzB4MWQwZTY5W18weDJiNmRhOCgweDFkOSldPSEweDAsZGVsZXRlIF8weDFkMGU2OVtfMHgyYjZkYTgoMHgxYWEpXTticmVhaztjYXNlIE51bWJlcltfMHgyYjZkYTgoMHgxYTIpXTpfMHgxZDBlNjlbXzB4MmI2ZGE4KDB4MWNiKV09ITB4MCxkZWxldGUgXzB4MWQwZTY5Wyd2YWx1ZSddO2JyZWFrO2Nhc2UgMHgwOnRoaXNbJ19pc05lZ2F0aXZlWmVybyddKF8weDFkMGU2OVsndmFsdWUnXSkmJihfMHgxZDBlNjlbJ25lZ2F0aXZlWmVybyddPSEweDApO2JyZWFrO319ZWxzZSBfMHgxZDBlNjlbXzB4MmI2ZGE4KDB4MWFjKV09PT1fMHgyYjZkYTgoMHgxNzMpJiZ0eXBlb2YgXzB4YWExNDAyW18weDJiNmRhOCgweDFjOSldPT0nc3RyaW5nJyYmXzB4YWExNDAyW18weDJiNmRhOCgweDFjOSldJiZfMHgxZDBlNjlbJ25hbWUnXSYmXzB4YWExNDAyW18weDJiNmRhOCgweDFjOSldIT09XzB4MWQwZTY5W18weDJiNmRhOCgweDFjOSldJiYoXzB4MWQwZTY5WydmdW5jTmFtZSddPV8weGFhMTQwMltfMHgyYjZkYTgoMHgxYzkpXSk7fVtfMHgxMjc3MzUoMHgxYmUpXShfMHg1YmY3OWYpe3ZhciBfMHgxZTBiZjI9XzB4MTI3NzM1O3JldHVybiAweDEvXzB4NWJmNzlmPT09TnVtYmVyW18weDFlMGJmMigweDFhMildO31bXzB4MTI3NzM1KDB4MTg1KV0oXzB4OWVjNDYzKXt2YXIgXzB4MjQ0NjQyPV8weDEyNzczNTshXzB4OWVjNDYzWydwcm9wcyddfHwhXzB4OWVjNDYzW18weDI0NDY0MigweDE2MildW18weDI0NDY0MigweDFiYyldfHxfMHg5ZWM0NjNbXzB4MjQ0NjQyKDB4MWFjKV09PT1fMHgyNDQ2NDIoMHgxZTYpfHxfMHg5ZWM0NjNbXzB4MjQ0NjQyKDB4MWFjKV09PT1fMHgyNDQ2NDIoMHgxZGIpfHxfMHg5ZWM0NjNbJ3R5cGUnXT09PV8weDI0NDY0MigweDFjNSl8fF8weDllYzQ2M1tfMHgyNDQ2NDIoMHgxNjIpXVsnc29ydCddKGZ1bmN0aW9uKF8weDRlYTllMCxfMHgzNWMzMjMpe3ZhciBfMHg0YjVjYjI9XzB4MjQ0NjQyLF8weDIwMzZmMz1fMHg0ZWE5ZTBbXzB4NGI1Y2IyKDB4MWM5KV1bXzB4NGI1Y2IyKDB4MjAyKV0oKSxfMHhiZjBlNzU9XzB4MzVjMzIzW18weDRiNWNiMigweDFjOSldW18weDRiNWNiMigweDIwMildKCk7cmV0dXJuIF8weDIwMzZmMzxfMHhiZjBlNzU/LTB4MTpfMHgyMDM2ZjM+XzB4YmYwZTc1PzB4MToweDA7fSk7fVsnX2FkZEZ1bmN0aW9uc05vZGUnXShfMHg1NzE0MTEsXzB4NTExNjZmKXt2YXIgXzB4MTQ0Mzg0PV8weDEyNzczNTtpZighKF8weDUxMTY2ZltfMHgxNDQzODQoMHgxODcpXXx8IV8weDU3MTQxMVtfMHgxNDQzODQoMHgxNjIpXXx8IV8weDU3MTQxMVtfMHgxNDQzODQoMHgxNjIpXVsnbGVuZ3RoJ10pKXtmb3IodmFyIF8weDE1ZjM4MT1bXSxfMHg0YjdlNGM9W10sXzB4MWVlOGQ5PTB4MCxfMHgxNTdkMWY9XzB4NTcxNDExW18weDE0NDM4NCgweDE2MildWydsZW5ndGgnXTtfMHgxZWU4ZDk8XzB4MTU3ZDFmO18weDFlZThkOSsrKXt2YXIgXzB4NWQxMWJlPV8weDU3MTQxMVtfMHgxNDQzODQoMHgxNjIpXVtfMHgxZWU4ZDldO18weDVkMTFiZVtfMHgxNDQzODQoMHgxYWMpXT09PV8weDE0NDM4NCgweDE3Myk/XzB4MTVmMzgxW18weDE0NDM4NCgweDE3MildKF8weDVkMTFiZSk6XzB4NGI3ZTRjW18weDE0NDM4NCgweDE3MildKF8weDVkMTFiZSk7fWlmKCEoIV8weDRiN2U0Y1tfMHgxNDQzODQoMHgxYmMpXXx8XzB4MTVmMzgxWydsZW5ndGgnXTw9MHgxKSl7XzB4NTcxNDExW18weDE0NDM4NCgweDE2MildPV8weDRiN2U0Yzt2YXIgXzB4NDNkMzFjPXsnZnVuY3Rpb25zTm9kZSc6ITB4MCwncHJvcHMnOl8weDE1ZjM4MX07dGhpc1snX3NldE5vZGVJZCddKF8weDQzZDMxYyxfMHg1MTE2NmYpLHRoaXNbJ19zZXROb2RlTGFiZWwnXShfMHg0M2QzMWMsXzB4NTExNjZmKSx0aGlzW18weDE0NDM4NCgweDFkNCldKF8weDQzZDMxYyksdGhpc1snX3NldE5vZGVQZXJtaXNzaW9ucyddKF8weDQzZDMxYyxfMHg1MTE2NmYpLF8weDQzZDMxY1snaWQnXSs9J1xcXFx4MjBmJyxfMHg1NzE0MTFbJ3Byb3BzJ11bXzB4MTQ0Mzg0KDB4MjE2KV0oXzB4NDNkMzFjKTt9fX1bXzB4MTI3NzM1KDB4MTkxKV0oXzB4NDk2YTlhLF8weGJlZWE3Nyl7fVtfMHgxMjc3MzUoMHgxZDQpXShfMHgyMmIwMjIpe31bXzB4MTI3NzM1KDB4MjBmKV0oXzB4MzU3NDczKXt2YXIgXzB4ZTRhOWQwPV8weDEyNzczNTtyZXR1cm4gQXJyYXlbJ2lzQXJyYXknXShfMHgzNTc0NzMpfHx0eXBlb2YgXzB4MzU3NDczPT1fMHhlNGE5ZDAoMHgxNjYpJiZ0aGlzWydfb2JqZWN0VG9TdHJpbmcnXShfMHgzNTc0NzMpPT09J1tvYmplY3RcXFxceDIwQXJyYXldJzt9W18weDEyNzczNSgweDFhZSldKF8weDJmNDBlNixfMHg0MDU0MWMpe31bXzB4MTI3NzM1KDB4MjE5KV0oXzB4NDVmY2FlKXt2YXIgXzB4NWViMzM4PV8weDEyNzczNTtkZWxldGUgXzB4NDVmY2FlWydfaGFzU3ltYm9sUHJvcGVydHlPbkl0c1BhdGgnXSxkZWxldGUgXzB4NDVmY2FlWydfaGFzU2V0T25JdHNQYXRoJ10sZGVsZXRlIF8weDQ1ZmNhZVtfMHg1ZWIzMzgoMHgyMjYpXTt9W18weDEyNzczNSgweDE3ZCldKF8weDJjOGU5OCxfMHg1ZDE2ZTkpe319bGV0IF8weDM4ZmQzNT1uZXcgXzB4MmUwZDNjKCksXzB4M2FlMmNjPXsncHJvcHMnOjB4NjQsJ2VsZW1lbnRzJzoweDY0LCdzdHJMZW5ndGgnOjB4NDAwKjB4MzIsJ3RvdGFsU3RyTGVuZ3RoJzoweDQwMCoweDMyLCdhdXRvRXhwYW5kTGltaXQnOjB4MTM4OCwnYXV0b0V4cGFuZE1heERlcHRoJzoweGF9LF8weDRlNDQxPXsncHJvcHMnOjB4NSwnZWxlbWVudHMnOjB4NSwnc3RyTGVuZ3RoJzoweDEwMCwndG90YWxTdHJMZW5ndGgnOjB4MTAwKjB4MywnYXV0b0V4cGFuZExpbWl0JzoweDFlLCdhdXRvRXhwYW5kTWF4RGVwdGgnOjB4Mn07ZnVuY3Rpb24gXzB4YTcxM2Q3KF8weDFkNGJkOSxfMHg1NjcwMGMsXzB4NWUzNWEyLF8weGNhNWZiYSxfMHg1Y2I5YjIsXzB4NDZlY2IzKXt2YXIgXzB4Yzk0NDJjPV8weDEyNzczNTtsZXQgXzB4MWFkODJiLF8weDU2OGYwMDt0cnl7XzB4NTY4ZjAwPV8weDViNjg5ZCgpLF8weDFhZDgyYj1fMHgyZGJiYjdbXzB4NTY3MDBjXSwhXzB4MWFkODJifHxfMHg1NjhmMDAtXzB4MWFkODJiWyd0cyddPjB4MWY0JiZfMHgxYWQ4MmJbXzB4Yzk0NDJjKDB4MWJhKV0mJl8weDFhZDgyYltfMHhjOTQ0MmMoMHgxOWEpXS9fMHgxYWQ4MmJbXzB4Yzk0NDJjKDB4MWJhKV08MHg2ND8oXzB4MmRiYmI3W18weDU2NzAwY109XzB4MWFkODJiPXsnY291bnQnOjB4MCwndGltZSc6MHgwLCd0cyc6XzB4NTY4ZjAwfSxfMHgyZGJiYjdbXzB4Yzk0NDJjKDB4MThmKV09e30pOl8weDU2OGYwMC1fMHgyZGJiYjdbXzB4Yzk0NDJjKDB4MThmKV1bJ3RzJ10+MHgzMiYmXzB4MmRiYmI3W18weGM5NDQyYygweDE4ZildW18weGM5NDQyYygweDFiYSldJiZfMHgyZGJiYjdbXzB4Yzk0NDJjKDB4MThmKV1bJ3RpbWUnXS9fMHgyZGJiYjdbXzB4Yzk0NDJjKDB4MThmKV1bXzB4Yzk0NDJjKDB4MWJhKV08MHg2NCYmKF8weDJkYmJiN1tfMHhjOTQ0MmMoMHgxOGYpXT17fSk7bGV0IF8weDU1Y2ZjOT1bXSxfMHg4NDFlNTY9XzB4MWFkODJiW18weGM5NDQyYygweDFiYildfHxfMHgyZGJiYjdbJ2hpdHMnXVtfMHhjOTQ0MmMoMHgxYmIpXT9fMHg0ZTQ0MTpfMHgzYWUyY2MsXzB4OTdlMjcwPV8weDNkNGE0Mj0+e3ZhciBfMHg5NzRhZTA9XzB4Yzk0NDJjO2xldCBfMHg1MzNjZjg9e307cmV0dXJuIF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxNjIpXT1fMHgzZDRhNDJbXzB4OTc0YWUwKDB4MTYyKV0sXzB4NTMzY2Y4W18weDk3NGFlMCgweDFiNildPV8weDNkNGE0MlsnZWxlbWVudHMnXSxfMHg1MzNjZjhbJ3N0ckxlbmd0aCddPV8weDNkNGE0MltfMHg5NzRhZTAoMHgxYTUpXSxfMHg1MzNjZjhbJ3RvdGFsU3RyTGVuZ3RoJ109XzB4M2Q0YTQyW18weDk3NGFlMCgweDE3NCldLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgyMTcpXT1fMHgzZDRhNDJbXzB4OTc0YWUwKDB4MjE3KV0sXzB4NTMzY2Y4W18weDk3NGFlMCgweDE3OSldPV8weDNkNGE0MltfMHg5NzRhZTAoMHgxNzkpXSxfMHg1MzNjZjhbXzB4OTc0YWUwKDB4MTRkKV09ITB4MSxfMHg1MzNjZjhbXzB4OTc0YWUwKDB4MTg3KV09IV8weDU4YmQ5MyxfMHg1MzNjZjhbXzB4OTc0YWUwKDB4MjExKV09MHgxLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxNmQpXT0weDAsXzB4NTMzY2Y4W18weDk3NGFlMCgweDE0NildPV8weDk3NGFlMCgweDFlMyksXzB4NTMzY2Y4W18weDk3NGFlMCgweDFhOSldPSdyb290X2V4cCcsXzB4NTMzY2Y4W18weDk3NGFlMCgweDFlZildPSEweDAsXzB4NTMzY2Y4W18weDk3NGFlMCgweDFhNildPVtdLF8weDUzM2NmOFtfMHg5NzRhZTAoMHgxNTYpXT0weDAsXzB4NTMzY2Y4WydyZXNvbHZlR2V0dGVycyddPSEweDAsXzB4NTMzY2Y4W18weDk3NGFlMCgweDE4ZCldPTB4MCxfMHg1MzNjZjhbXzB4OTc0YWUwKDB4MjE0KV09eydjdXJyZW50Jzp2b2lkIDB4MCwncGFyZW50Jzp2b2lkIDB4MCwnaW5kZXgnOjB4MH0sXzB4NTMzY2Y4O307Zm9yKHZhciBfMHg0NmI3YjY9MHgwO18weDQ2YjdiNjxfMHg1Y2I5YjJbXzB4Yzk0NDJjKDB4MWJjKV07XzB4NDZiN2I2KyspXzB4NTVjZmM5W18weGM5NDQyYygweDE3MildKF8weDM4ZmQzNVtfMHhjOTQ0MmMoMHgyMWUpXSh7J3RpbWVOb2RlJzpfMHgxZDRiZDk9PT1fMHhjOTQ0MmMoMHgxOWEpfHx2b2lkIDB4MH0sXzB4NWNiOWIyW18weDQ2YjdiNl0sXzB4OTdlMjcwKF8weDg0MWU1Nikse30pKTtpZihfMHgxZDRiZDk9PT1fMHhjOTQ0MmMoMHgxNGIpfHxfMHgxZDRiZDk9PT1fMHhjOTQ0MmMoMHgyMGMpKXtsZXQgXzB4MTVmZGYzPUVycm9yW18weGM5NDQyYygweDIxYyldO3RyeXtFcnJvclsnc3RhY2tUcmFjZUxpbWl0J109MHgxLzB4MCxfMHg1NWNmYzlbXzB4Yzk0NDJjKDB4MTcyKV0oXzB4MzhmZDM1W18weGM5NDQyYygweDIxZSldKHsnc3RhY2tOb2RlJzohMHgwfSxuZXcgRXJyb3IoKVtfMHhjOTQ0MmMoMHgxZTQpXSxfMHg5N2UyNzAoXzB4ODQxZTU2KSx7J3N0ckxlbmd0aCc6MHgxLzB4MH0pKTt9ZmluYWxseXtFcnJvcltfMHhjOTQ0MmMoMHgyMWMpXT1fMHgxNWZkZjM7fX1yZXR1cm57J21ldGhvZCc6J2xvZycsJ3ZlcnNpb24nOl8weDJlZmIzMiwnYXJncyc6W3sndHMnOl8weDVlMzVhMiwnc2Vzc2lvbic6XzB4Y2E1ZmJhLCdhcmdzJzpfMHg1NWNmYzksJ2lkJzpfMHg1NjcwMGMsJ2NvbnRleHQnOl8weDQ2ZWNiM31dfTt9Y2F0Y2goXzB4OWQzZWY1KXtyZXR1cm57J21ldGhvZCc6XzB4Yzk0NDJjKDB4MTY4KSwndmVyc2lvbic6XzB4MmVmYjMyLCdhcmdzJzpbeyd0cyc6XzB4NWUzNWEyLCdzZXNzaW9uJzpfMHhjYTVmYmEsJ2FyZ3MnOlt7J3R5cGUnOl8weGM5NDQyYygweDIxZCksJ2Vycm9yJzpfMHg5ZDNlZjUmJl8weDlkM2VmNVtfMHhjOTQ0MmMoMHgxYTEpXX1dLCdpZCc6XzB4NTY3MDBjLCdjb250ZXh0JzpfMHg0NmVjYjN9XX07fWZpbmFsbHl7dHJ5e2lmKF8weDFhZDgyYiYmXzB4NTY4ZjAwKXtsZXQgXzB4MzgzMzhlPV8weDViNjg5ZCgpO18weDFhZDgyYlsnY291bnQnXSsrLF8weDFhZDgyYlsndGltZSddKz1fMHgyMzJkMGQoXzB4NTY4ZjAwLF8weDM4MzM4ZSksXzB4MWFkODJiWyd0cyddPV8weDM4MzM4ZSxfMHgyZGJiYjdbJ2hpdHMnXVsnY291bnQnXSsrLF8weDJkYmJiN1snaGl0cyddW18weGM5NDQyYygweDE5YSldKz1fMHgyMzJkMGQoXzB4NTY4ZjAwLF8weDM4MzM4ZSksXzB4MmRiYmI3W18weGM5NDQyYygweDE4ZildWyd0cyddPV8weDM4MzM4ZSwoXzB4MWFkODJiWydjb3VudCddPjB4MzJ8fF8weDFhZDgyYltfMHhjOTQ0MmMoMHgxOWEpXT4weDY0KSYmKF8weDFhZDgyYltfMHhjOTQ0MmMoMHgxYmIpXT0hMHgwKSwoXzB4MmRiYmI3W18weGM5NDQyYygweDE4ZildW18weGM5NDQyYygweDFiYSldPjB4M2U4fHxfMHgyZGJiYjdbXzB4Yzk0NDJjKDB4MThmKV1bXzB4Yzk0NDJjKDB4MTlhKV0+MHgxMmMpJiYoXzB4MmRiYmI3W18weGM5NDQyYygweDE4ZildW18weGM5NDQyYygweDFiYildPSEweDApO319Y2F0Y2h7fX19cmV0dXJuIF8weGE3MTNkNzt9KChfMHg5MGMzN2EsXzB4MWQ3NDhkLF8weDI3ZjE4NCxfMHgxYzNlNDEsXzB4MTc1MmI5LF8weDE1YzRiZSxfMHg0M2FiNmMsXzB4NWUwMzU3LF8weDM4NTg2YyxfMHgxM2U5YWUsXzB4ODk4MmMxKT0+e3ZhciBfMHg1OTMxMTI9XzB4MzFlNDg2O2lmKF8weDkwYzM3YVsnX2NvbnNvbGVfbmluamEnXSlyZXR1cm4gXzB4OTBjMzdhW18weDU5MzExMigweDIyMyldO2lmKCFIKF8weDkwYzM3YSxfMHg1ZTAzNTcsXzB4MTc1MmI5KSlyZXR1cm4gXzB4OTBjMzdhW18weDU5MzExMigweDIyMyldPXsnY29uc29sZUxvZyc6KCk9Pnt9LCdjb25zb2xlVHJhY2UnOigpPT57fSwnY29uc29sZVRpbWUnOigpPT57fSwnY29uc29sZVRpbWVFbmQnOigpPT57fSwnYXV0b0xvZyc6KCk9Pnt9LCdhdXRvTG9nTWFueSc6KCk9Pnt9LCdhdXRvVHJhY2VNYW55JzooKT0+e30sJ2NvdmVyYWdlJzooKT0+e30sJ2F1dG9UcmFjZSc6KCk9Pnt9LCdhdXRvVGltZSc6KCk9Pnt9LCdhdXRvVGltZUVuZCc6KCk9Pnt9fSxfMHg5MGMzN2FbXzB4NTkzMTEyKDB4MjIzKV07bGV0IF8weDQwOTdlNj1CKF8weDkwYzM3YSksXzB4MTg1YWJhPV8weDQwOTdlNlsnZWxhcHNlZCddLF8weDI4ZWYxYz1fMHg0MDk3ZTZbXzB4NTkzMTEyKDB4MTc3KV0sXzB4MzRlNGMzPV8weDQwOTdlNltfMHg1OTMxMTIoMHgyMmIpXSxfMHg0NDNjNTk9eydoaXRzJzp7fSwndHMnOnt9fSxfMHg1NWFiY2M9WChfMHg5MGMzN2EsXzB4Mzg1ODZjLF8weDQ0M2M1OSxfMHgxNWM0YmUpLF8weGE4ZTE1PV8weDRjZjg5ND0+e18weDQ0M2M1OVsndHMnXVtfMHg0Y2Y4OTRdPV8weDI4ZWYxYygpO30sXzB4MWZiM2Y2PShfMHg1MjY0YzMsXzB4NWJjMWRjKT0+e3ZhciBfMHgzMDNhM2Q9XzB4NTkzMTEyO2xldCBfMHgyYjVmNDI9XzB4NDQzYzU5Wyd0cyddW18weDViYzFkY107aWYoZGVsZXRlIF8weDQ0M2M1OVsndHMnXVtfMHg1YmMxZGNdLF8weDJiNWY0Mil7bGV0IF8weDIyN2E0PV8weDE4NWFiYShfMHgyYjVmNDIsXzB4MjhlZjFjKCkpO18weDRlMTU4ZShfMHg1NWFiY2MoXzB4MzAzYTNkKDB4MTlhKSxfMHg1MjY0YzMsXzB4MzRlNGMzKCksXzB4MTg0YjQ4LFtfMHgyMjdhNF0sXzB4NWJjMWRjKSk7fX0sXzB4M2Q3ZmExPV8weDNjNWE2Mj0+e3ZhciBfMHg0N2FmMzM9XzB4NTkzMTEyLF8weDNlZTA3MjtyZXR1cm4gXzB4MTc1MmI5PT09XzB4NDdhZjMzKDB4MjJjKSYmXzB4OTBjMzdhWydvcmlnaW4nXSYmKChfMHgzZWUwNzI9XzB4M2M1YTYyPT1udWxsP3ZvaWQgMHgwOl8weDNjNWE2MlsnYXJncyddKT09bnVsbD92b2lkIDB4MDpfMHgzZWUwNzJbXzB4NDdhZjMzKDB4MWJjKV0pJiYoXzB4M2M1YTYyWydhcmdzJ11bMHgwXVtfMHg0N2FmMzMoMHgxZDApXT1fMHg5MGMzN2FbXzB4NDdhZjMzKDB4MWQwKV0pLF8weDNjNWE2Mjt9O18weDkwYzM3YVsnX2NvbnNvbGVfbmluamEnXT17J2NvbnNvbGVMb2cnOihfMHg1YTM1MmUsXzB4NDgzNWRhKT0+e3ZhciBfMHg0NTRjMDE9XzB4NTkzMTEyO18weDkwYzM3YVtfMHg0NTRjMDEoMHgxZGYpXVtfMHg0NTRjMDEoMHgxNjgpXVtfMHg0NTRjMDEoMHgxYzkpXSE9PV8weDQ1NGMwMSgweDE5ZikmJl8weDRlMTU4ZShfMHg1NWFiY2MoXzB4NDU0YzAxKDB4MTY4KSxfMHg1YTM1MmUsXzB4MzRlNGMzKCksXzB4MTg0YjQ4LF8weDQ4MzVkYSkpO30sJ2NvbnNvbGVUcmFjZSc6KF8weDJkNDUxMyxfMHg0ZTc5MTkpPT57dmFyIF8weDFkZjk5Zj1fMHg1OTMxMTIsXzB4MWMwYzU4LF8weDE1MWU3YTtfMHg5MGMzN2FbXzB4MWRmOTlmKDB4MWRmKV1bXzB4MWRmOTlmKDB4MTY4KV1bXzB4MWRmOTlmKDB4MWM5KV0hPT0nZGlzYWJsZWRUcmFjZScmJigoXzB4MTUxZTdhPShfMHgxYzBjNTg9XzB4OTBjMzdhWydwcm9jZXNzJ10pPT1udWxsP3ZvaWQgMHgwOl8weDFjMGM1OFtfMHgxZGY5OWYoMHgxNTIpXSkhPW51bGwmJl8weDE1MWU3YVtfMHgxZGY5OWYoMHgyMTQpXSYmKF8weDkwYzM3YVtfMHgxZGY5OWYoMHgxOGUpXT0hMHgwKSxfMHg0ZTE1OGUoXzB4M2Q3ZmExKF8weDU1YWJjYyhfMHgxZGY5OWYoMHgxNGIpLF8weDJkNDUxMyxfMHgzNGU0YzMoKSxfMHgxODRiNDgsXzB4NGU3OTE5KSkpKTt9LCdjb25zb2xlRXJyb3InOihfMHgyMTA1NjcsXzB4MzBhMDI1KT0+e3ZhciBfMHgzZDZjZmM9XzB4NTkzMTEyO18weDkwYzM3YVtfMHgzZDZjZmMoMHgxOGUpXT0hMHgwLF8weDRlMTU4ZShfMHgzZDdmYTEoXzB4NTVhYmNjKCdlcnJvcicsXzB4MjEwNTY3LF8weDM0ZTRjMygpLF8weDE4NGI0OCxfMHgzMGEwMjUpKSk7fSwnY29uc29sZVRpbWUnOl8weDE4YjhkOT0+e18weGE4ZTE1KF8weDE4YjhkOSk7fSwnY29uc29sZVRpbWVFbmQnOihfMHgzY2Y3NzgsXzB4NTkyNzc2KT0+e18weDFmYjNmNihfMHg1OTI3NzYsXzB4M2NmNzc4KTt9LCdhdXRvTG9nJzooXzB4MmVmNzZmLF8weDM5OTE2MCk9Pnt2YXIgXzB4NDliM2E1PV8weDU5MzExMjtfMHg0ZTE1OGUoXzB4NTVhYmNjKF8weDQ5YjNhNSgweDE2OCksXzB4Mzk5MTYwLF8weDM0ZTRjMygpLF8weDE4NGI0OCxbXzB4MmVmNzZmXSkpO30sJ2F1dG9Mb2dNYW55JzooXzB4NGIwOGNiLF8weDRlN2RlNCk9Pnt2YXIgXzB4MTg1ODRiPV8weDU5MzExMjtfMHg0ZTE1OGUoXzB4NTVhYmNjKF8weDE4NTg0YigweDE2OCksXzB4NGIwOGNiLF8weDM0ZTRjMygpLF8weDE4NGI0OCxfMHg0ZTdkZTQpKTt9LCdhdXRvVHJhY2UnOihfMHgzYjY5ZjAsXzB4MWQ3YTE5KT0+e3ZhciBfMHgzN2VkMjU9XzB4NTkzMTEyO18weDRlMTU4ZShfMHgzZDdmYTEoXzB4NTVhYmNjKF8weDM3ZWQyNSgweDE0YiksXzB4MWQ3YTE5LF8weDM0ZTRjMygpLF8weDE4NGI0OCxbXzB4M2I2OWYwXSkpKTt9LCdhdXRvVHJhY2VNYW55JzooXzB4NDc5YzM0LF8weDE5YTJhYik9PntfMHg0ZTE1OGUoXzB4M2Q3ZmExKF8weDU1YWJjYygndHJhY2UnLF8weDQ3OWMzNCxfMHgzNGU0YzMoKSxfMHgxODRiNDgsXzB4MTlhMmFiKSkpO30sJ2F1dG9UaW1lJzooXzB4MzdmODAzLF8weDE3MWMyNCxfMHg0Mjc1ODgpPT57XzB4YThlMTUoXzB4NDI3NTg4KTt9LCdhdXRvVGltZUVuZCc6KF8weGFlNDdmYyxfMHgyYTkwNDIsXzB4M2JlNjAzKT0+e18weDFmYjNmNihfMHgyYTkwNDIsXzB4M2JlNjAzKTt9LCdjb3ZlcmFnZSc6XzB4MzllNzc1PT57XzB4NGUxNThlKHsnbWV0aG9kJzonY292ZXJhZ2UnLCd2ZXJzaW9uJzpfMHgxNWM0YmUsJ2FyZ3MnOlt7J2lkJzpfMHgzOWU3NzV9XX0pO319O2xldCBfMHg0ZTE1OGU9cShfMHg5MGMzN2EsXzB4MWQ3NDhkLF8weDI3ZjE4NCxfMHgxYzNlNDEsXzB4MTc1MmI5LF8weDEzZTlhZSxfMHg4OTgyYzEpLF8weDE4NGI0OD1fMHg5MGMzN2FbXzB4NTkzMTEyKDB4MTc2KV07cmV0dXJuIF8weDkwYzM3YVtfMHg1OTMxMTIoMHgyMjMpXTt9KShnbG9iYWxUaGlzLCcxMjcuMC4wLjEnLF8weDMxZTQ4NigweDFiMiksXzB4MzFlNDg2KDB4MjAzKSxfMHgzMWU0ODYoMHgxZDcpLF8weDMxZTQ4NigweDIwNyksJzE3Mzc3MTg0OTczMDMnLF8weDMxZTQ4NigweDIyMiksXzB4MzFlNDg2KDB4MWI3KSwnJyxfMHgzMWU0ODYoMHgxNTEpKTtcIik7XG59XG5jYXRjaCAoZSkgeyB9IH1cbjsgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIG9vX29vKGksIC4uLnYpIHsgdHJ5IHtcbiAgICBvb19jbSgpLmNvbnNvbGVMb2coaSwgdik7XG59XG5jYXRjaCAoZSkgeyB9IHJldHVybiB2OyB9XG47XG5vb19vbzsgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIG9vX3RyKGksIC4uLnYpIHsgdHJ5IHtcbiAgICBvb19jbSgpLmNvbnNvbGVUcmFjZShpLCB2KTtcbn1cbmNhdGNoIChlKSB7IH0gcmV0dXJuIHY7IH1cbjtcbm9vX3RyOyAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gb29fdHgoaSwgLi4udikgeyB0cnkge1xuICAgIG9vX2NtKCkuY29uc29sZUVycm9yKGksIHYpO1xufVxuY2F0Y2ggKGUpIHsgfSByZXR1cm4gdjsgfVxuO1xub29fdHg7IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBvb190cyh2KSB7IHRyeSB7XG4gICAgb29fY20oKS5jb25zb2xlVGltZSh2KTtcbn1cbmNhdGNoIChlKSB7IH0gcmV0dXJuIHY7IH1cbjtcbm9vX3RzOyAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gb29fdGUodiwgaSkgeyB0cnkge1xuICAgIG9vX2NtKCkuY29uc29sZVRpbWVFbmQodiwgaSk7XG59XG5jYXRjaCAoZSkgeyB9IHJldHVybiB2OyB9XG47XG5vb190ZTsgLyplc2xpbnQgdW5pY29ybi9uby1hYnVzaXZlLWVzbGludC1kaXNhYmxlOixlc2xpbnQtY29tbWVudHMvZGlzYWJsZS1lbmFibGUtcGFpcjosZXNsaW50LWNvbW1lbnRzL25vLXVubGltaXRlZC1kaXNhYmxlOixlc2xpbnQtY29tbWVudHMvbm8tYWdncmVnYXRpbmctZW5hYmxlOixlc2xpbnQtY29tbWVudHMvbm8tZHVwbGljYXRlLWRpc2FibGU6LGVzbGludC1jb21tZW50cy9uby11bnVzZWQtZGlzYWJsZTosZXNsaW50LWNvbW1lbnRzL25vLXVudXNlZC1lbmFibGU6LCovXG4iXSwibmFtZXMiOlsiX3RvQ29uc3VtYWJsZUFycmF5IiwiYXJyIiwiX2FycmF5V2l0aG91dEhvbGVzIiwiX2l0ZXJhYmxlVG9BcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsIl9ub25JdGVyYWJsZVNwcmVhZCIsIlR5cGVFcnJvciIsIm8iLCJtaW5MZW4iLCJfYXJyYXlMaWtlVG9BcnJheSIsIm4iLCJPYmplY3QiLCJwcm90b3R5cGUiLCJ0b1N0cmluZyIsImNhbGwiLCJzbGljZSIsImNvbnN0cnVjdG9yIiwibmFtZSIsIkFycmF5IiwiZnJvbSIsInRlc3QiLCJpdGVyIiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJpc0FycmF5IiwibGVuIiwibGVuZ3RoIiwiaSIsImFycjIiLCJfY2xhc3NDYWxsQ2hlY2siLCJpbnN0YW5jZSIsIkNvbnN0cnVjdG9yIiwiX2RlZmluZVByb3BlcnRpZXMiLCJ0YXJnZXQiLCJwcm9wcyIsImRlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwiY29uZmlndXJhYmxlIiwid3JpdGFibGUiLCJkZWZpbmVQcm9wZXJ0eSIsImtleSIsIl9jcmVhdGVDbGFzcyIsInByb3RvUHJvcHMiLCJzdGF0aWNQcm9wcyIsIl9faW1wb3J0RGVmYXVsdCIsIm1vZCIsIl9fZXNNb2R1bGUiLCJleHBvcnRzIiwidmFsdWUiLCJEeW5hbWljRmllbGQiLCJqcXVlcnlfMSIsInJlcXVpcmUiLCJoaWRlU2hvd0Zvcm1GaWVsZHMiLCJodW1hbml0YXJpYW5TY29wZUhpZGVWb2NhYnVsYXJ5VXJpIiwiY291bnRyeUJ1ZGdldEhpZGVDb2RlRmllbGQiLCJhaWRUeXBlVm9jYWJ1bGFyeUhpZGVGaWVsZCIsInNlY3RvclZvY2FidWxhcnlIaWRlRmllbGQiLCJwb2xpY3lWb2NhYnVsYXJ5SGlkZUZpZWxkIiwicmVjaXBpZW50Vm9jYWJ1bGFyeUhpZGVGaWVsZCIsInRhZ1ZvY2FidWxhcnlIaWRlRmllbGQiLCJ0cmFuc2FjdGlvbkFpZFR5cGVWb2NhYnVsYXJ5SGlkZUZpZWxkIiwiaW5kaWNhdG9yUmVmZXJlbmNlSGlkZUZpZWxkVXJpIiwiX3RoaXMiLCJodW1hbml0YXJpYW5TY29wZVZvY2FidWxhcnkiLCJlYWNoIiwiaW5kZXgiLCJzY29wZSIsIl9hIiwidmFsIiwiaGlkZUh1bWFuaXRhcmlhblNjb3BlRmllbGQiLCJvbiIsImUiLCJwYXJhbXMiLCJkYXRhIiwiaWQiLCJjbG9zZXN0IiwiZmluZCIsInNob3ciLCJyZW1vdmVBdHRyIiwidHJpZ2dlciIsImhpZGUiLCJhdHRyIiwiX3RoaXMyIiwicmVmZXJlbmNlVm9jYWJ1bGFyeSIsImluZGljYXRvclJlZmVyZW5jZUhpZGVGaWVsZCIsInJlZmVyZW5jZVVyaSIsIl90aGlzMyIsImNvdW50cnlCdWRnZXRWb2NhYnVsYXJ5IiwiaGlkZUNvdW50cnlCdWRnZXRGaWVsZCIsImNvdW50cnlCdWRnZXRDb2RlSW5wdXQiLCJjb3VudHJ5QnVkZ2V0Q29kZVNlbGVjdCIsIl90aGlzNCIsImFpZHR5cGVfdm9jYWJ1bGFyeSIsIml0ZW0iLCJoaWRlQWlkVHlwZVNlbGVjdEZpZWxkIiwiX3RoaXM1IiwiaGlkZVRyYW5zYWN0aW9uQWlkVHlwZVNlbGVjdEZpZWxkIiwiZGVmYXVsdF9haWRfdHlwZSIsImVhcm1hcmtpbmdfY2F0ZWdvcnkiLCJlYXJtYXJraW5nX21vZGFsaXR5IiwiY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzIiwiY2FzZTEiLCJjYXNlMiIsImNhc2UzIiwiY2FzZTQiLCJhaWRfdHlwZSIsIl90aGlzNiIsInBvbGljeW1ha2VyX3ZvY2FidWxhcnkiLCJwb2xpY3lfbWFya2VyIiwiaGlkZVBvbGljeU1ha2VyRmllbGQiLCJjYXNlMV9zaG93IiwiY2FzZTJfc2hvdyIsIl90aGlzNyIsInNlY3Rvcl92b2NhYnVsYXJ5Iiwic2VjdG9yIiwiaGlkZVNlY3RvckZpZWxkIiwiY2FzZTdfc2hvdyIsImNhc2U4X3Nob3ciLCJjYXNlOThfOTlfc2hvdyIsImRlZmF1bHRfc2hvdyIsImNhc2U3IiwiY2FzZTgiLCJjYXNlOThfOTkiLCJkZWZhdWx0X2hpZGUiLCJfdGhpczgiLCJyZWdpb25fdm9jYWJ1bGFyeSIsInJlZ2lvbl92b2NhYiIsImhpZGVSZWNpcGllbnRSZWdpb25GaWVsZCIsImNhc2U5OV9zaG93IiwiY2FzZTk5IiwidXBkYXRlQWN0aXZpdHlJZGVudGlmaWVyIiwiYWN0aXZpdHlfaWRlbnRpZmllciIsImNvbmNhdCIsIl90aGlzOSIsInRhZ192b2NhYnVsYXJ5IiwidGFnIiwiaGlkZVRhZ0ZpZWxkIiwiY2FzZTNfc2hvdyIsImRvY3VtZW50IiwiZXZlbnQiLCJfY29uc29sZSIsInN0b3BQcm9wYWdhdGlvbiIsImNvbnNvbGUiLCJsb2ciLCJhcHBseSIsIm9vX29vIiwiaGVscFRleHQiLCJjc3MiLCJvcGFjaXR5IiwidmlzaWJpbGl0eSIsImNsb3NlSGVscFRleHQiLCJzZXRUaW1lb3V0Iiwib29fY20iLCJldmFsIiwiX2xlbiIsImFyZ3VtZW50cyIsInYiLCJfa2V5IiwiY29uc29sZUxvZyIsIm9vX3RyIiwiX2xlbjIiLCJfa2V5MiIsImNvbnNvbGVUcmFjZSIsIm9vX3R4IiwiX2xlbjMiLCJfa2V5MyIsImNvbnNvbGVFcnJvciIsIm9vX3RzIiwiY29uc29sZVRpbWUiLCJvb190ZSIsImNvbnNvbGVUaW1lRW5kIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJhbGxvd0FycmF5TGlrZSIsIml0IiwiRiIsInMiLCJkb25lIiwiX2UiLCJmIiwibm9ybWFsQ29tcGxldGlvbiIsImRpZEVyciIsImVyciIsInN0ZXAiLCJuZXh0IiwiX2UyIiwiYXhpb3NfMSIsIkR5bmFtaWNGaWVsZF8xIiwiZHluYW1pY0ZpZWxkIiwiRm9ybUJ1aWxkZXIiLCJhZGRGb3JtIiwiZXYiLCJwcmV2ZW50RGVmYXVsdCIsImNvbnRhaW5lciIsImNvdW50IiwicGFyc2VJbnQiLCJwYXJlbnQiLCJwYXJlbnRfY291bnQiLCJwYXJlbnRzIiwid3JhcHBlcl9wYXJlbnRfY291bnQiLCJwcm90byIsInJlcGxhY2UiLCJwcmV2IiwiYXBwZW5kIiwiY2hpbGRyZW4iLCJsYXN0Iiwic2VsZWN0MiIsInBsYWNlaG9sZGVyIiwiYWxsb3dDbGVhciIsIndyYXBBbGwiLCJhZGRQYXJlbnRGb3JtIiwiYWRkV3JhcHBlck9uQWRkIiwiZGVsZXRlRm9ybSIsImNvbGxlY3Rpb25MZW5ndGgiLCJ0ZyIsInJlbW92ZSIsImRlbGV0ZVBhcmVudEZvcm0iLCJhZGRXcmFwcGVyIiwiZm9ybUZpZWxkIiwidGV4dEFyZWFIZWlnaHQiLCJoZWlnaHQiLCJzY3JvbGxIZWlnaHQiLCJhZGRUb0NvbGxlY3Rpb24iLCJoYXNDbGFzcyIsImhhbmRsZURlbGV0ZVBhcmVudEJ1dHRvbnMiLCJkZWxldGVDb2xsZWN0aW9uIiwiZGVsZXRlQ29uZmlybWF0aW9uIiwiY2FuY2VsUG9wdXAiLCJkZWxldGVDb25maXJtIiwiZGVsZXRlSW5kZXgiLCJjaGlsZE9yUGFyZW50IiwiZmFkZUluIiwiZmFkZU91dCIsImRlbGV0ZUJ1dHRvbiIsIm11bHRpRm9ybSIsImJhY2tncm91bmQiLCJvdXRsaW5lIiwiZmlsZVBhdGgiLCJ1cmwiLCJnZXQiLCJ0aGVuIiwicmVzcG9uc2UiLCJzdWNjZXNzIiwiZm9ybWF0IiwibWltZXR5cGUiLCJtZXNzYWdlIiwiZmlsZVVybCIsImRlbGV0ZUJ1dHRvbnMiLCJxdWVyeVNlbGVjdG9yQWxsIiwiY2hhbmdlRGVsZXRlQnV0dG9uSW5uZXJIdG1sIiwiYnV0dG9uIiwiaW5pdGlhbFRleHQiLCJlc2NhcGVIdG1sIiwidGV4dENvbnRlbnQiLCJpbm5lckhUTUwiLCJmb3JFYWNoIiwiZm9ybUJ1aWxkZXIiLCJ0ZXh0QXJlYVRhcmdldCIsInNlbGVjdF9zZWFyY2giLCJxdWVyeVNlbGVjdG9yIiwiZm9jdXMiLCJ1cGRhdGVSZWdpc3RyYXRpb25BZ2VuY3kiLCJjb3VudHJ5IiwiZW5kcG9pbnQiLCJhamF4IiwiY3VycmVudF92YWwiLCJlbXB0eSIsIk9wdGlvbiIsImlkZW50aWZpZXIiLCJzdWJlbGVtZW50IiwidGl0bGUiLCJlcnJvckNvbnRhaW5lciIsImNoaWxkQ291bnQiLCJjaGlsZEVsZW1lbnRDb3VudCIsImNsYXNzTGlzdCIsImFkZCIsInJlYWRPbmx5U2VsZWN0cyIsInNlbGVjdCIsInNlbGVjdEVsZW1lbnRQYXJlbnRXcmFwcGVyIiwibmV4dFNpYmxpbmciLCJzZWxlY3RFbGVtZW50UGFyZW50IiwiZmlyc3RDaGlsZCIsInNlbGVjdEVsZW1lbnQiLCJzdHlsZSIsImN1cnNvciIsIm9ic2VydmVyIiwiTXV0YXRpb25PYnNlcnZlciIsIm11dGF0aW9uc0xpc3QiLCJtdXRhdGlvbiIsImFkZGVkTm9kZXMiLCJub2RlIiwiRWxlbWVudCIsIm1hdGNoZXMiLCJuZXdEZWxldGVCdXR0b25zIiwib2JzZXJ2ZSIsImJvZHkiLCJjaGlsZExpc3QiLCJzdWJ0cmVlIiwiYXR0YWNoQ29sbGFwc2FibGVCdXR0b25FdmVudHMiLCJsYWJlbCIsImdldENsb3Nlc3RMYWJlbERvbSIsIm9wdGlvbmFsTGFiZWwiLCJnZXRPcHRpb25hbFRleHREb20iLCJnZXRDbG9zZXN0UGFyZW50U3ViZWxlbWVudERvbSIsInRoaXNCdXR0b25CZWxvbmdzVG9PcHRpb25hbEZvcm0iLCJhZGRFdmVudExpc3RlbmVyIiwidG9nZ2xlT3B0aW9uYWxUZXh0IiwidG9nZ2xlQWNjb3JkaW9uSXRlbXMiLCJ0b2dnbGUiLCJlcnJvck1lc3NhZ2VFeGlzdHMiLCJjbGljayIsImVycm9yRGl2cyIsImVycm9yVGV4dHMiLCJfaXRlcmF0b3IiLCJfc3RlcCIsImRpdiIsInRyaW0iLCJfaXRlcmF0b3IyIiwiX3N0ZXAyIiwib3B0aW9uYWxMYWJlbFdpdGhTdmciLCJvcHRpb25hbExhYmVsV2l0aEJyYWNrZXRzIiwic3ZnRXhpc3RzIiwiaXNBZGRBZGRpdGlvbmFsQnV0dG9uT3V0c2lkZSIsIm5leHRFbGVtZW50U2libGluZyIsInRhZ05hbWUiLCJjb250YWlucyIsImhpZGVhYmxlU3ViZWxlbWVudHMiLCJmaWx0ZXIiLCJjaGlsZCIsIm91dHNpZGVCdXR0b24iLCJoYXNBZGRBZGRpdGlvbmFsQnV0dG9uT3V0c2lkZSIsImF0dGFjaEluaXRpYWxDb2xsYXBzYWJsZUJ1dHRvbkV2ZW50cyIsImFsbENvbGxhcHNhYmxlQnV0dG9ucyIsIm9ic2VydmVOZXdDb2xsYXBzYWJsZUJ1dHRvbnMiLCJ0eXBlIiwiSFRNTEVsZW1lbnQiLCJuZXdDb2xsYXBzYWJsZUJ1dHRvbnMiLCJ1bnNhZmUiXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUNqRSxVQUFVLENBQUMsT0FBTyxDQUFDO0VBQ2hDLENBQUMsRUFBRSxJQUFJLENBQUM7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvYXNzZXRzL2pzL3NjcmlwdHMvRHluYW1pY0ZpZWxkLnRzIiwid2VicGFjazovLy8uL3Jlc291cmNlcy9hc3NldHMvanMvc2NyaXB0cy9mb3JtYnVpbGRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2ltcG9ydERlZmF1bHQgPSAodGhpcyAmJiB0aGlzLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgXCJkZWZhdWx0XCI6IG1vZCB9O1xufTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuRHluYW1pY0ZpZWxkID0gdm9pZCAwO1xuY29uc3QganF1ZXJ5XzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZShcImpxdWVyeVwiKSk7XG5yZXF1aXJlKFwic2VsZWN0MlwiKTtcbmNsYXNzIER5bmFtaWNGaWVsZCB7XG4gICAgLyoqXG4gICAgICogSGlkZSBhbmQgU2hvdyBkaWZmZXJlbnQgZm9ybSBmaWVsZHMgYmFzZWQgb24gdm9jYWJ1bGFyeSBhbmQgb3RoZXIgdHlwZXNcbiAgICAgKi9cbiAgICBoaWRlU2hvd0Zvcm1GaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuaHVtYW5pdGFyaWFuU2NvcGVIaWRlVm9jYWJ1bGFyeVVyaSgpO1xuICAgICAgICB0aGlzLmNvdW50cnlCdWRnZXRIaWRlQ29kZUZpZWxkKCk7XG4gICAgICAgIHRoaXMuYWlkVHlwZVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgdGhpcy5zZWN0b3JWb2NhYnVsYXJ5SGlkZUZpZWxkKCk7XG4gICAgICAgIHRoaXMucG9saWN5Vm9jYWJ1bGFyeUhpZGVGaWVsZCgpO1xuICAgICAgICB0aGlzLnJlY2lwaWVudFZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgdGhpcy5zZWN0b3JWb2NhYnVsYXJ5SGlkZUZpZWxkKCk7XG4gICAgICAgIHRoaXMudGFnVm9jYWJ1bGFyeUhpZGVGaWVsZCgpO1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uQWlkVHlwZVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgdGhpcy5pbmRpY2F0b3JSZWZlcmVuY2VIaWRlRmllbGRVcmkoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSHVtYW5pdGFyaWFuIFNjb3BlIEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgZmllbGQgYmFzZWQgb24gJ0B2b2NhYnVsYXJ5JyBmaWVsZCB2YWx1ZVxuICAgICAqL1xuICAgIGh1bWFuaXRhcmlhblNjb3BlSGlkZVZvY2FidWxhcnlVcmkoKSB7XG4gICAgICAgIGNvbnN0IGh1bWFuaXRhcmlhblNjb3BlVm9jYWJ1bGFyeSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnc2VsZWN0W2lkXj1cImh1bWFuaXRhcmlhbl9zY29wZVwiXVtpZCo9XCJbdm9jYWJ1bGFyeV1cIl0nKTtcbiAgICAgICAgaWYgKGh1bWFuaXRhcmlhblNjb3BlVm9jYWJ1bGFyeS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyBoaWRlIGZpZWxkcyBvbiBwYWdlIGxvYWRcbiAgICAgICAgICAgIGpxdWVyeV8xLmRlZmF1bHQuZWFjaChodW1hbml0YXJpYW5TY29wZVZvY2FidWxhcnksIChpbmRleCwgc2NvcGUpID0+IHtcbiAgICAgICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsID0gKF9hID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHNjb3BlKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJyc7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSHVtYW5pdGFyaWFuU2NvcGVGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoc2NvcGUpLCB2YWwudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGhpZGUvc2hvdyBmaWVsZHMgb24gdmFsdWUgY2hhbmdlXG4gICAgICAgICAgICBodW1hbml0YXJpYW5TY29wZVZvY2FidWxhcnkub24oJ3NlbGVjdDI6c2VsZWN0JywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWwgPSBlLnBhcmFtcy5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSHVtYW5pdGFyaWFuU2NvcGVGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaW5kZXgpLCB2YWwpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBoaWRlL3Nob3cgZmllbGRzIG9uIHZhbHVlIGNsZWFyXG4gICAgICAgICAgICBodW1hbml0YXJpYW5TY29wZVZvY2FidWxhcnkub24oJ3NlbGVjdDI6Y2xlYXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSHVtYW5pdGFyaWFuU2NvcGVGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaW5kZXgpLCAnJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBoaWRlIGNvdW50cnkgYnVkZ2V0IGJhc2VkIG9uIHZvY2FidWxhcnlcbiAgICBoaWRlSHVtYW5pdGFyaWFuU2NvcGVGaWVsZChpbmRleCwgdmFsdWUpIHtcbiAgICAgICAgY29uc3QgaHVtYW5pdGFyaWFuU2NvcGVIaWRlVm9jYWJ1bGFyeVVyaSA9ICdpbnB1dFtpZF49XCJodW1hbml0YXJpYW5fc2NvcGVcIl1baWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXSc7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gJzk5Jykge1xuICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgIC5maW5kKGh1bWFuaXRhcmlhblNjb3BlSGlkZVZvY2FidWxhcnlVcmkpXG4gICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgIC5maW5kKGh1bWFuaXRhcmlhblNjb3BlSGlkZVZvY2FidWxhcnlVcmkpXG4gICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSHVtYW5pdGFyaWFuIFNjb3BlIEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgZmllbGQgYmFzZWQgb24gJ0B2b2NhYnVsYXJ5JyBmaWVsZCB2YWx1ZVxuICAgICAqL1xuICAgIGluZGljYXRvclJlZmVyZW5jZUhpZGVGaWVsZFVyaSgpIHtcbiAgICAgICAgY29uc3QgcmVmZXJlbmNlVm9jYWJ1bGFyeSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnc2VsZWN0W2lkXj1cInJlZmVyZW5jZVwiXVtpZCo9XCJbdm9jYWJ1bGFyeV1cIl0nKTtcbiAgICAgICAgaWYgKHJlZmVyZW5jZVZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gaGlkZSBmaWVsZHMgb24gcGFnZSBsb2FkXG4gICAgICAgICAgICBqcXVlcnlfMS5kZWZhdWx0LmVhY2gocmVmZXJlbmNlVm9jYWJ1bGFyeSwgKGluZGV4LCBzY29wZSkgPT4ge1xuICAgICAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWwgPSAoX2EgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoc2NvcGUpLnZhbCgpKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiAnJztcbiAgICAgICAgICAgICAgICB0aGlzLmluZGljYXRvclJlZmVyZW5jZUhpZGVGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoc2NvcGUpLCB2YWwudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGhpZGUvc2hvdyBmaWVsZHMgb24gdmFsdWUgY2hhbmdlXG4gICAgICAgICAgICByZWZlcmVuY2VWb2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOnNlbGVjdCcsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsID0gZS5wYXJhbXMuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaW5kaWNhdG9yUmVmZXJlbmNlSGlkZUZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KShpbmRleCksIHZhbCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIGhpZGUvc2hvdyBmaWVsZHMgb24gdmFsdWUgY2xlYXJcbiAgICAgICAgICAgIHJlZmVyZW5jZVZvY2FidWxhcnkub24oJ3NlbGVjdDI6Y2xlYXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5pbmRpY2F0b3JSZWZlcmVuY2VIaWRlRmllbGQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGluZGV4KSwgJycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gaGlkZSBjb3VudHJ5IGJ1ZGdldCBiYXNlZCBvbiB2b2NhYnVsYXJ5XG4gICAgaW5kaWNhdG9yUmVmZXJlbmNlSGlkZUZpZWxkKGluZGV4LCB2YWx1ZSkge1xuICAgICAgICBjb25zdCByZWZlcmVuY2VVcmkgPSAnaW5wdXRbaWRePVwicmVmZXJlbmNlXCJdW2lkKj1cIltpbmRpY2F0b3JfdXJpXVwiXSc7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gJzk5Jykge1xuICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgIC5maW5kKHJlZmVyZW5jZVVyaSlcbiAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgLmZpbmQocmVmZXJlbmNlVXJpKVxuICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvdW50cnkgQnVkZ2V0IEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIHNob3cvaGlkZSAnY29kZScgZmllbGQgYmFzZWQgb24gJ0B2b2NhYnVsYXJ5JyBmaWVsZCB2YWx1ZVxuICAgICAqL1xuICAgIGNvdW50cnlCdWRnZXRIaWRlQ29kZUZpZWxkKCkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGNvbnN0IGNvdW50cnlCdWRnZXRWb2NhYnVsYXJ5ID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdzZWxlY3QjY291bnRyeV9idWRnZXRfdm9jYWJ1bGFyeScpO1xuICAgICAgICBpZiAoY291bnRyeUJ1ZGdldFZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gaGlkZS9zaG93IG9uIHBhZ2UgbG9hZFxuICAgICAgICAgICAgY29uc3QgdmFsID0gKF9hID0gY291bnRyeUJ1ZGdldFZvY2FidWxhcnkudmFsKCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6ICcxJztcbiAgICAgICAgICAgIHRoaXMuaGlkZUNvdW50cnlCdWRnZXRGaWVsZCh2YWwudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAvLyBoaWRlL3Nob3cgb24gdmFsdWUgY2hhbmdlXG4gICAgICAgICAgICBjb3VudHJ5QnVkZ2V0Vm9jYWJ1bGFyeS5vbignc2VsZWN0MjpzZWxlY3QnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbCA9IGUucGFyYW1zLmRhdGEuaWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ291bnRyeUJ1ZGdldEZpZWxkKHZhbCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vaGlkZS9zaG93IGJhc2VkIG9uIHZhbHVlIGNsZWFyZWRcbiAgICAgICAgICAgIGNvdW50cnlCdWRnZXRWb2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOmNsZWFyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUNvdW50cnlCdWRnZXRGaWVsZCgnJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIaWRlIENvdW50cnkgQnVkZ2V0IEZpZWxkc1xuICAgICAqL1xuICAgIGhpZGVDb3VudHJ5QnVkZ2V0RmllbGQodmFsdWUpIHtcbiAgICAgICAgY29uc3QgY291bnRyeUJ1ZGdldENvZGVJbnB1dCA9ICdpbnB1dFtpZF49XCJidWRnZXRfaXRlbVwiXVtpZCo9XCJbY29kZV90ZXh0XVwiXScsIGNvdW50cnlCdWRnZXRDb2RlU2VsZWN0ID0gJ3NlbGVjdFtpZF49XCJidWRnZXRfaXRlbVwiXVtpZCo9XCJbY29kZV1cIl0nO1xuICAgICAgICBpZiAodmFsdWUgPT09ICcxJykge1xuICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGNvdW50cnlCdWRnZXRDb2RlU2VsZWN0KVxuICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoY291bnRyeUJ1ZGdldENvZGVJbnB1dClcbiAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KShjb3VudHJ5QnVkZ2V0Q29kZVNlbGVjdClcbiAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KShjb3VudHJ5QnVkZ2V0Q29kZUlucHV0KVxuICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFpZFR5cGUgRm9ybSBQYWdlXG4gICAgICpcbiAgICAgKiBATG9naWMgaGlkZSB2b2NhYnVsYXJ5LXVyaSBhbmQgY29kZXMgZmllbGQgYmFzZWQgb24gJ0B2b2NhYnVsYXJ5JyBmaWVsZCB2YWx1ZVxuICAgICAqL1xuICAgIGFpZFR5cGVWb2NhYnVsYXJ5SGlkZUZpZWxkKCkge1xuICAgICAgICBjb25zdCBhaWR0eXBlX3ZvY2FidWxhcnkgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3NlbGVjdFtpZCo9XCJkZWZhdWx0X2FpZF90eXBlX3ZvY2FidWxhcnlcIl0nKTtcbiAgICAgICAgaWYgKGFpZHR5cGVfdm9jYWJ1bGFyeS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBqcXVlcnlfMS5kZWZhdWx0LmVhY2goYWlkdHlwZV92b2NhYnVsYXJ5LCAoaW5kZXgsIGl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IChfYSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KShpdGVtKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJzEnO1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUFpZFR5cGVTZWxlY3RGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaXRlbSksIGRhdGEudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGFpZHR5cGVfdm9jYWJ1bGFyeS5vbignc2VsZWN0MjpzZWxlY3QnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBlLnBhcmFtcy5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUFpZFR5cGVTZWxlY3RGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGFpZHR5cGVfdm9jYWJ1bGFyeS5vbignc2VsZWN0MjpjbGVhcicsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQWlkVHlwZVNlbGVjdEZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLCAnJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBaWRUeXBlIEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgYW5kIGNvZGVzIGZpZWxkIGJhc2VkIG9uICdAdm9jYWJ1bGFyeScgZmllbGQgdmFsdWVcbiAgICAgKi9cbiAgICB0cmFuc2FjdGlvbkFpZFR5cGVWb2NhYnVsYXJ5SGlkZUZpZWxkKCkge1xuICAgICAgICBjb25zdCBhaWR0eXBlX3ZvY2FidWxhcnkgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3NlbGVjdFtpZCo9XCJhaWRfdHlwZV92b2NhYnVsYXJ5XCJdJyk7XG4gICAgICAgIGlmIChhaWR0eXBlX3ZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAganF1ZXJ5XzEuZGVmYXVsdC5lYWNoKGFpZHR5cGVfdm9jYWJ1bGFyeSwgKGluZGV4LCBpdGVtKSA9PiB7XG4gICAgICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSAoX2EgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaXRlbSkudmFsKCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6ICcxJztcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUcmFuc2FjdGlvbkFpZFR5cGVTZWxlY3RGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoaXRlbSksIGRhdGEudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGFpZHR5cGVfdm9jYWJ1bGFyeS5vbignc2VsZWN0MjpzZWxlY3QnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBlLnBhcmFtcy5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVRyYW5zYWN0aW9uQWlkVHlwZVNlbGVjdEZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLCBkYXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYWlkdHlwZV92b2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOmNsZWFyJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUcmFuc2FjdGlvbkFpZFR5cGVTZWxlY3RGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgJycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGlkZSBBaWQgVHlwZSBTZWxlY3QgRmllbGRzXG4gICAgICovXG4gICAgaGlkZUFpZFR5cGVTZWxlY3RGaWVsZChpbmRleCwgdmFsdWUpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdF9haWRfdHlwZSA9ICdzZWxlY3RbaWQqPVwiW2RlZmF1bHRfYWlkX3R5cGVdXCJdJywgZWFybWFya2luZ19jYXRlZ29yeSA9ICdzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfY2F0ZWdvcnldXCJdJywgZWFybWFya2luZ19tb2RhbGl0eSA9ICdzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfbW9kYWxpdHldXCJdJywgY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzID0gJ3NlbGVjdFtpZCo9XCJbY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzXVwiXScsIGNhc2UxID0gJ3NlbGVjdFtpZCo9XCJbZWFybWFya2luZ19jYXRlZ29yeV1cIl0sc2VsZWN0W2lkKj1cIltlYXJtYXJraW5nX21vZGFsaXR5XVwiXSxzZWxlY3RbaWQqPVwiW2Nhc2hfYW5kX3ZvdWNoZXJfbW9kYWxpdGllc11cIl0nLCBjYXNlMiA9ICdzZWxlY3RbaWQqPVwiW2RlZmF1bHRfYWlkX3R5cGVdXCJdLHNlbGVjdFtpZCo9XCJbZWFybWFya2luZ19tb2RhbGl0eV1cIl0sc2VsZWN0W2lkKj1cIltjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXNdXCJdJywgY2FzZTMgPSAnc2VsZWN0W2lkKj1cIltkZWZhdWx0X2FpZF90eXBlXVwiXSxzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfY2F0ZWdvcnldXCJdLHNlbGVjdFtpZCo9XCJbY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzXVwiXScsIGNhc2U0ID0gJ3NlbGVjdFtpZCo9XCJbZGVmYXVsdF9haWRfdHlwZV1cIl0sc2VsZWN0W2lkKj1cIltlYXJtYXJraW5nX2NhdGVnb3J5XVwiXSxzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfbW9kYWxpdHldXCJdJztcbiAgICAgICAgc3dpdGNoICh2YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSAnMic6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoZWFybWFya2luZ19jYXRlZ29yeSlcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMyc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoZWFybWFya2luZ19tb2RhbGl0eSlcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UzKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnNCc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTQpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGRlZmF1bHRfYWlkX3R5cGUpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMSlcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIaWRlIFRyYW5zYWN0aW9uIEFpZCBUeXBlIFNlbGVjdCBGaWVsZHNcbiAgICAgKi9cbiAgICBoaWRlVHJhbnNhY3Rpb25BaWRUeXBlU2VsZWN0RmllbGQoaW5kZXgsIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGFpZF90eXBlID0gJ3NlbGVjdFtpZCo9XCJbYWlkX3R5cGVfY29kZV1cIl0nLCBlYXJtYXJraW5nX2NhdGVnb3J5ID0gJ3NlbGVjdFtpZCo9XCJbZWFybWFya2luZ19jYXRlZ29yeV1cIl0nLCBlYXJtYXJraW5nX21vZGFsaXR5ID0gJ3NlbGVjdFtpZCo9XCJbZWFybWFya2luZ19tb2RhbGl0eV1cIl0nLCBjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXMgPSAnc2VsZWN0W2lkKj1cIltjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXNdXCJdJywgY2FzZTEgPSAnc2VsZWN0W2lkKj1cIltlYXJtYXJraW5nX2NhdGVnb3J5XVwiXSxzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfbW9kYWxpdHldXCJdLHNlbGVjdFtpZCo9XCJbY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzXVwiXScsIGNhc2UyID0gJ3NlbGVjdFtpZCo9XCJbYWlkX3R5cGVfY29kZV1cIl0sc2VsZWN0W2lkKj1cIltlYXJtYXJraW5nX21vZGFsaXR5XVwiXSxzZWxlY3RbaWQqPVwiW2Nhc2hfYW5kX3ZvdWNoZXJfbW9kYWxpdGllc11cIl0nLCBjYXNlMyA9ICdzZWxlY3RbaWQqPVwiW2FpZF90eXBlX2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbZWFybWFya2luZ19jYXRlZ29yeV1cIl0sc2VsZWN0W2lkKj1cIltjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXNdXCJdJywgY2FzZTQgPSAnc2VsZWN0W2lkKj1cIlthaWRfdHlwZV9jb2RlXVwiXSxzZWxlY3RbaWQqPVwiW2Vhcm1hcmtpbmdfY2F0ZWdvcnldXCJdLHNlbGVjdFtpZCo9XCJbZWFybWFya2luZ19tb2RhbGl0eV1cIl0nO1xuICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlICcyJzpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChlYXJtYXJraW5nX2NhdGVnb3J5KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTIpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICczJzpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChlYXJtYXJraW5nX21vZGFsaXR5KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTMpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICc0JzpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNoX2FuZF92b3VjaGVyX21vZGFsaXRpZXMpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlNClcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoYWlkX3R5cGUpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMSlcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBQb2xpY3kgTWFya2VyIEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgYW5kIGNvZGVzIGZpZWxkIGJhc2VkIG9uICdAdm9jYWJ1bGFyeScgZmllbGQgdmFsdWVcbiAgICAgKi9cbiAgICBwb2xpY3lWb2NhYnVsYXJ5SGlkZUZpZWxkKCkge1xuICAgICAgICBjb25zdCBwb2xpY3ltYWtlcl92b2NhYnVsYXJ5ID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdzZWxlY3RbaWQqPVwicG9saWN5X21hcmtlcl92b2NhYnVsYXJ5XCJdJyk7XG4gICAgICAgIGlmIChwb2xpY3ltYWtlcl92b2NhYnVsYXJ5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGpxdWVyeV8xLmRlZmF1bHQuZWFjaChwb2xpY3ltYWtlcl92b2NhYnVsYXJ5LCAoaW5kZXgsIHBvbGljeV9tYXJrZXIpID0+IHtcbiAgICAgICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IChfYSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KShwb2xpY3lfbWFya2VyKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJzEnO1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVBvbGljeU1ha2VyRmllbGQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHBvbGljeV9tYXJrZXIpLCBkYXRhLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwb2xpY3ltYWtlcl92b2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOnNlbGVjdCcsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IGUucGFyYW1zLmRhdGEuaWQ7XG4gICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlUG9saWN5TWFrZXJGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBvbGljeW1ha2VyX3ZvY2FidWxhcnkub24oJ3NlbGVjdDI6Y2xlYXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVBvbGljeU1ha2VyRmllbGQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCksICc5OScpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGlkZXMgUG9saWN5IE1hcmtlciBGb3JtIEZpZWxkc1xuICAgICAqL1xuICAgIGhpZGVQb2xpY3lNYWtlckZpZWxkKGluZGV4LCB2YWx1ZSkge1xuICAgICAgICBjb25zdCBjYXNlMV9zaG93ID0gJ3NlbGVjdFtpZCo9XCJbcG9saWN5X21hcmtlcl1cIl0nLCBjYXNlMl9zaG93ID0gJ2lucHV0W2lkKj1cIltwb2xpY3lfbWFya2VyX3RleHRdXCJdLGlucHV0W2lkKj1cIlt2b2NhYnVsYXJ5X3VyaV1cIl0nLCBjYXNlMSA9ICdpbnB1dFtpZCo9XCJbcG9saWN5X21hcmtlcl90ZXh0XVwiXSxpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJywgY2FzZTIgPSAnc2VsZWN0W2lkKj1cIltwb2xpY3lfbWFya2VyXVwiXSc7XG4gICAgICAgIHN3aXRjaCAodmFsdWUpIHtcbiAgICAgICAgICAgIGNhc2UgJzEnOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UxX3Nob3cpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMSlcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJzk5JzpcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTJfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlY3RvciBGb3JtIFBhZ2VcbiAgICAgKlxuICAgICAqIEBMb2dpYyBoaWRlIHZvY2FidWxhcnktdXJpIGFuZCBjb2RlcyBmaWVsZCBiYXNlZCBvbiAnQHZvY2FidWxhcnknIGZpZWxkIHZhbHVlXG4gICAgICovXG4gICAgc2VjdG9yVm9jYWJ1bGFyeUhpZGVGaWVsZCgpIHtcbiAgICAgICAgY29uc3Qgc2VjdG9yX3ZvY2FidWxhcnkgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3NlbGVjdFtpZCo9XCJzZWN0b3Jfdm9jYWJ1bGFyeVwiXScpO1xuICAgICAgICBpZiAoc2VjdG9yX3ZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAganF1ZXJ5XzEuZGVmYXVsdC5lYWNoKHNlY3Rvcl92b2NhYnVsYXJ5LCAoaW5kZXgsIHNlY3RvcikgPT4ge1xuICAgICAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gKF9hID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHNlY3RvcikudmFsKCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6ICcxJztcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVTZWN0b3JGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoc2VjdG9yKSwgZGF0YS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2VjdG9yX3ZvY2FidWxhcnkub24oJ3NlbGVjdDI6c2VsZWN0JywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gZS5wYXJhbXMuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVTZWN0b3JGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHNlY3Rvcl92b2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOmNsZWFyJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVTZWN0b3JGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgJycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGlkZSBTZWN0b3IgRm9ybSBmaWVsZHNcbiAgICAgKi9cbiAgICBoaWRlU2VjdG9yRmllbGQoaW5kZXgsIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGNhc2UxX3Nob3cgPSAnc2VsZWN0W2lkKj1cIltjb2RlXVwiXScsIGNhc2UyX3Nob3cgPSAnc2VsZWN0W2lkKj1cIltjYXRlZ29yeV9jb2RlXVwiXScsIGNhc2U3X3Nob3cgPSAnc2VsZWN0W2lkKj1cIltzZGdfZ29hbF1cIl0nLCBjYXNlOF9zaG93ID0gJ3NlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0nLCBjYXNlOThfOTlfc2hvdyA9ICdpbnB1dFtpZCo9XCJbdGV4dF1cIl0saW5wdXRbaWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXScsIGRlZmF1bHRfc2hvdyA9ICdpbnB1dFtpZCo9XCJbdGV4dF1cIl0nLCBjYXNlMSA9ICdzZWxlY3RbaWQqPVwiW2NhdGVnb3J5X2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX2dvYWxdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0saW5wdXRbaWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXSxpbnB1dFtpZCo9XCJbdGV4dF1cIl0nLCBjYXNlMiA9ICdpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdLHNlbGVjdFtpZCo9XCJbc2RnX2dvYWxdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0sc2VsZWN0W2lkKj1cIltjb2RlXVwiXSxpbnB1dFtpZCo9XCJbdGV4dF1cIl0nLCBjYXNlNyA9ICdpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdLHNlbGVjdFtpZCo9XCJbY2F0ZWdvcnlfY29kZV1cIl0sc2VsZWN0W2lkKj1cIltzZGdfdGFyZ2V0XVwiXSxzZWxlY3RbaWQqPVwiW2NvZGVdXCJdLGlucHV0W2lkKj1cIlt0ZXh0XVwiXScsIGNhc2U4ID0gJ2lucHV0W2lkKj1cIlt2b2NhYnVsYXJ5X3VyaV1cIl0sc2VsZWN0W2lkKj1cIltjYXRlZ29yeV9jb2RlXVwiXSxzZWxlY3RbaWQqPVwiW3NkZ19nb2FsXVwiXSxzZWxlY3RbaWQqPVwiW2NvZGVdXCJdLGlucHV0W2lkKj1cIlt0ZXh0XVwiXScsIGNhc2U5OF85OSA9ICdzZWxlY3RbaWQqPVwiW2NhdGVnb3J5X2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX2dvYWxdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0sc2VsZWN0W2lkKj1cIltjb2RlXVwiXScsIGRlZmF1bHRfaGlkZSA9ICdzZWxlY3RbaWQqPVwiW2NhdGVnb3J5X2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX2dvYWxdXCJdLHNlbGVjdFtpZCo9XCJbc2RnX3RhcmdldF1cIl0sc2VsZWN0W2lkKj1cIltjb2RlXVwiXSxpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJztcbiAgICAgICAgc3dpdGNoICh2YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSAnMSc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTFfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UxKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMic6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTJfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnNyc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTdfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U3KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOCc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZThfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U4KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOTgnOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U5OF85OV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTk4Xzk5KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOTknOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U5OF85OV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTk4Xzk5KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChkZWZhdWx0X3Nob3cpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KClcbiAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2Rpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKTtcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChkZWZhdWx0X2hpZGUpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogIFJlY2lwaWVudCBWb2NhYnVsYXJ5IEZvcm0gUGFnZVxuICAgICAqXG4gICAgICogQExvZ2ljIGhpZGUgdm9jYWJ1bGFyeS11cmkgYW5kIGNvZGVzIGZpZWxkIGJhc2VkIG9uICdAdm9jYWJ1bGFyeScgZmllbGQgdmFsdWVcbiAgICAgKi9cbiAgICByZWNpcGllbnRWb2NhYnVsYXJ5SGlkZUZpZWxkKCkge1xuICAgICAgICBjb25zdCByZWdpb25fdm9jYWJ1bGFyeSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnc2VsZWN0W2lkKj1cInJlZ2lvbl92b2NhYnVsYXJ5XCJdJyk7XG4gICAgICAgIGlmIChyZWdpb25fdm9jYWJ1bGFyeS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBqcXVlcnlfMS5kZWZhdWx0LmVhY2gocmVnaW9uX3ZvY2FidWxhcnksIChpbmRleCwgcmVnaW9uX3ZvY2FiKSA9PiB7XG4gICAgICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSAoX2EgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkocmVnaW9uX3ZvY2FiKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJzEnO1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVJlY2lwaWVudFJlZ2lvbkZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KShyZWdpb25fdm9jYWIpLCBkYXRhLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZWdpb25fdm9jYWJ1bGFyeS5vbignc2VsZWN0MjpzZWxlY3QnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBlLnBhcmFtcy5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVJlY2lwaWVudFJlZ2lvbkZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLCBkYXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVnaW9uX3ZvY2FidWxhcnkub24oJ3NlbGVjdDI6Y2xlYXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVJlY2lwaWVudFJlZ2lvbkZpZWxkKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLCAnJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIaWRlcyBSZWNpcGllbnQgUmVnaW9uIEZvcm0gRmllbGRzXG4gICAgICovXG4gICAgaGlkZVJlY2lwaWVudFJlZ2lvbkZpZWxkKGluZGV4LCB2YWx1ZSkge1xuICAgICAgICBjb25zdCBjYXNlMV9zaG93ID0gJ3NlbGVjdFtpZCo9XCJbcmVnaW9uX2NvZGVdXCJdJywgY2FzZTJfc2hvdyA9ICdpbnB1dFtpZCo9XCJbY3VzdG9tX2NvZGVdXCJdLCBpbnB1dFtpZCo9XCJbY29kZV1cIl0nLCBjYXNlOTlfc2hvdyA9ICdpbnB1dFtpZCo9XCJbY3VzdG9tX2NvZGVdXCJdLGlucHV0W2lkKj1cIlt2b2NhYnVsYXJ5X3VyaV1cIl0sIGlucHV0W2lkKj1cIltjb2RlXVwiXScsIGNhc2UxID0gJ2lucHV0W2lkKj1cIltjdXN0b21fY29kZV1cIl0saW5wdXRbaWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXSxpbnB1dFtpZCo9XCJbY29kZV1cIl0nLCBjYXNlMiA9ICdzZWxlY3RbaWQqPVwiW3JlZ2lvbl9jb2RlXVwiXSxpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJywgY2FzZTk5ID0gJ3NlbGVjdFtpZCo9XCJbcmVnaW9uX2NvZGVdXCJdJztcbiAgICAgICAgc3dpdGNoICh2YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSAnMSc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTFfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UxKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMic6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTJfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOTknOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U5OV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTk5KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMl9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTIpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlcyBBY3Rpdml0eSBpZGVudGlmaWVyXG4gICAgICovXG4gICAgdXBkYXRlQWN0aXZpdHlJZGVudGlmaWVyKCkge1xuICAgICAgICBjb25zdCBhY3Rpdml0eV9pZGVudGlmaWVyID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjYWN0aXZpdHlfaWRlbnRpZmllcicpO1xuICAgICAgICBpZiAoYWN0aXZpdHlfaWRlbnRpZmllci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBhY3Rpdml0eV9pZGVudGlmaWVyLm9uKCdrZXl1cCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJyNpYXRpX2lkZW50aWZpZXJfdGV4dCcpLnZhbCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5pZGVudGlmaWVyJykuYXR0cignYWN0aXZpdHlfaWRlbnRpZmllcicpICsgYC0keygwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS52YWwoKX1gKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRhZyBGb3JtIFBhZ2VcbiAgICAgKlxuICAgICAqIEBMb2dpYyBoaWRlIHZvY2FidWxhcnktdXJpIGFuZCBjb2RlcyBmaWVsZCBiYXNlZCBvbiAnQHZvY2FidWxhcnknIGZpZWxkIHZhbHVlXG4gICAgICovXG4gICAgdGFnVm9jYWJ1bGFyeUhpZGVGaWVsZCgpIHtcbiAgICAgICAgY29uc3QgdGFnX3ZvY2FidWxhcnkgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3NlbGVjdFtpZCo9XCJ0YWdfdm9jYWJ1bGFyeVwiXScpO1xuICAgICAgICBpZiAodGFnX3ZvY2FidWxhcnkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAganF1ZXJ5XzEuZGVmYXVsdC5lYWNoKHRhZ192b2NhYnVsYXJ5LCAoaW5kZXgsIHRhZykgPT4ge1xuICAgICAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gKF9hID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhZykudmFsKCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6ICcxJztcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUYWdGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFnKSwgZGF0YS50b1N0cmluZygpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGFnX3ZvY2FidWxhcnkub24oJ3NlbGVjdDI6c2VsZWN0JywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gZS5wYXJhbXMuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUYWdGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgZGF0YSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRhZ192b2NhYnVsYXJ5Lm9uKCdzZWxlY3QyOmNsZWFyJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVUYWdGaWVsZCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KSwgJycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGlkZSBUYWcgRm9ybSBmaWVsZHNcbiAgICAgKi9cbiAgICBoaWRlVGFnRmllbGQoaW5kZXgsIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGNhc2UxX3Nob3cgPSAnaW5wdXRbaWQqPVwiW3RhZ190ZXh0XVwiXScsIGNhc2UyX3Nob3cgPSAnc2VsZWN0W2lkKj1cIltnb2Fsc190YWdfY29kZV1cIl0nLCBjYXNlM19zaG93ID0gJ3NlbGVjdFtpZCo9XCJbdGFyZ2V0c190YWdfY29kZV1cIl0nLCBjYXNlOTlfc2hvdyA9ICdpbnB1dFtpZCo9XCJbdGFnX3RleHRdXCJdLCBpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJywgY2FzZTEgPSAnc2VsZWN0W2lkKj1cIltnb2Fsc190YWdfY29kZV1cIl0sc2VsZWN0W2lkKj1cIlt0YXJnZXRzX3RhZ19jb2RlXVwiXSxpbnB1dFtpZCo9XCJbdm9jYWJ1bGFyeV91cmldXCJdJywgY2FzZTIgPSAnaW5wdXRbaWQqPVwiW3ZvY2FidWxhcnlfdXJpXVwiXSxzZWxlY3RbaWQqPVwiW3RhcmdldHNfdGFnX2NvZGVdXCJdLHNlbGVjdFtpZCo9XCJbdGFyZ2V0c190YWdfY29kZV1cIl0saW5wdXRbaWQqPVwiW3RhZ190ZXh0XVwiXScsIGNhc2UzID0gJ2lucHV0W2lkKj1cIlt2b2NhYnVsYXJ5X3VyaV1cIl0sc2VsZWN0W2lkKj1cIltnb2Fsc190YWdfY29kZV1cIl0saW5wdXRbaWQqPVwiW3RhZ190ZXh0XVwiXScsIGNhc2U5OSA9ICdzZWxlY3RbaWQqPVwiW2dvYWxzX3RhZ19jb2RlXVwiXSxzZWxlY3RbaWQqPVwiW3RhcmdldHNfdGFnX2NvZGVdXCJdJztcbiAgICAgICAgc3dpdGNoICh2YWx1ZSkge1xuICAgICAgICAgICAgY2FzZSAnMSc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTFfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UxKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMic6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTJfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UyKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnMyc6XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTNfc2hvdylcbiAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2UzKVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnOTknOlxuICAgICAgICAgICAgICAgIGluZGV4XG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKGNhc2U5OV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTk5KVxuICAgICAgICAgICAgICAgICAgICAudmFsKCcnKVxuICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJylcbiAgICAgICAgICAgICAgICAgICAgLmhpZGUoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKVxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbmRleFxuICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAuZmluZChjYXNlMV9zaG93KVxuICAgICAgICAgICAgICAgICAgICAuc2hvdygpXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoY2FzZTEpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKVxuICAgICAgICAgICAgICAgICAgICAuaGlkZSgpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZCcpXG4gICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnRzLkR5bmFtaWNGaWVsZCA9IER5bmFtaWNGaWVsZDtcbi8qXG4gKlxuICogSGVscCBUZXh0IE9wZW4gQ2xvc2UgSGFuZGxlcnMgU3RhcnRcbiAqXG4gKi9cbigwLCBqcXVlcnlfMS5kZWZhdWx0KShkb2N1bWVudCkub24oJ2NsaWNrJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKCEoMCwganF1ZXJ5XzEuZGVmYXVsdCkoZXZlbnQudGFyZ2V0KS5jbG9zZXN0KCcuaGVscCcpLmxlbmd0aCkge1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5oZWxwX190ZXh0JykucmVtb3ZlQXR0cignc3R5bGUnKTtcbiAgICB9XG59KTtcbigwLCBqcXVlcnlfMS5kZWZhdWx0KShkb2N1bWVudCkub24oJ2NsaWNrJywgJy5oZWxwJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc29sZS5sb2coJ0hlbGxvJyk7XG4gICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuaGVscF9fdGV4dCcpLnJlbW92ZUF0dHIoJ3N0eWxlJyk7XG4gICAgY29uc3QgaGVscFRleHQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcykuZmluZCgnLmhlbHBfX3RleHQnKTtcbiAgICBpZiAoaGVscFRleHQubGVuZ3RoID4gMCkge1xuICAgICAgICBoZWxwVGV4dC5jc3Moe1xuICAgICAgICAgICAgb3BhY2l0eTogJzEnLFxuICAgICAgICAgICAgdmlzaWJpbGl0eTogJ3Zpc2libGUnLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgaWYgKCgwLCBqcXVlcnlfMS5kZWZhdWx0KShldmVudC50YXJnZXQpLmNsb3Nlc3QoJy5jbG9zZS1oZWxwJykubGVuZ3RoKSB7XG4gICAgICAgIGNsb3NlSGVscFRleHQoaGVscFRleHQpO1xuICAgIH1cbn0pO1xuKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGRvY3VtZW50KS5vbigna2V5ZG93bicsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmhlbHBfX3RleHQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNsb3NlSGVscFRleHQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpKTtcbiAgICAgICAgfSk7XG4gICAgfVxufSk7XG4vKipcbiAqIENsb3NlcyB0aGUgaGVscCB0ZXh0IHRvb2x0aXAgYnkgc2V0dGluZyBpdHMgQ1NTIHByb3BlcnRpZXMgdG8gbWFrZSBpdCBpbnZpc2libGUgYW5kIG5vbi1pbnRlcmFjdGl2ZS5cbiAqIEFmdGVyIGEgZGVsYXksIGl0IHJlbW92ZXMgdGhlIGlubGluZSBzdHlsZXMgdG8gcmVzZXQgdGhlIGVsZW1lbnQncyBzdGF0ZS5cbiAqXG4gKiBAcGFyYW0gaGVscFRleHQgLSBUaGUgalF1ZXJ5IG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHRvb2x0aXAgZWxlbWVudCB0byBiZSBjbG9zZWQuXG4gKi9cbmZ1bmN0aW9uIGNsb3NlSGVscFRleHQoaGVscFRleHQpIHtcbiAgICBoZWxwVGV4dC5jc3Moe1xuICAgICAgICAncG9pbnRlci1ldmVudHMnOiAnbm9uZScsXG4gICAgICAgIG9wYWNpdHk6ICcwJyxcbiAgICAgICAgdmlzaWJpbGl0eTogJ2ludmlzaWJsZScsXG4gICAgfSk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGhlbHBUZXh0LnJlbW92ZUF0dHIoJ3N0eWxlJyk7XG4gICAgfSwgMTAwMCk7XG59XG4vKlxuICpcbiAqIEhlbHAgVGV4dCBPcGVuIENsb3NlIEhhbmRsZXJzIEVuZFxuICpcbiAqL1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgX19pbXBvcnREZWZhdWx0ID0gKHRoaXMgJiYgdGhpcy5fX2ltcG9ydERlZmF1bHQpIHx8IGZ1bmN0aW9uIChtb2QpIHtcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcbn07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jb25zdCBheGlvc18xID0gX19pbXBvcnREZWZhdWx0KHJlcXVpcmUoXCJheGlvc1wiKSk7XG5jb25zdCBqcXVlcnlfMSA9IF9faW1wb3J0RGVmYXVsdChyZXF1aXJlKFwianF1ZXJ5XCIpKTtcbnJlcXVpcmUoXCJzZWxlY3QyXCIpO1xuY29uc3QgRHluYW1pY0ZpZWxkXzEgPSByZXF1aXJlKFwiLi9EeW5hbWljRmllbGRcIik7XG5jb25zdCBkeW5hbWljRmllbGQgPSBuZXcgRHluYW1pY0ZpZWxkXzEuRHluYW1pY0ZpZWxkKCk7XG5jbGFzcyBGb3JtQnVpbGRlciB7XG4gICAgLy8gYWRkcyBuZXcgY29sbGVjdGlvbiBvZiBzdWItZWxlbWVudFxuICAgIGFkZEZvcm0oZXYpIHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXYudGFyZ2V0O1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdmb3JtX3R5cGUnKVxuICAgICAgICAgICAgPyAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoYC5jb2xsZWN0aW9uLWNvbnRhaW5lcltmb3JtX3R5cGUgPSckeygwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2Zvcm1fdHlwZScpfSddYClcbiAgICAgICAgICAgIDogKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuY29sbGVjdGlvbi1jb250YWluZXInKTtcbiAgICAgICAgY29uc3QgY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdjaGlsZF9jb3VudCcpXG4gICAgICAgICAgICA/IHBhcnNlSW50KCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2NoaWxkX2NvdW50JykpICsgMVxuICAgICAgICAgICAgOiAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5wYXJlbnQoKS5maW5kKCcuZm9ybS1jaGlsZC1ib2R5JykubGVuZ3RoO1xuICAgICAgICBjb25zdCBwYXJlbnRfY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdwYXJlbnRfY291bnQnKVxuICAgICAgICAgICAgPyBwYXJzZUludCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdwYXJlbnRfY291bnQnKSlcbiAgICAgICAgICAgIDogKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkucGFyZW50cygnLm11bHRpLWZvcm0nKS5pbmRleCgpIC0gMTtcbiAgICAgICAgY29uc3Qgd3JhcHBlcl9wYXJlbnRfY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCd3cmFwcGVkX3BhcmVudF9jb3VudCcpXG4gICAgICAgICAgICA/IHBhcnNlSW50KCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ3dyYXBwZWRfcGFyZW50X2NvdW50JykpXG4gICAgICAgICAgICA6ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnBhcmVudHMoJy53cmFwcGVkLWNoaWxkLWJvZHknKS5pbmRleCgpIC0gMTtcbiAgICAgICAgbGV0IHByb3RvID0gY29udGFpbmVyXG4gICAgICAgICAgICAuZGF0YSgncHJvdG90eXBlJylcbiAgICAgICAgICAgIC5yZXBsYWNlKC9fX1BBUkVOVF9OQU1FX18vZywgcGFyZW50X2NvdW50KTtcbiAgICAgICAgaWYgKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2hhc19jaGlsZF9jb2xsZWN0aW9uJykpIHtcbiAgICAgICAgICAgIHByb3RvID0gcHJvdG8ucmVwbGFjZSgvX19XUkFQUEVSX05BTUVfXy9nLCBjb3VudCk7XG4gICAgICAgICAgICBwcm90byA9IHByb3RvLnJlcGxhY2UoL19fTkFNRV9fL2csIDApO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHJvdG8gPSBwcm90by5yZXBsYWNlKC9fX05BTUVfXy9nLCBjb3VudCk7XG4gICAgICAgICAgICBwcm90byA9IHByb3RvLnJlcGxhY2UoL19fV1JBUFBFUl9OQU1FX18vZywgd3JhcHBlcl9wYXJlbnRfY291bnQpO1xuICAgICAgICB9XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5hcHBlbmQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHByb3RvKSk7XG4gICAgICAgIGlmICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdoYXNfY2hpbGRfY29sbGVjdGlvbicpKSB7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KVxuICAgICAgICAgICAgICAgIC5wcmV2KCcuc3ViZWxlbWVudCcpXG4gICAgICAgICAgICAgICAgLmNoaWxkcmVuKCcud3JhcHBlZC1jaGlsZC1ib2R5JylcbiAgICAgICAgICAgICAgICAubGFzdCgpXG4gICAgICAgICAgICAgICAgLmZpbmQoJy5hZGRfdG9fY29sbGVjdGlvbicpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ3dyYXBwZWRfcGFyZW50X2NvdW50JywgY291bnQpO1xuICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldClcbiAgICAgICAgICAgICAgICAucHJldignLnN1YmVsZW1lbnQnKVxuICAgICAgICAgICAgICAgIC5jaGlsZHJlbignLndyYXBwZWQtY2hpbGQtYm9keScpXG4gICAgICAgICAgICAgICAgLmxhc3QoKVxuICAgICAgICAgICAgICAgIC5maW5kKCcuYWRkX3RvX2NvbGxlY3Rpb24nKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdwYXJlbnRfY291bnQnLCBwYXJlbnRfY291bnQpO1xuICAgICAgICB9XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpXG4gICAgICAgICAgICAucHJldigpXG4gICAgICAgICAgICAuZmluZCgnLndyYXBwZWQtY2hpbGQtYm9keScpXG4gICAgICAgICAgICAubGFzdCgpXG4gICAgICAgICAgICAuZmluZCgnLmFkZF90b19jb2xsZWN0aW9uJylcbiAgICAgICAgICAgIC5hdHRyKCd3cmFwcGVyX3BhcmVudF9jb3VudCcsIHdyYXBwZXJfcGFyZW50X2NvdW50ICE9PSBudWxsICYmIHdyYXBwZXJfcGFyZW50X2NvdW50ICE9PSB2b2lkIDAgPyB3cmFwcGVyX3BhcmVudF9jb3VudCA6IDApO1xuICAgICAgICBpZiAoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkuYXR0cignZm9ybV90eXBlJykpIHtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5sYXN0KCkuZmluZCgnLnNlbGVjdDInKS5zZWxlY3QyKHtcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBhbiBvcHRpb24nLFxuICAgICAgICAgICAgICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCcuc3ViLWF0dHJpYnV0ZScpXG4gICAgICAgICAgICAgICAgLndyYXBBbGwoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCc8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1ncm91cCBmbGV4IGZsZXgtd3JhcCBzdWItYXR0cmlidXRlLXdyYXBwZXJcIj48L2Rpdj4nKSk7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KVxuICAgICAgICAgICAgICAgIC5wcmV2KCcuc3ViZWxlbWVudCcpXG4gICAgICAgICAgICAgICAgLmNoaWxkcmVuKCcud3JhcHBlZC1jaGlsZC1ib2R5JylcbiAgICAgICAgICAgICAgICAubGFzdCgpXG4gICAgICAgICAgICAgICAgLmZpbmQoJy5zdWItYXR0cmlidXRlJylcbiAgICAgICAgICAgICAgICAud3JhcEFsbCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJzxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLWdyb3VwIGZsZXggZmxleC13cmFwIHN1Yi1hdHRyaWJ1dGUtd3JhcHBlciBtdC02XCI+PC9kaXY+JykpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldClcbiAgICAgICAgICAgICAgICAucGFyZW50KClcbiAgICAgICAgICAgICAgICAuZmluZCgnLmZvcm0tY2hpbGQtYm9keScpXG4gICAgICAgICAgICAgICAgLmxhc3QoKVxuICAgICAgICAgICAgICAgIC5maW5kKCcuc2VsZWN0MicpXG4gICAgICAgICAgICAgICAgLnNlbGVjdDIoe1xuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiAnU2VsZWN0IGFuIG9wdGlvbicsXG4gICAgICAgICAgICAgICAgYWxsb3dDbGVhcjogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2NoaWxkX2NvdW50JywgY291bnQpO1xuICAgICAgICBkeW5hbWljRmllbGQuYWlkVHlwZVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnNlY3RvclZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICB9XG4gICAgLy8gYWRkcyBwYXJlbnQgY29sbGVjdGlvblxuICAgIGFkZFBhcmVudEZvcm0oZXYpIHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXYudGFyZ2V0O1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdmb3JtX3R5cGUnKVxuICAgICAgICAgICAgPyAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoYC5wYXJlbnQtY29sbGVjdGlvbltmb3JtX3R5cGUgPSckeygwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmF0dHIoJ2Zvcm1fdHlwZScpfSddYClcbiAgICAgICAgICAgIDogKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcucGFyZW50LWNvbGxlY3Rpb24nKTtcbiAgICAgICAgY29uc3QgY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdwYXJlbnRfY291bnQnKVxuICAgICAgICAgICAgPyBwYXJzZUludCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5hdHRyKCdwYXJlbnRfY291bnQnKSkgKyAxXG4gICAgICAgICAgICA6ICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5wcmV2KCkuZmluZCgnLm11bHRpLWZvcm0nKS5sZW5ndGhcbiAgICAgICAgICAgICAgICA/ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5maW5kKCcubXVsdGktZm9ybScpLmxlbmd0aFxuICAgICAgICAgICAgICAgIDogKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkucHJldigpLmZpbmQoJy53cmFwcGVkLWNoaWxkLWJvZHknKS5sZW5ndGgpICsgMTtcbiAgICAgICAgbGV0IHByb3RvID0gY29udGFpbmVyLmRhdGEoJ3Byb3RvdHlwZScpLnJlcGxhY2UoL19fUEFSRU5UX05BTUVfXy9nLCBjb3VudCk7XG4gICAgICAgIHByb3RvID0gcHJvdG8ucmVwbGFjZSgvX19OQU1FX18vZywgMCk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5hcHBlbmQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHByb3RvKSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLnByZXYoKS5maW5kKCcubXVsdGktZm9ybScpLmxhc3QoKS5maW5kKCcuc2VsZWN0MicpLnNlbGVjdDIoe1xuICAgICAgICAgICAgcGxhY2Vob2xkZXI6ICdTZWxlY3QgYW4gb3B0aW9uJyxcbiAgICAgICAgICAgIGFsbG93Q2xlYXI6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KVxuICAgICAgICAgICAgLnByZXYoKVxuICAgICAgICAgICAgLmZpbmQoJy5tdWx0aS1mb3JtJylcbiAgICAgICAgICAgIC5sYXN0KClcbiAgICAgICAgICAgIC5maW5kKCcuYWRkX3RvX2NvbGxlY3Rpb24nKVxuICAgICAgICAgICAgLmF0dHIoJ3BhcmVudF9jb3VudCcsIGNvdW50KTtcbiAgICAgICAgdGhpcy5hZGRXcmFwcGVyT25BZGQodGFyZ2V0KTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkuYXR0cigncGFyZW50X2NvdW50JywgY291bnQpO1xuICAgICAgICBkeW5hbWljRmllbGQuaHVtYW5pdGFyaWFuU2NvcGVIaWRlVm9jYWJ1bGFyeVVyaSgpO1xuICAgICAgICBkeW5hbWljRmllbGQuY291bnRyeUJ1ZGdldEhpZGVDb2RlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnNlY3RvclZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnJlY2lwaWVudFZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnBvbGljeVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnRhZ1ZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLnRyYW5zYWN0aW9uQWlkVHlwZVZvY2FidWxhcnlIaWRlRmllbGQoKTtcbiAgICAgICAgZHluYW1pY0ZpZWxkLmluZGljYXRvclJlZmVyZW5jZUhpZGVGaWVsZFVyaSgpO1xuICAgIH1cbiAgICAvLyBkZWxldGVzIGNvbGxlY3Rpb25cbiAgICBkZWxldGVGb3JtKGV2KSB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGV2LnRhcmdldDtcbiAgICAgICAgY29uc3QgY29sbGVjdGlvbkxlbmd0aCA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLm11bHRpLWZvcm0nKS5sZW5ndGhcbiAgICAgICAgICAgID8gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkuY2xvc2VzdCgnLnN1YmVsZW1lbnQnKS5maW5kKCcuZm9ybS1jaGlsZC1ib2R5JykubGVuZ3RoXG4gICAgICAgICAgICA6ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmZvcm0tY2hpbGQtYm9keScpLmxlbmd0aDtcbiAgICAgICAgY29uc3QgY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5hZGRfdG9fY29sbGVjdGlvbicpLmF0dHIoJ2NoaWxkX2NvdW50JylcbiAgICAgICAgICAgID8gcGFyc2VJbnQoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuYWRkX3RvX2NvbGxlY3Rpb24nKS5hdHRyKCdjaGlsZF9jb3VudCcpKSArIDFcbiAgICAgICAgICAgIDogY29sbGVjdGlvbkxlbmd0aDtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuYWRkX3RvX2NvbGxlY3Rpb24nKS5hdHRyKCdjaGlsZF9jb3VudCcsIGNvdW50KTtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb25MZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBjb25zdCB0ZyA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpLmNsb3Nlc3QoJy5mb3JtLWNoaWxkLWJvZHknKTtcbiAgICAgICAgICAgIHRnLm5leHQoJy5lcnJvcicpLnJlbW92ZSgpO1xuICAgICAgICAgICAgdGcucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gZGVsZXRlcyBwYXJlbnQgY29sbGVjdGlvblxuICAgIGRlbGV0ZVBhcmVudEZvcm0oZXYpIHtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXYudGFyZ2V0O1xuICAgICAgICBjb25zdCBjb2xsZWN0aW9uTGVuZ3RoID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuc3ViZWxlbWVudCcpLmxlbmd0aDtcbiAgICAgICAgY29uc3QgY291bnQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5hZGRfdG9fcGFyZW50JykuYXR0cignY2hpbGRfY291bnQnKVxuICAgICAgICAgICAgPyBwYXJzZUludCgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5hZGRfdG9fcGFyZW50JykuYXR0cignY2hpbGRfY291bnQnKSkgKyAxXG4gICAgICAgICAgICA6IGNvbGxlY3Rpb25MZW5ndGg7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmFkZF90b19wYXJlbnQnKS5hdHRyKCdjaGlsZF9jb3VudCcsIGNvdW50KTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuYWRkX3RvX3BhcmVudCcpLmF0dHIoJ3BhcmVudF9jb3VudCcsIGNvdW50KTtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb25MZW5ndGggPiAyKSB7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGFyZ2V0KS5wYXJlbnQoKS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvL2FkZCB3cmFwcGVyIGRpdiBhcm91bmQgdGhlIGF0dHJpYnV0ZXNcbiAgICBhZGRXcmFwcGVyKCkge1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5tdWx0aS1mb3JtJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgnLmF0dHJpYnV0ZScpXG4gICAgICAgICAgICAgICAgLndyYXBBbGwoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCc8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1ncm91cCBmbGV4IGZsZXgtd3JhcCBhdHRyaWJ1dGUtd3JhcHBlciBtYi00XCI+PC9kaXY+JykpO1xuICAgICAgICB9KTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuc3ViZWxlbWVudCcpXG4gICAgICAgICAgICAuZmluZCgnLndyYXBwZWQtY2hpbGQtYm9keScpXG4gICAgICAgICAgICAuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgnLnN1Yi1hdHRyaWJ1dGUnKVxuICAgICAgICAgICAgICAgIC53cmFwQWxsKCgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtZ3JvdXAgZmxleCBmbGV4LXdyYXAgc3ViLWF0dHJpYnV0ZS13cmFwcGVyIG1iLTRcIj48L2Rpdj4nKSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBmb3JtRmllbGQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2Zvcm0+LmZvcm0tZmllbGQnKTtcbiAgICAgICAgaWYgKGZvcm1GaWVsZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBmb3JtRmllbGQud3JhcEFsbCgnPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtZ3JvdXAtb3V0ZXIgZ3JpZCB4bDpncmlkLWNvbHMtMiBtYi02IC1teC0zIGdhcC15LTZcIj48L2Rpdj4nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRXcmFwcGVyT25BZGQodGFyZ2V0KSB7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpXG4gICAgICAgICAgICAucHJldigpXG4gICAgICAgICAgICAuZmluZCgnLm11bHRpLWZvcm0nKVxuICAgICAgICAgICAgLmxhc3QoKVxuICAgICAgICAgICAgLmZpbmQoJy5hdHRyaWJ1dGUnKVxuICAgICAgICAgICAgLndyYXBBbGwoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCc8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1ncm91cCBncmlkIHhsOmdyaWQtY29scy0yIGF0dHJpYnV0ZS13cmFwcGVyIG1iLTRcIj48L2Rpdj4nKSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0YXJnZXQpXG4gICAgICAgICAgICAucHJldigpXG4gICAgICAgICAgICAuZmluZCgnLm11bHRpLWZvcm0nKVxuICAgICAgICAgICAgLmxhc3QoKVxuICAgICAgICAgICAgLmZpbmQoJy5zdWJlbGVtZW50JylcbiAgICAgICAgICAgIC5maW5kKCcud3JhcHBlZC1jaGlsZC1ib2R5JylcbiAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCcuc3ViLWF0dHJpYnV0ZScpXG4gICAgICAgICAgICAgICAgLndyYXBBbGwoKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCc8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1ncm91cCBmbGV4IGZsZXgtd3JhcCBzdWItYXR0cmlidXRlLXdyYXBwZXIgbWItNFwiPjwvZGl2PicpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHRleHRBcmVhSGVpZ2h0KGV2KSB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGV2LnRhcmdldDtcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gdGFyZ2V0LnNjcm9sbEhlaWdodDtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRhcmdldCkuY3NzKCdoZWlnaHQnLCBoZWlnaHQpO1xuICAgIH1cbiAgICBhZGRUb0NvbGxlY3Rpb24oKSB7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdjbGljaycsICcuYWRkX3RvX2NvbGxlY3Rpb24nLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoZXZlbnQudGFyZ2V0KS5oYXNDbGFzcygnYWRkLWljb24nKSkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KShldmVudC50YXJnZXQpXG4gICAgICAgICAgICAgICAgICAgIC5wYXJlbnQoJ2J1dHRvbicpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjbGljaycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRGb3JtKGV2ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZURlbGV0ZVBhcmVudEJ1dHRvbnMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmFkZF90b19wYXJlbnQnKS5vbignY2xpY2snLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoZXZlbnQudGFyZ2V0KS5oYXNDbGFzcygnYWRkLWljb24nKSkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KShldmVudC50YXJnZXQpXG4gICAgICAgICAgICAgICAgICAgIC5wYXJlbnQoJ2J1dHRvbicpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjbGljaycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRQYXJlbnRGb3JtKGV2ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZURlbGV0ZVBhcmVudEJ1dHRvbnMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRlbGV0ZUNvbGxlY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IGRlbGV0ZUNvbmZpcm1hdGlvbiA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmRlbGV0ZS1jb25maXJtYXRpb24nKSwgY2FuY2VsUG9wdXAgPSAnLmNhbmNlbC1wb3B1cCcsIGRlbGV0ZUNvbmZpcm0gPSAnLmRlbGV0ZS1jb25maXJtJztcbiAgICAgICAgbGV0IGRlbGV0ZUluZGV4ID0ge30sIGNoaWxkT3JQYXJlbnQgPSAnJztcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ2NsaWNrJywgJy5kZWxldGUnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGRlbGV0ZUNvbmZpcm1hdGlvbi5mYWRlSW4oKTtcbiAgICAgICAgICAgIGRlbGV0ZUluZGV4ID0gZXZlbnQ7XG4gICAgICAgICAgICBjaGlsZE9yUGFyZW50ID0gJ2NoaWxkJztcbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdjbGljaycsIGNhbmNlbFBvcHVwLCAoKSA9PiB7XG4gICAgICAgICAgICBkZWxldGVDb25maXJtYXRpb24uZmFkZU91dCgpO1xuICAgICAgICAgICAgZGVsZXRlSW5kZXggPSB7fTtcbiAgICAgICAgICAgIGNoaWxkT3JQYXJlbnQgPSAnJztcbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdjbGljaycsIGRlbGV0ZUNvbmZpcm0sICgpID0+IHtcbiAgICAgICAgICAgIGlmIChjaGlsZE9yUGFyZW50ID09PSAnY2hpbGQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVGb3JtKGRlbGV0ZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkT3JQYXJlbnQgPT09ICdwYXJlbnQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVQYXJlbnRGb3JtKGRlbGV0ZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZUNvbmZpcm1hdGlvbi5mYWRlT3V0KCk7XG4gICAgICAgICAgICBkZWxldGVJbmRleCA9IHt9O1xuICAgICAgICAgICAgY2hpbGRPclBhcmVudCA9ICcnO1xuICAgICAgICB9KTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ21vdXNlZW50ZXInLCAnLmRlbGV0ZS1wYXJlbnQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnRcbiAgICAgICAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc3QgZGVsZXRlQnV0dG9uID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGV2ZW50LnRhcmdldCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4gICAgICAgICAgICAvL0B0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IG11bHRpRm9ybSA9IGRlbGV0ZUJ1dHRvbi5jbG9zZXN0KCcubXVsdGktZm9ybSwgLndyYXBwZWQtY2hpbGQtYm9keScpO1xuICAgICAgICAgICAgbXVsdGlGb3JtLmNzcyh7XG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJyNGRkY4RjcnLFxuICAgICAgICAgICAgICAgIG91dGxpbmU6ICcycHggc29saWQgI0YxOUJBMCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdtb3VzZWxlYXZlJywgJy5kZWxldGUtcGFyZW50JywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4gICAgICAgICAgICAvL0B0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IGRlbGV0ZUJ1dHRvbiA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KShldmVudC50YXJnZXQpO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudFxuICAgICAgICAgICAgLy9AdHMtaWdub3JlXG4gICAgICAgICAgICBjb25zdCBtdWx0aUZvcm0gPSBkZWxldGVCdXR0b24uY2xvc2VzdCgnLm11bHRpLWZvcm0sIC53cmFwcGVkLWNoaWxkLWJvZHknKTtcbiAgICAgICAgICAgIG11bHRpRm9ybS5jc3Moe1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICcnLFxuICAgICAgICAgICAgICAgIG91dGxpbmU6ICcnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2JvZHknKS5vbignY2xpY2snLCAnLmRlbGV0ZS1wYXJlbnQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGRlbGV0ZUNvbmZpcm1hdGlvbi5mYWRlSW4oKTtcbiAgICAgICAgICAgIGRlbGV0ZUluZGV4ID0gZXZlbnQ7XG4gICAgICAgICAgICBjaGlsZE9yUGFyZW50ID0gJ3BhcmVudCc7XG4gICAgICAgIH0pO1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5zZWxlY3QyJykuc2VsZWN0Mih7XG4gICAgICAgICAgICBwbGFjZWhvbGRlcjogJ1NlbGVjdCBhbiBvcHRpb24nLFxuICAgICAgICAgICAgYWxsb3dDbGVhcjogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHVwZGF0ZSBmb3JtYXQgb24gY2hhbmdlIG9mIGRvY3VtZW50IGxpbmtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ2NoYW5nZScsICdpbnB1dFtpZCo9XCJbdXJsXVwiXScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gKChfYSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJycpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBjb25zdCBkb2N1bWVudCA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgLmZpbmQoJ2lucHV0W2lkKj1cIltkb2N1bWVudF1cIl0nKVxuICAgICAgICAgICAgICAgIC52YWwoKTtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IGAvbWltZXR5cGU/dXJsPSR7ZmlsZVBhdGh9JnR5cGU9dXJsYDtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS5jbG9zZXN0KCcuZm9ybS1maWVsZCcpLmZpbmQoJy50ZXh0LWRhbmdlcicpLnJlbW92ZSgpO1xuICAgICAgICAgICAgaWYgKGZpbGVQYXRoICE9PSAnJykge1xuICAgICAgICAgICAgICAgIGF4aW9zXzEuZGVmYXVsdC5nZXQodXJsKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXQgPSByZXNwb25zZS5kYXRhLmRhdGEubWltZXR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maW5kKCdzZWxlY3RbaWQqPVwiW2Zvcm1hdF1cIl0nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWwoZm9ybWF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS5jbG9zZXN0KCcuZm9ybS1maWVsZCcpLmZpbmQoJy50ZXh0LWRhbmdlcicpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKFwiPGRpdiBjbGFzcz0ndGV4dC1kYW5nZXIgZXJyb3InPlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5kYXRhLm1lc3NhZ2UgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ3NlbGVjdFtpZCo9XCJbZm9ybWF0XVwiXScpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ2lucHV0W2lkKj1cIltkb2N1bWVudF1cIl0nKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFkb2N1bWVudCB8fCBkb2N1bWVudCA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ3NlbGVjdFtpZCo9XCJbZm9ybWF0XVwiXScpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdjaGFuZ2UnLCAnaW5wdXRbaWQqPVwiW2RvY3VtZW50XVwiXScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gKChfYSA9ICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJycpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBgL21pbWV0eXBlP3VybD0ke2ZpbGVQYXRofSYmdHlwZT1kb2N1bWVudGA7XG4gICAgICAgICAgICBjb25zdCBmaWxlVXJsID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpXG4gICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAuZmluZCgnaW5wdXRbaWQqPVwiW3VybF1cIl0nKVxuICAgICAgICAgICAgICAgIC52YWwoKTtcbiAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS5jbG9zZXN0KCcuZm9ybS1maWVsZCcpLmZpbmQoJy50ZXh0LWRhbmdlcicpLnJlbW92ZSgpO1xuICAgICAgICAgICAgaWYgKGZpbGVQYXRoICE9PSAnJykge1xuICAgICAgICAgICAgICAgIGF4aW9zXzEuZGVmYXVsdC5nZXQodXJsKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXQgPSByZXNwb25zZS5kYXRhLmRhdGEubWltZXR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2xvc2VzdCgnLmZvcm0tZmllbGQtZ3JvdXAnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maW5kKCdzZWxlY3RbaWQqPVwiW2Zvcm1hdF1cIl0nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWwoZm9ybWF0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jbG9zZXN0KCcuZm9ybS1maWVsZC1ncm91cCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ3NlbGVjdFtpZCo9XCJbZm9ybWF0XVwiXScpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ2lucHV0W2lkKj1cIlt1cmxdXCJdJylcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWZpbGVVcmwgfHwgZmlsZVVybCA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcylcbiAgICAgICAgICAgICAgICAgICAgLmNsb3Nlc3QoJy5mb3JtLWZpZWxkLWdyb3VwJylcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoJ3NlbGVjdFtpZCo9XCJbZm9ybWF0XVwiXScpXG4gICAgICAgICAgICAgICAgICAgIC52YWwoJycpXG4gICAgICAgICAgICAgICAgICAgIC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGhhbmRsZURlbGV0ZVBhcmVudEJ1dHRvbnMoKSB7XG4gICAgICAgIGNvbnN0IGRlbGV0ZUJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZGVsZXRlLXBhcmVudC1zZWxlY3RvcicpO1xuICAgICAgICBjb25zdCBjaGFuZ2VEZWxldGVCdXR0b25Jbm5lckh0bWwgPSAoYnV0dG9uKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbml0aWFsVGV4dCA9IGVzY2FwZUh0bWwoYnV0dG9uLnRleHRDb250ZW50KTtcbiAgICAgICAgICAgIGJ1dHRvbi5pbm5lckhUTUwgPSBgXG4gICAgICAgICA8c3ZnIGNsYXNzPVwidGV4dC1bMXJlbV0gbWItMC41XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICAgICAgICAgICA8cGF0aCBkPVwiTTYuNjY2NjcgMTJDNi44NDM0OCAxMiA3LjAxMzA1IDExLjkyOTggNy4xMzgwNyAxMS44MDQ3QzcuMjYzMSAxMS42Nzk3IDcuMzMzMzMgMTEuNTEwMSA3LjMzMzMzIDExLjMzMzNWNy4zMzMzNEM3LjMzMzMzIDcuMTU2NTMgNy4yNjMxIDYuOTg2OTYgNy4xMzgwNyA2Ljg2MTkzQzcuMDEzMDUgNi43MzY5MSA2Ljg0MzQ4IDYuNjY2NjcgNi42NjY2NyA2LjY2NjY3QzYuNDg5ODYgNi42NjY2NyA2LjMyMDI5IDYuNzM2OTEgNi4xOTUyNiA2Ljg2MTkzQzYuMDcwMjQgNi45ODY5NiA2IDcuMTU2NTMgNiA3LjMzMzM0VjExLjMzMzNDNiAxMS41MTAxIDYuMDcwMjQgMTEuNjc5NyA2LjE5NTI2IDExLjgwNDdDNi4zMjAyOSAxMS45Mjk4IDYuNDg5ODYgMTIgNi42NjY2NyAxMlpNMTMuMzMzMyA0SDEwLjY2NjdWMy4zMzMzNEMxMC42NjY3IDIuODAyOSAxMC40NTYgMi4yOTQyIDEwLjA4MDkgMS45MTkxMkM5LjcwNTgxIDEuNTQ0MDUgOS4xOTcxIDEuMzMzMzQgOC42NjY2NyAxLjMzMzM0SDcuMzMzMzNDNi44MDI5IDEuMzMzMzQgNi4yOTQxOSAxLjU0NDA1IDUuOTE5MTIgMS45MTkxMkM1LjU0NDA1IDIuMjk0MiA1LjMzMzMzIDIuODAyOSA1LjMzMzMzIDMuMzMzMzRWNEgyLjY2NjY3QzIuNDg5ODYgNCAyLjMyMDI5IDQuMDcwMjQgMi4xOTUyNiA0LjE5NTI2QzIuMDcwMjQgNC4zMjAyOSAyIDQuNDg5ODYgMiA0LjY2NjY3QzIgNC44NDM0OCAyLjA3MDI0IDUuMDEzMDUgMi4xOTUyNiA1LjEzODA3QzIuMzIwMjkgNS4yNjMxIDIuNDg5ODYgNS4zMzMzNCAyLjY2NjY3IDUuMzMzMzRIMy4zMzMzM1YxMi42NjY3QzMuMzMzMzMgMTMuMTk3MSAzLjU0NDA1IDEzLjcwNTggMy45MTkxMiAxNC4wODA5QzQuMjk0MTkgMTQuNDU2IDQuODAyOSAxNC42NjY3IDUuMzMzMzMgMTQuNjY2N0gxMC42NjY3QzExLjE5NzEgMTQuNjY2NyAxMS43MDU4IDE0LjQ1NiAxMi4wODA5IDE0LjA4MDlDMTIuNDU2IDEzLjcwNTggMTIuNjY2NyAxMy4xOTcxIDEyLjY2NjcgMTIuNjY2N1Y1LjMzMzM0SDEzLjMzMzNDMTMuNTEwMSA1LjMzMzM0IDEzLjY3OTcgNS4yNjMxIDEzLjgwNDcgNS4xMzgwN0MxMy45Mjk4IDUuMDEzMDUgMTQgNC44NDM0OCAxNCA0LjY2NjY3QzE0IDQuNDg5ODYgMTMuOTI5OCA0LjMyMDI5IDEzLjgwNDcgNC4xOTUyNkMxMy42Nzk3IDQuMDcwMjQgMTMuNTEwMSA0IDEzLjMzMzMgNFpNNi42NjY2NyAzLjMzMzM0QzYuNjY2NjcgMy4xNTY1MiA2LjczNjkgMi45ODY5NiA2Ljg2MTkzIDIuODYxOTNDNi45ODY5NSAyLjczNjkxIDcuMTU2NTIgMi42NjY2NyA3LjMzMzMzIDIuNjY2NjdIOC42NjY2N0M4Ljg0MzQ4IDIuNjY2NjcgOS4wMTMwNSAyLjczNjkxIDkuMTM4MDcgMi44NjE5M0M5LjI2MzEgMi45ODY5NiA5LjMzMzMzIDMuMTU2NTIgOS4zMzMzMyAzLjMzMzM0VjRINi42NjY2N1YzLjMzMzM0Wk0xMS4zMzMzIDEyLjY2NjdDMTEuMzMzMyAxMi44NDM1IDExLjI2MzEgMTMuMDEzMSAxMS4xMzgxIDEzLjEzODFDMTEuMDEzIDEzLjI2MzEgMTAuODQzNSAxMy4zMzMzIDEwLjY2NjcgMTMuMzMzM0g1LjMzMzMzQzUuMTU2NTIgMTMuMzMzMyA0Ljk4Njk1IDEzLjI2MzEgNC44NjE5MyAxMy4xMzgxQzQuNzM2OSAxMy4wMTMxIDQuNjY2NjcgMTIuODQzNSA0LjY2NjY3IDEyLjY2NjdWNS4zMzMzNEgxMS4zMzMzVjEyLjY2NjdaTTkuMzMzMzMgMTJDOS41MTAxNCAxMiA5LjY3OTcxIDExLjkyOTggOS44MDQ3NCAxMS44MDQ3QzkuOTI5NzYgMTEuNjc5NyAxMCAxMS41MTAxIDEwIDExLjMzMzNWNy4zMzMzNEMxMCA3LjE1NjUzIDkuOTI5NzYgNi45ODY5NiA5LjgwNDc0IDYuODYxOTNDOS42Nzk3MSA2LjczNjkxIDkuNTEwMTQgNi42NjY2NyA5LjMzMzMzIDYuNjY2NjdDOS4xNTY1MiA2LjY2NjY3IDguOTg2OTUgNi43MzY5MSA4Ljg2MTkzIDYuODYxOTNDOC43MzY5MSA2Ljk4Njk2IDguNjY2NjcgNy4xNTY1MyA4LjY2NjY3IDcuMzMzMzRWMTEuMzMzM0M4LjY2NjY3IDExLjUxMDEgOC43MzY5MSAxMS42Nzk3IDguODYxOTMgMTEuODA0N0M4Ljk4Njk1IDExLjkyOTggOS4xNTY1MiAxMiA5LjMzMzMzIDEyWlwiIGZpbGw9XCIjRTM0RDVCXCIvPlxuICAgICAgICAgPC9zdmc+XG4gICAgICAgICAke2luaXRpYWxUZXh0fVxuICAgICAgYDtcbiAgICAgICAgfTtcbiAgICAgICAgZGVsZXRlQnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgICAgICAgIGNoYW5nZURlbGV0ZUJ1dHRvbklubmVySHRtbChidXR0b24pO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4oMCwganF1ZXJ5XzEuZGVmYXVsdCkoZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGZvcm1CdWlsZGVyID0gbmV3IEZvcm1CdWlsZGVyKCk7XG4gICAgZm9ybUJ1aWxkZXIuYWRkV3JhcHBlcigpO1xuICAgIGR5bmFtaWNGaWVsZC5oaWRlU2hvd0Zvcm1GaWVsZHMoKTtcbiAgICBkeW5hbWljRmllbGQudXBkYXRlQWN0aXZpdHlJZGVudGlmaWVyKCk7XG4gICAgZm9ybUJ1aWxkZXIuYWRkVG9Db2xsZWN0aW9uKCk7XG4gICAgZm9ybUJ1aWxkZXIuZGVsZXRlQ29sbGVjdGlvbigpO1xuICAgIC8qKlxuICAgICAqIFRleHQgYXJlYSBoZWlnaHQgb24gdHlwaW5nXG4gICAgICovXG4gICAgY29uc3QgdGV4dEFyZWFUYXJnZXQgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ3RleHRhcmVhLmZvcm1fX2lucHV0Jyk7XG4gICAgaWYgKHRleHRBcmVhVGFyZ2V0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ2lucHV0JywgJ3RleHRhcmVhLmZvcm1fX2lucHV0JywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBmb3JtQnVpbGRlci50ZXh0QXJlYUhlaWdodChldmVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2JvZHknKS5vbignc2VsZWN0MjpvcGVuJywgJy5zZWxlY3QyJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBzZWxlY3Rfc2VhcmNoID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjdDItc2VhcmNoX19maWVsZCcpO1xuICAgICAgICBpZiAoc2VsZWN0X3NlYXJjaCkge1xuICAgICAgICAgICAgc2VsZWN0X3NlYXJjaC5mb2N1cygpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgLyoqXG4gICAgICogY2hlY2tzIHJlZ2lzdHJhdGlvbiBhZ2VuY3ksIGNvdW50cnkgYW5kIHJlZ2lzdHJhdGlvbiBudW1iZXIgdG8gZGVkdWNlIGlkZW50aWZpZXJcbiAgICAgKi9cbiAgICB1cGRhdGVSZWdpc3RyYXRpb25BZ2VuY3koKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pemF0aW9uX2NvdW50cnknKSk7XG4gICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pc2F0aW9uX2lkZW50aWZpZXInKS5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpO1xuICAgIGZ1bmN0aW9uIHVwZGF0ZVJlZ2lzdHJhdGlvbkFnZW5jeShjb3VudHJ5KSB7XG4gICAgICAgIGNvbnN0IGVuZHBvaW50ID0gY291bnRyeS52YWwoKVxuICAgICAgICAgICAgPyAnL29yZ2FuaXNhdGlvbi9hZ2VuY3kvJyArIGNvdW50cnkudmFsKClcbiAgICAgICAgICAgIDogJy9vcmdhbmlzYXRpb24vYWdlbmN5Lyc7XG4gICAgICAgIGpxdWVyeV8xLmRlZmF1bHQuYWpheCh7IHVybDogZW5kcG9pbnQgfSkudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRfdmFsID0gKF9hID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pemF0aW9uX3JlZ2lzdHJhdGlvbl9hZ2VuY3knKS52YWwoKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogJyc7XG4gICAgICAgICAgICBsZXQgdmFsID0gZmFsc2U7XG4gICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJyNvcmdhbml6YXRpb25fcmVnaXN0cmF0aW9uX2FnZW5jeScpLmVtcHR5KCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGRhdGEgaW4gcmVzcG9uc2UuZGF0YSkge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhID09PSBjdXJyZW50X3ZhbCkge1xuICAgICAgICAgICAgICAgICAgICB2YWwgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJyNvcmdhbml6YXRpb25fcmVnaXN0cmF0aW9uX2FnZW5jeScpXG4gICAgICAgICAgICAgICAgICAgIC5hcHBlbmQobmV3IE9wdGlvbihyZXNwb25zZS5kYXRhW2RhdGFdLCBkYXRhLCB0cnVlLCB0cnVlKSlcbiAgICAgICAgICAgICAgICAgICAgLnZhbCgnJylcbiAgICAgICAgICAgICAgICAgICAgLnRyaWdnZXIoJ2NoYW5nZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pemF0aW9uX3JlZ2lzdHJhdGlvbl9hZ2VuY3knKVxuICAgICAgICAgICAgICAgIC52YWwodmFsID8gY3VycmVudF92YWwgOiAnJylcbiAgICAgICAgICAgICAgICAudHJpZ2dlcignY2hhbmdlJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2JvZHknKS5vbignc2VsZWN0MjpzZWxlY3QnLCAnI29yZ2FuaXphdGlvbl9jb3VudHJ5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICB1cGRhdGVSZWdpc3RyYXRpb25BZ2VuY3koKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpKTtcbiAgICB9KTtcbiAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJ2JvZHknKS5vbignc2VsZWN0MjpjbGVhcicsICcjb3JnYW5pemF0aW9uX2NvdW50cnknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHVwZGF0ZVJlZ2lzdHJhdGlvbkFnZW5jeSgoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcykpO1xuICAgIH0pO1xuICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdzZWxlY3QyOnNlbGVjdCcsICcjb3JnYW5pemF0aW9uX3JlZ2lzdHJhdGlvbl9hZ2VuY3knLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGlkZW50aWZpZXIgPSAoMCwganF1ZXJ5XzEuZGVmYXVsdCkodGhpcykudmFsKCkgKyAnLScgKyAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJyNyZWdpc3RyYXRpb25fbnVtYmVyJykudmFsKCk7XG4gICAgICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnI29yZ2FuaXNhdGlvbl9pZGVudGlmaWVyJykudmFsKGlkZW50aWZpZXIpO1xuICAgIH0pO1xuICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnYm9keScpLm9uKCdzZWxlY3QyOmNsZWFyJywgJyNvcmdhbml6YXRpb25fcmVnaXN0cmF0aW9uX2FnZW5jeScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaWRlbnRpZmllciA9ICctJyArICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnI3JlZ2lzdHJhdGlvbl9udW1iZXInKS52YWwoKTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pc2F0aW9uX2lkZW50aWZpZXInKS52YWwoaWRlbnRpZmllcik7XG4gICAgfSk7XG4gICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCdib2R5Jykub24oJ2tleXVwJywgJyNyZWdpc3RyYXRpb25fbnVtYmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpZGVudGlmaWVyID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pemF0aW9uX3JlZ2lzdHJhdGlvbl9hZ2VuY3knKS52YWwoKSArICctJyArICgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKS52YWwoKTtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcjb3JnYW5pc2F0aW9uX2lkZW50aWZpZXInKS52YWwoaWRlbnRpZmllcik7XG4gICAgfSk7XG4gICAgLy8gYWRkIGNsYXNzIHRvIHRpdGxlIG9mIGNvbGxlY3Rpb24gd2hlbiB2YWxpZGF0aW9uIGVycm9yIG9jY3VycyBvbiBjb2xsZWN0aW9uIGxldmVsXG4gICAgY29uc3Qgc3ViZWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zdWJlbGVtZW50Jyk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdWJlbGVtZW50Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHRpdGxlID0gc3ViZWxlbWVudFtpXS5xdWVyeVNlbGVjdG9yKCcuY29udHJvbC1sYWJlbCcpO1xuICAgICAgICBjb25zdCBlcnJvckNvbnRhaW5lciA9IHN1YmVsZW1lbnRbaV0ucXVlcnlTZWxlY3RvcignLmNvbGxlY3Rpb25fZXJyb3InKTtcbiAgICAgICAgY29uc3QgY2hpbGRDb3VudCA9IGVycm9yQ29udGFpbmVyID09PSBudWxsIHx8IGVycm9yQ29udGFpbmVyID09PSB2b2lkIDAgPyB2b2lkIDAgOiBlcnJvckNvbnRhaW5lci5jaGlsZEVsZW1lbnRDb3VudDtcbiAgICAgICAgaWYgKGNoaWxkQ291bnQgJiYgY2hpbGRDb3VudCA+IDApIHtcbiAgICAgICAgICAgIHRpdGxlID09PSBudWxsIHx8IHRpdGxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiB0aXRsZS5jbGFzc0xpc3QuYWRkKCdlcnJvci10aXRsZScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEFkZGluZyBjdXJzb3Igbm90IGFsbG93ZWQgdG8gPHNlbGVjdD4gd2hlcmUgZWxlbWVudEpzb25TY2hlbWEgcmVhZF9vbmx5IDogdHJ1ZVxuICAgIGNvbnN0IHJlYWRPbmx5U2VsZWN0cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3NlbGVjdC5jdXJzb3Itbm90LWFsbG93ZWQnKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlYWRPbmx5U2VsZWN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBzZWxlY3QgPSByZWFkT25seVNlbGVjdHNbaV07XG4gICAgICAgIGNvbnN0IHNlbGVjdEVsZW1lbnRQYXJlbnRXcmFwcGVyID0gc2VsZWN0Lm5leHRTaWJsaW5nO1xuICAgICAgICBjb25zdCBzZWxlY3RFbGVtZW50UGFyZW50ID0gc2VsZWN0RWxlbWVudFBhcmVudFdyYXBwZXIgPT09IG51bGwgfHwgc2VsZWN0RWxlbWVudFBhcmVudFdyYXBwZXIgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHNlbGVjdEVsZW1lbnRQYXJlbnRXcmFwcGVyLmZpcnN0Q2hpbGQ7XG4gICAgICAgIGNvbnN0IHNlbGVjdEVsZW1lbnQgPSBzZWxlY3RFbGVtZW50UGFyZW50ID09PSBudWxsIHx8IHNlbGVjdEVsZW1lbnRQYXJlbnQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHNlbGVjdEVsZW1lbnRQYXJlbnQuZmlyc3RDaGlsZDtcbiAgICAgICAgaWYgKHNlbGVjdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHNlbGVjdEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gJ25vdC1hbGxvd2VkJztcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBkZWxldGVCdXR0b25zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmRlbGV0ZS1wYXJlbnQtc2VsZWN0b3InKTtcbiAgICBmdW5jdGlvbiBjaGFuZ2VEZWxldGVCdXR0b25Jbm5lckh0bWwoYnV0dG9uKSB7XG4gICAgICAgIGNvbnN0IGluaXRpYWxUZXh0ID0gZXNjYXBlSHRtbChidXR0b24udGV4dENvbnRlbnQpO1xuICAgICAgICBidXR0b24uaW5uZXJIVE1MID0gYFxuICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgIDxwYXRoIGQ9XCJNNi42NjY2NyAxMkM2Ljg0MzQ4IDEyIDcuMDEzMDUgMTEuOTI5OCA3LjEzODA3IDExLjgwNDdDNy4yNjMxIDExLjY3OTcgNy4zMzMzMyAxMS41MTAxIDcuMzMzMzMgMTEuMzMzM1Y3LjMzMzM0QzcuMzMzMzMgNy4xNTY1MyA3LjI2MzEgNi45ODY5NiA3LjEzODA3IDYuODYxOTNDNy4wMTMwNSA2LjczNjkxIDYuODQzNDggNi42NjY2NyA2LjY2NjY3IDYuNjY2NjdDNi40ODk4NiA2LjY2NjY3IDYuMzIwMjkgNi43MzY5MSA2LjE5NTI2IDYuODYxOTNDNi4wNzAyNCA2Ljk4Njk2IDYgNy4xNTY1MyA2IDcuMzMzMzRWMTEuMzMzM0M2IDExLjUxMDEgNi4wNzAyNCAxMS42Nzk3IDYuMTk1MjYgMTEuODA0N0M2LjMyMDI5IDExLjkyOTggNi40ODk4NiAxMiA2LjY2NjY3IDEyWk0xMy4zMzMzIDRIMTAuNjY2N1YzLjMzMzM0QzEwLjY2NjcgMi44MDI5IDEwLjQ1NiAyLjI5NDIgMTAuMDgwOSAxLjkxOTEyQzkuNzA1ODEgMS41NDQwNSA5LjE5NzEgMS4zMzMzNCA4LjY2NjY3IDEuMzMzMzRINy4zMzMzM0M2LjgwMjkgMS4zMzMzNCA2LjI5NDE5IDEuNTQ0MDUgNS45MTkxMiAxLjkxOTEyQzUuNTQ0MDUgMi4yOTQyIDUuMzMzMzMgMi44MDI5IDUuMzMzMzMgMy4zMzMzNFY0SDIuNjY2NjdDMi40ODk4NiA0IDIuMzIwMjkgNC4wNzAyNCAyLjE5NTI2IDQuMTk1MjZDMi4wNzAyNCA0LjMyMDI5IDIgNC40ODk4NiAyIDQuNjY2NjdDMiA0Ljg0MzQ4IDIuMDcwMjQgNS4wMTMwNSAyLjE5NTI2IDUuMTM4MDdDMi4zMjAyOSA1LjI2MzEgMi40ODk4NiA1LjMzMzM0IDIuNjY2NjcgNS4zMzMzNEgzLjMzMzMzVjEyLjY2NjdDMy4zMzMzMyAxMy4xOTcxIDMuNTQ0MDUgMTMuNzA1OCAzLjkxOTEyIDE0LjA4MDlDNC4yOTQxOSAxNC40NTYgNC44MDI5IDE0LjY2NjcgNS4zMzMzMyAxNC42NjY3SDEwLjY2NjdDMTEuMTk3MSAxNC42NjY3IDExLjcwNTggMTQuNDU2IDEyLjA4MDkgMTQuMDgwOUMxMi40NTYgMTMuNzA1OCAxMi42NjY3IDEzLjE5NzEgMTIuNjY2NyAxMi42NjY3VjUuMzMzMzRIMTMuMzMzM0MxMy41MTAxIDUuMzMzMzQgMTMuNjc5NyA1LjI2MzEgMTMuODA0NyA1LjEzODA3QzEzLjkyOTggNS4wMTMwNSAxNCA0Ljg0MzQ4IDE0IDQuNjY2NjdDMTQgNC40ODk4NiAxMy45Mjk4IDQuMzIwMjkgMTMuODA0NyA0LjE5NTI2QzEzLjY3OTcgNC4wNzAyNCAxMy41MTAxIDQgMTMuMzMzMyA0Wk02LjY2NjY3IDMuMzMzMzRDNi42NjY2NyAzLjE1NjUyIDYuNzM2OSAyLjk4Njk2IDYuODYxOTMgMi44NjE5M0M2Ljk4Njk1IDIuNzM2OTEgNy4xNTY1MiAyLjY2NjY3IDcuMzMzMzMgMi42NjY2N0g4LjY2NjY3QzguODQzNDggMi42NjY2NyA5LjAxMzA1IDIuNzM2OTEgOS4xMzgwNyAyLjg2MTkzQzkuMjYzMSAyLjk4Njk2IDkuMzMzMzMgMy4xNTY1MiA5LjMzMzMzIDMuMzMzMzRWNEg2LjY2NjY3VjMuMzMzMzRaTTExLjMzMzMgMTIuNjY2N0MxMS4zMzMzIDEyLjg0MzUgMTEuMjYzMSAxMy4wMTMxIDExLjEzODEgMTMuMTM4MUMxMS4wMTMgMTMuMjYzMSAxMC44NDM1IDEzLjMzMzMgMTAuNjY2NyAxMy4zMzMzSDUuMzMzMzNDNS4xNTY1MiAxMy4zMzMzIDQuOTg2OTUgMTMuMjYzMSA0Ljg2MTkzIDEzLjEzODFDNC43MzY5IDEzLjAxMzEgNC42NjY2NyAxMi44NDM1IDQuNjY2NjcgMTIuNjY2N1Y1LjMzMzM0SDExLjMzMzNWMTIuNjY2N1pNOS4zMzMzMyAxMkM5LjUxMDE0IDEyIDkuNjc5NzEgMTEuOTI5OCA5LjgwNDc0IDExLjgwNDdDOS45Mjk3NiAxMS42Nzk3IDEwIDExLjUxMDEgMTAgMTEuMzMzM1Y3LjMzMzM0QzEwIDcuMTU2NTMgOS45Mjk3NiA2Ljk4Njk2IDkuODA0NzQgNi44NjE5M0M5LjY3OTcxIDYuNzM2OTEgOS41MTAxNCA2LjY2NjY3IDkuMzMzMzMgNi42NjY2N0M5LjE1NjUyIDYuNjY2NjcgOC45ODY5NSA2LjczNjkxIDguODYxOTMgNi44NjE5M0M4LjczNjkxIDYuOTg2OTYgOC42NjY2NyA3LjE1NjUzIDguNjY2NjcgNy4zMzMzNFYxMS4zMzMzQzguNjY2NjcgMTEuNTEwMSA4LjczNjkxIDExLjY3OTcgOC44NjE5MyAxMS44MDQ3QzguOTg2OTUgMTEuOTI5OCA5LjE1NjUyIDEyIDkuMzMzMzMgMTJaXCIgZmlsbD1cIiNFMzRENUJcIi8+XG4gICAgICA8L3N2Zz5cbiAgICAgICR7aW5pdGlhbFRleHR9YDtcbiAgICB9XG4gICAgZGVsZXRlQnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IGNoYW5nZURlbGV0ZUJ1dHRvbklubmVySHRtbChidXR0b24pKTtcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnNMaXN0KSA9PiB7XG4gICAgICAgIG11dGF0aW9uc0xpc3QuZm9yRWFjaCgobXV0YXRpb24pID0+IHtcbiAgICAgICAgICAgIGlmIChtdXRhdGlvbi5hZGRlZE5vZGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBtdXRhdGlvbi5hZGRlZE5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS5tYXRjaGVzKCcuZGVsZXRlLWl0ZW0tc2VsZWN0b3InKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZURlbGV0ZUJ1dHRvbklubmVySHRtbChub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0RlbGV0ZUJ1dHRvbnMgPSBub2RlLnF1ZXJ5U2VsZWN0b3JBbGwoJy5kZWxldGUtaXRlbS1zZWxlY3RvcicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RlbGV0ZUJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiBjaGFuZ2VEZWxldGVCdXR0b25Jbm5lckh0bWwoYnV0dG9uKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudC5ib2R5LCB7XG4gICAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICAgICAgc3VidHJlZTogdHJ1ZSxcbiAgICB9KTtcbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGRvZXMgdHdvIG1haW4gdGhpbmdzOlxuICAgICAqXG4gICAgICogMS4gQWRkcyBhIGNsaWNrIGV2ZW50IGxpc3RlbmVyIHRvIHRoZSBidXR0b24gdG8gY29udHJvbCB0aGUgY29sbGFwc2libGUgZmxvdzpcbiAgICAgKiAgICAtIEl0IGZpbmRzIHRoZSBjbG9zZXN0IDxsYWJlbD4gZWxlbWVudCByZWxhdGVkIHRvIHRoZSBidXR0b24uXG4gICAgICogICAgLSBXaXRoaW4gdGhhdCA8bGFiZWw+LCBpdCBsb29rcyBmb3IgYW4gZWxlbWVudCB3aXRoIHRoZSBjbGFzcyAnb3B0aW9uYWwtdGV4dCcuIElmIGl0IGZpbmRzICdvcHRpb25hbC10ZXh0JywgaXQgdG9nZ2xlcyBob3cgdGhhdCB0ZXh0IGlzIGRpc3BsYXllZCAoZWl0aGVyIHdpdGggYnJhY2tldHMgb3IgYW4gaWNvbikuXG4gICAgICogICAgLSBJdCBhbHNvIGxvY2F0ZXMgdGhlIG5lYXJlc3QgcGFyZW50IGVsZW1lbnQgd2l0aCB0aGUgY2xhc3NlcyAnc3ViZWxlbWVudCByb3VuZGVkLXQtc20nLiBJZiB0aGF0IHBhcmVudCBzdWJlbGVtZW50IGV4aXN0cywgaXQgdG9nZ2xlcyBpdHMgc3RhdGUgdG8gZWl0aGVyIGNvbGxhcHNlIG9yIGV4cGFuZCB0aGUgZm9ybSBzZWN0aW9uLlxuICAgICAqICAgIC0gRmluYWxseSwgaXQgcm90YXRlcyB0aGUgY29sbGFwc2UgYnV0dG9uIGVhY2ggdGltZSBpdOKAmXMgY2xpY2tlZC5cbiAgICAgKlxuICAgICAqIDIuIEl0IHRyaWdnZXJzIHRoZSBidXR0b24gY2xpY2sgZXZlbnQgaWYgdGhlIHN1YmVsZW1lbnQgaXMgb3B0aW9uYWwgdXNpbmcgdGhlIGZsYWc6IHRoaXNCdXR0b25CZWxvbmdzVG9PcHRpb25hbEZvcm0uXG4gICAgICogICAgVGhpcyBlbnN1cmVzIG9wdGlvbmFsIGZvcm1zIHN0YXJ0IG9mZiBjb2xsYXBzZWQgYnkgZGVmYXVsdCB3aGVuIHJlbmRlcmVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGJ1dHRvbiAtIFRoZSBidXR0b24gZWxlbWVudCB0aGF0IG1hbmFnZXMgdGhlIGNvbGxhcHNpYmxlIGZvcm0gc2VjdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhdHRhY2hDb2xsYXBzYWJsZUJ1dHRvbkV2ZW50cyhidXR0b24pIHtcbiAgICAgICAgY29uc3QgbGFiZWwgPSBnZXRDbG9zZXN0TGFiZWxEb20oYnV0dG9uKTtcbiAgICAgICAgY29uc3Qgb3B0aW9uYWxMYWJlbCA9IGxhYmVsID8gZ2V0T3B0aW9uYWxUZXh0RG9tKGxhYmVsKSA6IG51bGw7XG4gICAgICAgIGNvbnN0IHN1YmVsZW1lbnQgPSBsYWJlbCA/IGdldENsb3Nlc3RQYXJlbnRTdWJlbGVtZW50RG9tKGxhYmVsKSA6IG51bGw7XG4gICAgICAgIGNvbnN0IHRoaXNCdXR0b25CZWxvbmdzVG9PcHRpb25hbEZvcm0gPSBvcHRpb25hbExhYmVsICE9PSBudWxsO1xuICAgICAgICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAob3B0aW9uYWxMYWJlbCkge1xuICAgICAgICAgICAgICAgIHRvZ2dsZU9wdGlvbmFsVGV4dChvcHRpb25hbExhYmVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzdWJlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdG9nZ2xlQWNjb3JkaW9uSXRlbXMoc3ViZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidXR0b24uY2xhc3NMaXN0LnRvZ2dsZSgncm90YXRlLTE4MCcpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXNCdXR0b25CZWxvbmdzVG9PcHRpb25hbEZvcm0gJiYgIWVycm9yTWVzc2FnZUV4aXN0cyhzdWJlbGVtZW50KSkge1xuICAgICAgICAgICAgYnV0dG9uLmNsaWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYW55IGVycm9yIG1lc3NhZ2UgZXhpc3RzIGluIHRoZSBzdWJlbGVtZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIHN1YmVsZW1lbnRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcnJvck1lc3NhZ2VFeGlzdHMoc3ViZWxlbWVudCkge1xuICAgICAgICBjb25zdCBlcnJvckRpdnMgPSBzdWJlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5lcnJvcicpO1xuICAgICAgICBjb25zdCBlcnJvclRleHRzID0gc3ViZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudGV4dC1kYW5nZXItZXJyb3InKTtcbiAgICAgICAgZm9yIChjb25zdCBkaXYgb2YgZXJyb3JEaXZzKSB7XG4gICAgICAgICAgICBpZiAoZGl2LnRleHRDb250ZW50LnRyaW0oKSAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGRpdiBvZiBlcnJvclRleHRzKSB7XG4gICAgICAgICAgICBpZiAoZGl2LnRleHRDb250ZW50LnRyaW0oKSAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgY2xvc2VzdCA8bGFiZWw+IGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYnV0dG9uXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0Q2xvc2VzdExhYmVsRG9tKGJ1dHRvbikge1xuICAgICAgICByZXR1cm4gYnV0dG9uLmNsb3Nlc3QoJ2xhYmVsJyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgY2xvc2VzdCBlbGVtZW50IHdpdGggY2xhc3MgJ29wdGlvbmFsLXRleHQnLlxuICAgICAqXG4gICAgICogQHBhcmFtIGxhYmVsXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0T3B0aW9uYWxUZXh0RG9tKGxhYmVsKSB7XG4gICAgICAgIHJldHVybiBsYWJlbC5xdWVyeVNlbGVjdG9yKCcub3B0aW9uYWwtdGV4dCcpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBmaXJzdCBOdGggcGFyZW50IHRoYXQgaGFzIGNsYXNzICdzdWJlbGVtZW50Jy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBsYWJlbFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldENsb3Nlc3RQYXJlbnRTdWJlbGVtZW50RG9tKGxhYmVsKSB7XG4gICAgICAgIHJldHVybiBsYWJlbC5jbG9zZXN0KCcuc3ViZWxlbWVudC5yb3VuZGVkLXQtc20nKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVG9nZ2xlcyB3aGF0IGlzIHJlbmRlcmVkIG9uIG9wdGlvbmFsIHRleHQuIChkb3Qgb3IgYnJhY2tldClcbiAgICAgKlxuICAgICAqIEBwYXJhbSBvcHRpb25hbExhYmVsXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9nZ2xlT3B0aW9uYWxUZXh0KG9wdGlvbmFsTGFiZWwpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uYWxMYWJlbFdpdGhTdmcgPSAnPHN2ZyB2aWV3Qm94PVwiMCAwIDE2IDE4XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+PHBhdGggZD1cIk02IDlhMS44NyAxLjg3IDAgMSAwIDMuNzQgMEExLjg3IDEuODcgMCAwIDAgNiA5WlwiIGZpbGw9XCIjNjg3OTdFXCI+PC9wYXRoPjwvc3ZnPjxzcGFuPk9wdGlvbmFsPC9zcGFuPic7XG4gICAgICAgIGNvbnN0IG9wdGlvbmFsTGFiZWxXaXRoQnJhY2tldHMgPSAnPHNwYW4+KCBPcHRpb25hbCApPC9zcGFuPic7XG4gICAgICAgIGNvbnN0IHN2Z0V4aXN0cyA9IG9wdGlvbmFsTGFiZWwucXVlcnlTZWxlY3Rvcignc3ZnJykgIT09IG51bGw7XG4gICAgICAgIGlmIChzdmdFeGlzdHMpIHtcbiAgICAgICAgICAgIG9wdGlvbmFsTGFiZWwuaW5uZXJIVE1MID0gb3B0aW9uYWxMYWJlbFdpdGhCcmFja2V0cztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG9wdGlvbmFsTGFiZWwuaW5uZXJIVE1MID0gb3B0aW9uYWxMYWJlbFdpdGhTdmc7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVG9nZ2xlcyBjb2xsYXBzZWQgc3RhdGUuIChleHBhbmQgb3IgY29sbGFwc2VkKVxuICAgICAqXG4gICAgICogS2V5IGNvbnNpZGVyYXRpb25zOlxuICAgICAqIDEuIFRoZSBcIkFkZCBBZGRpdGlvbmFsXCIgYnV0dG9uIGNhbiBiZSBlaXRoZXIgaW5zaWRlIG9yIG91dHNpZGUgdGhlIHN1YmVsZW1lbnQuXG4gICAgICogMi4gV2hlbiB0aGUgYnV0dG9uIGlzIG91dHNpZGUsIGl0IHdpbGwgYWx3YXlzIGJlIHRoZSBpbW1lZGlhdGUgc2libGluZyB0byB0aGUgc3ViZWxlbWVudC5cbiAgICAgKiAzLiBUaGUgY29sbGFwc2UgbWVjaGFuaXNtIGlzIGhhbmRsZWQgYnkgYWRqdXN0aW5nIHRoZSBtYXggaGVpZ2h0IHRvIGdpdmUgdGhlIGlsbHVzaW9uIG9mIHNsaWRpbmcgdXAuXG4gICAgICogNC4gSWYgdGhlIGJ1dHRvbiBpcyBvdXRzaWRlIHRoZSBzdWJlbGVtZW50LCB0aGUgc2xpZGUtdXAgZWZmZWN0IHdpbGwgbm90IGFmZmVjdCB0aGUgYnV0dG9uLlxuICAgICAqICAgIFRoZXJlZm9yZSwgd2UgdG9nZ2xlIHRoZSAnZGlzcGxheS1ub25lJyBjbGFzcyB0byBjb250cm9sIGl0cyB2aXNpYmlsaXR5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHN1YmVsZW1lbnRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b2dnbGVBY2NvcmRpb25JdGVtcyhzdWJlbGVtZW50KSB7XG4gICAgICAgIGZ1bmN0aW9uIGlzQWRkQWRkaXRpb25hbEJ1dHRvbk91dHNpZGUoc3ViZWxlbWVudCkge1xuICAgICAgICAgICAgY29uc3QgbmV4dFNpYmxpbmcgPSBzdWJlbGVtZW50Lm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgICAgIGlmIChuZXh0U2libGluZyAmJiBuZXh0U2libGluZy50YWdOYW1lID09PSAnQlVUVE9OJykge1xuICAgICAgICAgICAgICAgIHJldHVybiAobmV4dFNpYmxpbmcuY2xhc3NMaXN0LmNvbnRhaW5zKCdhZGRfbW9yZScpICYmXG4gICAgICAgICAgICAgICAgICAgIG5leHRTaWJsaW5nLmNsYXNzTGlzdC5jb250YWlucygnYnV0dG9uJykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhpZGVhYmxlU3ViZWxlbWVudHMgPSBbLi4uc3ViZWxlbWVudC5jaGlsZHJlbl0uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudGFnTmFtZSAhPT0gJ0xBQkVMJyk7XG4gICAgICAgIGxldCBvdXRzaWRlQnV0dG9uID0gbnVsbDtcbiAgICAgICAgY29uc3QgaGFzQWRkQWRkaXRpb25hbEJ1dHRvbk91dHNpZGUgPSBpc0FkZEFkZGl0aW9uYWxCdXR0b25PdXRzaWRlKHN1YmVsZW1lbnQpO1xuICAgICAgICBpZiAoaGFzQWRkQWRkaXRpb25hbEJ1dHRvbk91dHNpZGUpIHtcbiAgICAgICAgICAgIG91dHNpZGVCdXR0b24gPSBzdWJlbGVtZW50Lm5leHRFbGVtZW50U2libGluZztcbiAgICAgICAgICAgIGlmIChvdXRzaWRlQnV0dG9uKSB7XG4gICAgICAgICAgICAgICAgb3V0c2lkZUJ1dHRvbi5jbGFzc0xpc3QudG9nZ2xlKCdkaXNwbGF5LW5vbmUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBoaWRlYWJsZVN1YmVsZW1lbnRzLmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgICAgICAgICBpZiAoaGFzQWRkQWRkaXRpb25hbEJ1dHRvbk91dHNpZGUgJiYgb3V0c2lkZUJ1dHRvbikge1xuICAgICAgICAgICAgICAgIHN1YmVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZSgnbWItNicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNoaWxkLmNsYXNzTGlzdC5jb250YWlucygnaGVpZ2h0LWhpZGUnKSkge1xuICAgICAgICAgICAgICAgIGNoaWxkLmNsYXNzTGlzdC5yZW1vdmUoJ2hlaWdodC1oaWRlJyk7XG4gICAgICAgICAgICAgICAgY2hpbGQuY2xhc3NMaXN0LmFkZCgnaGVpZ2h0LXNob3cnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNoaWxkLmNsYXNzTGlzdC5yZW1vdmUoJ2hlaWdodC1zaG93Jyk7XG4gICAgICAgICAgICAgICAgY2hpbGQuY2xhc3NMaXN0LmFkZCgnaGVpZ2h0LWhpZGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gaGFuZGxlcyB0aGUgZm9ybXMgcmVuZGVyZWQgb24gaW5pdGlhbCBwYWdlIGxvYWQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXR0YWNoSW5pdGlhbENvbGxhcHNhYmxlQnV0dG9uRXZlbnRzKCkge1xuICAgICAgICBjb25zdCBhbGxDb2xsYXBzYWJsZUJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuY29sbGFwc2FibGUtYnV0dG9uJyk7XG4gICAgICAgIGFsbENvbGxhcHNhYmxlQnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IGF0dGFjaENvbGxhcHNhYmxlQnV0dG9uRXZlbnRzKGJ1dHRvbikpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGhhbmRsZXMgdGhlIGZvcm1zIHJlbmRlcmVkIG9uIGNsaWNraW5nICdBREQgQURESVRJT05BTCBYJyBidXR0b24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gb2JzZXJ2ZU5ld0NvbGxhcHNhYmxlQnV0dG9ucygpIHtcbiAgICAgICAgY29uc3Qgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigobXV0YXRpb25zTGlzdCkgPT4ge1xuICAgICAgICAgICAgbXV0YXRpb25zTGlzdC5mb3JFYWNoKChtdXRhdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChtdXRhdGlvbi50eXBlID09PSAnY2hpbGRMaXN0Jykge1xuICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbi5hZGRlZE5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdDb2xsYXBzYWJsZUJ1dHRvbnMgPSBub2RlLnF1ZXJ5U2VsZWN0b3JBbGwoJy5jb2xsYXBzYWJsZS1idXR0b24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdDb2xsYXBzYWJsZUJ1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiBhdHRhY2hDb2xsYXBzYWJsZUJ1dHRvbkV2ZW50cyhidXR0b24pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBvYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LmJvZHksIHsgY2hpbGRMaXN0OiB0cnVlLCBzdWJ0cmVlOiB0cnVlIH0pO1xuICAgIH1cbiAgICBhdHRhY2hJbml0aWFsQ29sbGFwc2FibGVCdXR0b25FdmVudHMoKTtcbiAgICBvYnNlcnZlTmV3Q29sbGFwc2FibGVCdXR0b25zKCk7XG59KTtcbmZ1bmN0aW9uIGVzY2FwZUh0bWwodW5zYWZlKSB7XG4gICAgcmV0dXJuIHVuc2FmZVxuICAgICAgICAucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgICAgICAucmVwbGFjZSgvPC9nLCAnJmx0OycpXG4gICAgICAgIC5yZXBsYWNlKC8+L2csICcmZ3Q7JylcbiAgICAgICAgLnJlcGxhY2UoL1wiL2csICcmcXVvdDsnKVxuICAgICAgICAucmVwbGFjZSgvJy9nLCAnJiMwMzk7Jyk7XG59XG4vKlxuICpcbiAqIEhlbHAgVGV4dCBPcGVuIENsb3NlIEhhbmRsZXJzIFN0YXJ0XG4gKlxuICovXG4oMCwganF1ZXJ5XzEuZGVmYXVsdCkoZG9jdW1lbnQpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmICghKDAsIGpxdWVyeV8xLmRlZmF1bHQpKGV2ZW50LnRhcmdldCkuY2xvc2VzdCgnLmhlbHAnKS5sZW5ndGgpIHtcbiAgICAgICAgKDAsIGpxdWVyeV8xLmRlZmF1bHQpKCcuaGVscF9fdGV4dCcpLnJlbW92ZUF0dHIoJ3N0eWxlJyk7XG4gICAgfVxufSk7XG4oMCwganF1ZXJ5XzEuZGVmYXVsdCkoZG9jdW1lbnQpLm9uKCdjbGljaycsICcuaGVscCcsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnNvbGUubG9nKCdIZWxsbycpO1xuICAgICgwLCBqcXVlcnlfMS5kZWZhdWx0KSgnLmhlbHBfX3RleHQnKS5yZW1vdmVBdHRyKCdzdHlsZScpO1xuICAgIGNvbnN0IGhlbHBUZXh0ID0gKDAsIGpxdWVyeV8xLmRlZmF1bHQpKHRoaXMpLmZpbmQoJy5oZWxwX190ZXh0Jyk7XG4gICAgaWYgKGhlbHBUZXh0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgaGVscFRleHQuY3NzKHtcbiAgICAgICAgICAgIG9wYWNpdHk6ICcxJyxcbiAgICAgICAgICAgIHZpc2liaWxpdHk6ICd2aXNpYmxlJyxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlmICgoMCwganF1ZXJ5XzEuZGVmYXVsdCkoZXZlbnQudGFyZ2V0KS5jbG9zZXN0KCcuY2xvc2UtaGVscCcpLmxlbmd0aCkge1xuICAgICAgICBjbG9zZUhlbHBUZXh0KGhlbHBUZXh0KTtcbiAgICB9XG59KTtcbigwLCBqcXVlcnlfMS5kZWZhdWx0KShkb2N1bWVudCkub24oJ2tleWRvd24nLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgICAoMCwganF1ZXJ5XzEuZGVmYXVsdCkoJy5oZWxwX190ZXh0JykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjbG9zZUhlbHBUZXh0KCgwLCBqcXVlcnlfMS5kZWZhdWx0KSh0aGlzKSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn0pO1xuLyoqXG4gKiBDbG9zZXMgdGhlIGhlbHAgdGV4dCB0b29sdGlwIGJ5IHNldHRpbmcgaXRzIENTUyBwcm9wZXJ0aWVzIHRvIG1ha2UgaXQgaW52aXNpYmxlIGFuZCBub24taW50ZXJhY3RpdmUuXG4gKiBBZnRlciBhIGRlbGF5LCBpdCByZW1vdmVzIHRoZSBpbmxpbmUgc3R5bGVzIHRvIHJlc2V0IHRoZSBlbGVtZW50J3Mgc3RhdGUuXG4gKlxuICogQHBhcmFtIGhlbHBUZXh0IC0gVGhlIGpRdWVyeSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSB0b29sdGlwIGVsZW1lbnQgdG8gYmUgY2xvc2VkLlxuICovXG5mdW5jdGlvbiBjbG9zZUhlbHBUZXh0KGhlbHBUZXh0KSB7XG4gICAgaGVscFRleHQuY3NzKHtcbiAgICAgICAgJ3BvaW50ZXItZXZlbnRzJzogJ25vbmUnLFxuICAgICAgICBvcGFjaXR5OiAnMCcsXG4gICAgICAgIHZpc2liaWxpdHk6ICdpbnZpc2libGUnLFxuICAgIH0pO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBoZWxwVGV4dC5yZW1vdmVBdHRyKCdzdHlsZScpO1xuICAgIH0sIDEwMDApO1xufVxuLypcbiAqXG4gKiBIZWxwIFRleHQgT3BlbiBDbG9zZSBIYW5kbGVycyBFbmRcbiAqXG4gKi9cbiJdLCJuYW1lcyI6WyJfY2xhc3NDYWxsQ2hlY2siLCJpbnN0YW5jZSIsIkNvbnN0cnVjdG9yIiwiVHlwZUVycm9yIiwiX2RlZmluZVByb3BlcnRpZXMiLCJ0YXJnZXQiLCJwcm9wcyIsImkiLCJsZW5ndGgiLCJkZXNjcmlwdG9yIiwiZW51bWVyYWJsZSIsImNvbmZpZ3VyYWJsZSIsIndyaXRhYmxlIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJrZXkiLCJfY3JlYXRlQ2xhc3MiLCJwcm90b1Byb3BzIiwic3RhdGljUHJvcHMiLCJwcm90b3R5cGUiLCJfX2ltcG9ydERlZmF1bHQiLCJtb2QiLCJfX2VzTW9kdWxlIiwiZXhwb3J0cyIsInZhbHVlIiwiRHluYW1pY0ZpZWxkIiwianF1ZXJ5XzEiLCJyZXF1aXJlIiwiaGlkZVNob3dGb3JtRmllbGRzIiwiaHVtYW5pdGFyaWFuU2NvcGVIaWRlVm9jYWJ1bGFyeVVyaSIsImNvdW50cnlCdWRnZXRIaWRlQ29kZUZpZWxkIiwiYWlkVHlwZVZvY2FidWxhcnlIaWRlRmllbGQiLCJzZWN0b3JWb2NhYnVsYXJ5SGlkZUZpZWxkIiwicG9saWN5Vm9jYWJ1bGFyeUhpZGVGaWVsZCIsInJlY2lwaWVudFZvY2FidWxhcnlIaWRlRmllbGQiLCJ0YWdWb2NhYnVsYXJ5SGlkZUZpZWxkIiwidHJhbnNhY3Rpb25BaWRUeXBlVm9jYWJ1bGFyeUhpZGVGaWVsZCIsImluZGljYXRvclJlZmVyZW5jZUhpZGVGaWVsZFVyaSIsIl90aGlzIiwiaHVtYW5pdGFyaWFuU2NvcGVWb2NhYnVsYXJ5IiwiZWFjaCIsImluZGV4Iiwic2NvcGUiLCJfYSIsInZhbCIsImhpZGVIdW1hbml0YXJpYW5TY29wZUZpZWxkIiwidG9TdHJpbmciLCJvbiIsImUiLCJwYXJhbXMiLCJkYXRhIiwiaWQiLCJjbG9zZXN0IiwiZmluZCIsInNob3ciLCJyZW1vdmVBdHRyIiwidHJpZ2dlciIsImhpZGUiLCJhdHRyIiwiX3RoaXMyIiwicmVmZXJlbmNlVm9jYWJ1bGFyeSIsImluZGljYXRvclJlZmVyZW5jZUhpZGVGaWVsZCIsInJlZmVyZW5jZVVyaSIsIl90aGlzMyIsImNvdW50cnlCdWRnZXRWb2NhYnVsYXJ5IiwiaGlkZUNvdW50cnlCdWRnZXRGaWVsZCIsImNvdW50cnlCdWRnZXRDb2RlSW5wdXQiLCJjb3VudHJ5QnVkZ2V0Q29kZVNlbGVjdCIsIl90aGlzNCIsImFpZHR5cGVfdm9jYWJ1bGFyeSIsIml0ZW0iLCJoaWRlQWlkVHlwZVNlbGVjdEZpZWxkIiwiX3RoaXM1IiwiaGlkZVRyYW5zYWN0aW9uQWlkVHlwZVNlbGVjdEZpZWxkIiwiZGVmYXVsdF9haWRfdHlwZSIsImVhcm1hcmtpbmdfY2F0ZWdvcnkiLCJlYXJtYXJraW5nX21vZGFsaXR5IiwiY2FzaF9hbmRfdm91Y2hlcl9tb2RhbGl0aWVzIiwiY2FzZTEiLCJjYXNlMiIsImNhc2UzIiwiY2FzZTQiLCJhaWRfdHlwZSIsIl90aGlzNiIsInBvbGljeW1ha2VyX3ZvY2FidWxhcnkiLCJwb2xpY3lfbWFya2VyIiwiaGlkZVBvbGljeU1ha2VyRmllbGQiLCJjYXNlMV9zaG93IiwiY2FzZTJfc2hvdyIsIl90aGlzNyIsInNlY3Rvcl92b2NhYnVsYXJ5Iiwic2VjdG9yIiwiaGlkZVNlY3RvckZpZWxkIiwiY2FzZTdfc2hvdyIsImNhc2U4X3Nob3ciLCJjYXNlOThfOTlfc2hvdyIsImRlZmF1bHRfc2hvdyIsImNhc2U3IiwiY2FzZTgiLCJjYXNlOThfOTkiLCJkZWZhdWx0X2hpZGUiLCJfdGhpczgiLCJyZWdpb25fdm9jYWJ1bGFyeSIsInJlZ2lvbl92b2NhYiIsImhpZGVSZWNpcGllbnRSZWdpb25GaWVsZCIsImNhc2U5OV9zaG93IiwiY2FzZTk5IiwidXBkYXRlQWN0aXZpdHlJZGVudGlmaWVyIiwiYWN0aXZpdHlfaWRlbnRpZmllciIsImNvbmNhdCIsIl90aGlzOSIsInRhZ192b2NhYnVsYXJ5IiwidGFnIiwiaGlkZVRhZ0ZpZWxkIiwiY2FzZTNfc2hvdyIsImRvY3VtZW50IiwiZXZlbnQiLCJzdG9wUHJvcGFnYXRpb24iLCJjb25zb2xlIiwibG9nIiwiaGVscFRleHQiLCJjc3MiLCJvcGFjaXR5IiwidmlzaWJpbGl0eSIsImNsb3NlSGVscFRleHQiLCJzZXRUaW1lb3V0IiwiX3RvQ29uc3VtYWJsZUFycmF5IiwiYXJyIiwiX2FycmF5V2l0aG91dEhvbGVzIiwiX2l0ZXJhYmxlVG9BcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsIl9ub25JdGVyYWJsZVNwcmVhZCIsIml0ZXIiLCJTeW1ib2wiLCJpdGVyYXRvciIsIkFycmF5IiwiZnJvbSIsImlzQXJyYXkiLCJfYXJyYXlMaWtlVG9BcnJheSIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwibyIsImFsbG93QXJyYXlMaWtlIiwiaXQiLCJGIiwicyIsIm4iLCJkb25lIiwiX2UiLCJmIiwibm9ybWFsQ29tcGxldGlvbiIsImRpZEVyciIsImVyciIsImNhbGwiLCJzdGVwIiwibmV4dCIsIl9lMiIsIm1pbkxlbiIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwidGVzdCIsImxlbiIsImFycjIiLCJheGlvc18xIiwiRHluYW1pY0ZpZWxkXzEiLCJkeW5hbWljRmllbGQiLCJGb3JtQnVpbGRlciIsImFkZEZvcm0iLCJldiIsInByZXZlbnREZWZhdWx0IiwiY29udGFpbmVyIiwiY291bnQiLCJwYXJzZUludCIsInBhcmVudCIsInBhcmVudF9jb3VudCIsInBhcmVudHMiLCJ3cmFwcGVyX3BhcmVudF9jb3VudCIsInByb3RvIiwicmVwbGFjZSIsInByZXYiLCJhcHBlbmQiLCJjaGlsZHJlbiIsImxhc3QiLCJzZWxlY3QyIiwicGxhY2Vob2xkZXIiLCJhbGxvd0NsZWFyIiwid3JhcEFsbCIsImFkZFBhcmVudEZvcm0iLCJhZGRXcmFwcGVyT25BZGQiLCJkZWxldGVGb3JtIiwiY29sbGVjdGlvbkxlbmd0aCIsInRnIiwicmVtb3ZlIiwiZGVsZXRlUGFyZW50Rm9ybSIsImFkZFdyYXBwZXIiLCJmb3JtRmllbGQiLCJ0ZXh0QXJlYUhlaWdodCIsImhlaWdodCIsInNjcm9sbEhlaWdodCIsImFkZFRvQ29sbGVjdGlvbiIsImhhc0NsYXNzIiwiaGFuZGxlRGVsZXRlUGFyZW50QnV0dG9ucyIsImRlbGV0ZUNvbGxlY3Rpb24iLCJkZWxldGVDb25maXJtYXRpb24iLCJjYW5jZWxQb3B1cCIsImRlbGV0ZUNvbmZpcm0iLCJkZWxldGVJbmRleCIsImNoaWxkT3JQYXJlbnQiLCJmYWRlSW4iLCJmYWRlT3V0IiwiZGVsZXRlQnV0dG9uIiwibXVsdGlGb3JtIiwiYmFja2dyb3VuZCIsIm91dGxpbmUiLCJmaWxlUGF0aCIsInVybCIsImdldCIsInRoZW4iLCJyZXNwb25zZSIsInN1Y2Nlc3MiLCJmb3JtYXQiLCJtaW1ldHlwZSIsIm1lc3NhZ2UiLCJmaWxlVXJsIiwiZGVsZXRlQnV0dG9ucyIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJjaGFuZ2VEZWxldGVCdXR0b25Jbm5lckh0bWwiLCJidXR0b24iLCJpbml0aWFsVGV4dCIsImVzY2FwZUh0bWwiLCJ0ZXh0Q29udGVudCIsImlubmVySFRNTCIsImZvckVhY2giLCJmb3JtQnVpbGRlciIsInRleHRBcmVhVGFyZ2V0Iiwic2VsZWN0X3NlYXJjaCIsInF1ZXJ5U2VsZWN0b3IiLCJmb2N1cyIsInVwZGF0ZVJlZ2lzdHJhdGlvbkFnZW5jeSIsImNvdW50cnkiLCJlbmRwb2ludCIsImFqYXgiLCJjdXJyZW50X3ZhbCIsImVtcHR5IiwiT3B0aW9uIiwiaWRlbnRpZmllciIsInN1YmVsZW1lbnQiLCJ0aXRsZSIsImVycm9yQ29udGFpbmVyIiwiY2hpbGRDb3VudCIsImNoaWxkRWxlbWVudENvdW50IiwiY2xhc3NMaXN0IiwiYWRkIiwicmVhZE9ubHlTZWxlY3RzIiwic2VsZWN0Iiwic2VsZWN0RWxlbWVudFBhcmVudFdyYXBwZXIiLCJuZXh0U2libGluZyIsInNlbGVjdEVsZW1lbnRQYXJlbnQiLCJmaXJzdENoaWxkIiwic2VsZWN0RWxlbWVudCIsInN0eWxlIiwiY3Vyc29yIiwib2JzZXJ2ZXIiLCJNdXRhdGlvbk9ic2VydmVyIiwibXV0YXRpb25zTGlzdCIsIm11dGF0aW9uIiwiYWRkZWROb2RlcyIsIm5vZGUiLCJFbGVtZW50IiwibWF0Y2hlcyIsIm5ld0RlbGV0ZUJ1dHRvbnMiLCJvYnNlcnZlIiwiYm9keSIsImNoaWxkTGlzdCIsInN1YnRyZWUiLCJhdHRhY2hDb2xsYXBzYWJsZUJ1dHRvbkV2ZW50cyIsImxhYmVsIiwiZ2V0Q2xvc2VzdExhYmVsRG9tIiwib3B0aW9uYWxMYWJlbCIsImdldE9wdGlvbmFsVGV4dERvbSIsImdldENsb3Nlc3RQYXJlbnRTdWJlbGVtZW50RG9tIiwidGhpc0J1dHRvbkJlbG9uZ3NUb09wdGlvbmFsRm9ybSIsImFkZEV2ZW50TGlzdGVuZXIiLCJ0b2dnbGVPcHRpb25hbFRleHQiLCJ0b2dnbGVBY2NvcmRpb25JdGVtcyIsInRvZ2dsZSIsImVycm9yTWVzc2FnZUV4aXN0cyIsImNsaWNrIiwiZXJyb3JEaXZzIiwiZXJyb3JUZXh0cyIsIl9pdGVyYXRvciIsIl9zdGVwIiwiZGl2IiwidHJpbSIsIl9pdGVyYXRvcjIiLCJfc3RlcDIiLCJvcHRpb25hbExhYmVsV2l0aFN2ZyIsIm9wdGlvbmFsTGFiZWxXaXRoQnJhY2tldHMiLCJzdmdFeGlzdHMiLCJpc0FkZEFkZGl0aW9uYWxCdXR0b25PdXRzaWRlIiwibmV4dEVsZW1lbnRTaWJsaW5nIiwidGFnTmFtZSIsImNvbnRhaW5zIiwiaGlkZWFibGVTdWJlbGVtZW50cyIsImZpbHRlciIsImNoaWxkIiwib3V0c2lkZUJ1dHRvbiIsImhhc0FkZEFkZGl0aW9uYWxCdXR0b25PdXRzaWRlIiwiYXR0YWNoSW5pdGlhbENvbGxhcHNhYmxlQnV0dG9uRXZlbnRzIiwiYWxsQ29sbGFwc2FibGVCdXR0b25zIiwib2JzZXJ2ZU5ld0NvbGxhcHNhYmxlQnV0dG9ucyIsInR5cGUiLCJIVE1MRWxlbWVudCIsIm5ld0NvbGxhcHNhYmxlQnV0dG9ucyIsInVuc2FmZSJdLCJzb3VyY2VSb290IjoiIn0= \ No newline at end of file diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 42a1ac6ebb..f11f86a46f 100755 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,8 +1,8 @@ { - "/js/app.js": "/js/app.js?id=9ad6a60f9e4920935e882b84c76134bd", - "/js/script.js": "/js/script.js?id=1b7daeec82b90108f10210751a69236d", - "/js/webportal-script.js": "/js/webportal-script.js?id=b575e764668b3559917bdf4cce514c6b", - "/js/formbuilder.js": "/js/formbuilder.js?id=fe5f7ed2f535b132deb64e41f45d7a35", + "/js/app.js": "/js/app.js?id=d90f4c0ff15fdac44b1efd5a25837063", + "/js/script.js": "/js/script.js?id=5022c99737e05b78f00088f76a8a0f9f", + "/js/webportal-script.js": "/js/webportal-script.js?id=1bcae4271c042a8b79b241f34a1653fc", + "/js/formbuilder.js": "/js/formbuilder.js?id=61b98dc742ffedfa84ee6995cd9691c5", "/manifest.js": "/manifest.js?id=3ed1124c8f4dcb98acc36de67cb80349", "/css/webportal-app.css": "/css/webportal-app.css?id=71f014dd2fe03c8a8042e36f88cfb349", "/css/app.css": "/css/app.css?id=77cbecca26daebdbb95eed429e8a1e6e", diff --git a/tests/Feature/Element/ContactInfoCompleteTest.php b/tests/Feature/Element/ContactInfoCompleteTest.php index c8e045b02e..fc38ec17ec 100644 --- a/tests/Feature/Element/ContactInfoCompleteTest.php +++ b/tests/Feature/Element/ContactInfoCompleteTest.php @@ -4,521 +4,269 @@ namespace Tests\Feature\Element; +use App\IATI\Models\Activity\Activity; +use Illuminate\Support\Arr; +use Tests\Traits\FilterMandatoryItemsTrait; + /** - * Class ContactInfoCompleteTest. + * Class LocationCompleteTest. */ class ContactInfoCompleteTest extends ElementCompleteTest { + use FilterMandatoryItemsTrait; + /** - * Element contact_info. + * Element location. * * @var string */ private string $element = 'contact_info'; /** - * Mandatory attribute test. - * - * @return void - * @throws \JsonException + * @var array|string[] */ - public function test_contact_info_mandatory_attributes(): void - { - $this->test_mandatory_attributes($this->element, []); - } + private array $mandatoryAttributes = ['attributes.type.criteria' => 'mandatory']; /** - * Mandatory sub element test. - * - * @return void - * @throws \JsonException + * @var array */ - public function test_condition_mandatory_sub_elements(): void - { - $this->test_mandatory_sub_elements($this->element, []); - } + private array $mandatorySubelements = []; /** - * Empty contact_info data test. + * Test for ensuring mandatory attributes have not changed since the time of writing this test. * * @return void - * @throws \JsonException - */ - public function test_contact_info_empty_data(): void - { - $actualData = ''; - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Empty contact_info array test. - * - * @return void - * @throws \JsonException - */ - public function test_contact_info_empty_array(): void - { - $actualData = json_decode('[]', true, 512, JSON_THROW_ON_ERROR); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Empty contact_info json array test. - * - * @return void - * @throws \JsonException - */ - public function test_contact_info_empty_json_array(): void - { - $actualData = json_decode('[{}]', true, 512, JSON_THROW_ON_ERROR); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element person_name empty test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_empty_person_name(): void + public function test_contact_info_mandatory_attributes_have_not_changed(): void { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":"","job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR + $contactInfoSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $contactInfoFlattened = flattenArrayWithKeys($contactInfoSchema); + $contactInfoFlattened = getItemsWhereKeyContains($contactInfoFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $contactInfoFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' ); - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); - } + $this->unsetMandatorySubelements($mandatoryItemsInSchema); - /** - * Sub element person_name empty array test. - * - * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_empty_person_name_array(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[],"job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); + $this->assertEquals($mandatoryItemsInSchema, $this->mandatoryAttributes); } /** - * Sub element person_name empty json array test. + * Test for ensuring mandatory subelements have not changed since the time of writing this test. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_empty_person_name_json_array(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{}],"job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); - } - - /** - * Sub element person_name empty narrative test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_person_name_empty_narrative(): void + public function test_contact_info_subelements_have_not_changed(): void { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":""}],"job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR + $contactInfoSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $contactInfoFlattened = flattenArrayWithKeys($contactInfoSchema); + $contactInfoFlattened = getItemsWhereKeyContains($contactInfoFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $contactInfoFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' ); - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); - } + $this->unsetMandatoryAttributes($mandatoryItemsInSchema); - /** - * Sub element person_name empty narrative array test. - * - * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_person_name_empty_narrative_array(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[]}],"job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); + $this->assertEquals($mandatoryItemsInSchema, $this->mandatorySubelements); } /** - * Sub element person_name empty narrative json array test. + * Test for ensuring the contact info is not complete with empty data. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_person_name_empty_narrative_json_array(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{}]}],"job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); - } - - /** - * Sub element person_name sub element narrative empty narrative test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_person_name_sub_element_narrative_empty_narrative(): void + public function test_contact_info_is_not_complete_in_empty_data(): void { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"","language":"en"}]}],"job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $actualData = []; - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); + $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); } /** - * Sub element person_name sub element narrative no narrative key test. + * Test for ensuring the contact info is not complete with an empty JSON array. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_person_name_sub_element_narrative_no_narrative_key(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"language":"en"}]}],"job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); - } - - /** - * Sub element job_title empty test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_empty_job_title(): void + public function test_contact_info_empty_json_array(): void { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":"","telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $actualData = json_decode('[{}]', true, 512, JSON_THROW_ON_ERROR); $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); } /** - * Sub element job_title empty array test. + * Test for checking if contact info is incomplete when all sub-elements are filled except for the type attribute. * * @return void + * * @throws \JsonException */ - public function test_contact_info_sub_element_empty_job_title_array(): void + public function test_contact_info_is_incomplete_when_all_subelements_are_filled_except_type_attribute() { + $activity = new Activity(); + $data = '[{"type":null,"organisation":[{"narrative":[{"narrative":"Org name","language":"ng"}]}],"department":[{"narrative":[{"narrative":"Dept","language":"ng"}]}],"person_name":[{"narrative":[{"narrative":"John","language":"ng"}]}],"job_title":[{"narrative":[{"narrative":"PM","language":"ng"}]}],"telephone":[{"telephone":"9860123456"}],"email":[{"email":"superadmin@yipl.com.np"}],"website":[{"website":"https://iatipublisher-staging.yipl.com.np"}],"mailing_address":[{"narrative":[{"narrative":"Mahalaxmi-sthan, Patan","language":"ng"}]}]}]'; $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', + $data, true, 512, JSON_THROW_ON_ERROR ); + $activity->contact_info = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isContactInfoElementCompleted($activity)); } /** - * Sub element job_title empty json array test. + * Test for checking if contact info is incomplete when the type attribute is filled but no sub-elements are filled. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_empty_job_title_json_array(): void - { - $actualData = json_decode('[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', true, 512, JSON_THROW_ON_ERROR); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element job_title empty narrative test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_job_title_empty_narrative(): void + public function test_contact_info_is_incomplete_when_type_attribute_is_filled_but_no_subelement_is_filled() { + $activity = new Activity(); + $data = '[{"type":"1","organisation":[{"narrative":[{"narrative":null,"language":null}]}],"department":[{"narrative":[{"narrative":null,"language":null}]}],"person_name":[{"narrative":[{"narrative":null,"language":null}]}],"job_title":[{"narrative":[{"narrative":null,"language":null}]}],"telephone":[{"telephone":null}],"email":[{"email":null}],"website":[{"website":null}],"mailing_address":[{"narrative":[{"narrative":null,"language":null}]}]}]'; $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{"narrative":""}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', + $data, true, 512, JSON_THROW_ON_ERROR ); + $activity->contact_info = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isContactInfoElementCompleted($activity)); } /** - * Sub element job_title empty narrative array test. + * Test for checking if contact info is complete when the type attribute plus any sub-element is filled. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_job_title_empty_narrative_array(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{"narrative":[]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element job_title empty narrative json array test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_job_title_empty_narrative_json_array(): void + public function test_contact_info_is_complete_when_type_attribute_plus_any_subelement_is_filled() { + $activity = new Activity(); + $data = '[{"type":"1","organisation":[{"narrative":[{"narrative":"narr 1","language":"en"}]}],"department":[{"narrative":[{"narrative":null,"language":null}]}],"person_name":[{"narrative":[{"narrative":null,"language":null}]}],"job_title":[{"narrative":[{"narrative":null,"language":null}]}],"telephone":[{"telephone":null}],"email":[{"email":null}],"website":[{"website":null}],"mailing_address":[{"narrative":[{"narrative":null,"language":null}]}]}]'; $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', + $data, true, 512, JSON_THROW_ON_ERROR ); + $activity->contact_info = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isContactInfoElementCompleted($activity)); } /** - * Sub element job_title sub element narrative empty narrative test. + * Test for checking if contact info is complete when the type attribute plus multiple sub-elements are filled. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_job_title_sub_element_narrative_empty_narrative(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{"narrative":[{"narrative":"","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element job_title sub element narrative no narrative key test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_job_title_sub_element_narrative_no_narrative_key(): void + public function test_contact_info_is_complete_when_type_attribute_plus_multiple_subelements_are_filled() { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{"narrative":[{"language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $activity = new Activity(); + $data = '[{"type":"1","organisation":[{"narrative":[{"narrative":"Org name","language":"en"}]}],"department":[{"narrative":[{"narrative":"Dept","language":"en"}]}],"person_name":[{"narrative":[{"narrative":null,"language":null}]}],"job_title":[{"narrative":[{"narrative":null,"language":null}]}],"telephone":[{"telephone":"123456789"}],"email":[{"email":"test@example.com"}],"website":[{"website":"https://example.com"}],"mailing_address":[{"narrative":[{"narrative":"Address","language":"en"}]}]}]'; + $actualData = json_decode($data, true, 512, JSON_THROW_ON_ERROR); + $activity->contact_info = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isContactInfoElementCompleted($activity)); } /** - * Sub element mailing_address empty test. + * Test for checking if contact info is incomplete when the type attribute is missing. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_empty_mailing_address(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"contact-info1-person-name-narrative1","language":"ae"}]}],"job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":""}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element mailing_address empty array test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_empty_mailing_address_array(): void + public function test_contact_info_is_incomplete_when_type_attribute_is_missing() { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $activity = new Activity(); + $data = '[{"organisation":[{"narrative":[{"narrative":"Org name","language":"en"}]}]}]'; + $actualData = json_decode($data, true, 512, JSON_THROW_ON_ERROR); + $activity->contact_info = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isContactInfoElementCompleted($activity)); } /** - * Sub element mailing_address empty json array test. + * Test for checking if contact info is incomplete when the contact info element is missing. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_empty_mailing_address_json_array(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element mailing_address empty narrative test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_mailing_address_empty_narrative(): void + public function test_contact_info_is_incomplete_when_contact_info_element_is_missing() { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{"narrative":""}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":""}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $activity = new Activity(); + $activity->contact_info = null; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isContactInfoElementCompleted($activity)); } /** - * ub element mailing_address empty narrative array test. + * Test for checking if contact info is complete with the type attribute and all sub-elements filled. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_mailing_address_empty_narrative_array(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{"narrative":[]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element mailing_address empty narrative json array test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_mailing_address_empty_narrative_json_array(): void + public function test_contact_info_is_complete_with_type_attributes_and_all_sub_elements_filled() { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $activity = new Activity(); + $data = '[{"type":"1","organisation":[{"narrative":[{"narrative":"Org name","language":"en"}]}],"department":[{"narrative":[{"narrative":"Dept","language":"en"}]}],"person_name":[{"narrative":[{"narrative":"John Doe","language":"en"}]}],"job_title":[{"narrative":[{"narrative":"Manager","language":"en"}]}],"telephone":[{"telephone":"123456789"}],"email":[{"email":"test@example.com"}],"website":[{"website":"https://example.com"}],"mailing_address":[{"narrative":[{"narrative":"Address","language":"en"}]}]}]'; + $actualData = json_decode($data, true, 512, JSON_THROW_ON_ERROR); + $activity->contact_info = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isContactInfoElementCompleted($activity)); } /** - * Sub element mailing_address sub element narrative empty narrative test. + * Test for checking if multiple contact info elements are incomplete when one instance is incomplete. * * @return void - * @throws \JsonException - */ - public function test_contact_info_sub_element_mailing_address_sub_element_narrative_empty_narrative(): void - { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{"narrative":[{"narrative":"","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element mailing_address sub element narrative no narrative key test. * - * @return void * @throws \JsonException */ - public function test_contact_info_sub_element_mailing_address_sub_element_narrative_no_narrative_key(): void + public function test_multiple_contact_info_is_incomplete_when_one_is_incomplete() { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"asd","language":"en"}]}],"job_title":[{"narrative":[{"language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $activity = new Activity(); + $data = '[{"type":"1","organisation":[{"narrative":[{"narrative":"Org name","language":"en"}]}],"department":[{"narrative":[{"narrative":"Dept","language":"en"}]}],"person_name":[{"narrative":[{"narrative":"John","language":"en"}]}],"job_title":[{"narrative":[{"narrative":"PM","language":"en"}]}],"telephone":[{"telephone":"123456789"}],"email":[{"email":"test@example.com"}],"website":[{"website":"https://example.com"}],"mailing_address":[{"narrative":[{"narrative":"Address","language":"en"}]}]}, {"type":"2","organisation":[],"department":[],"person_name":[],"job_title":[],"telephone":[{"telephone":null}],"email":[{"email":null}],"website":[{"website":null}],"mailing_address":[]}]'; + $actualData = json_decode($data, true, 512, JSON_THROW_ON_ERROR); + $activity->contact_info = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isContactInfoElementCompleted($activity)); } /** - * Contact Info element complete test. + *Test for checking if multiple contact info elements with all contact info instances complete. * * @return void + * * @throws \JsonException */ - public function test_contact_info_element_complete(): void + public function test_multiple_contact_info_elements_with_one_complete() { - $actualData = json_decode( - '[{"type":"1","organisation":[{"narrative":[{"narrative":"contact-info1-org-narrative1","language":"aa"}]}],"department":[{"narrative":[{"narrative":"contact-info1-dept-narrative1","language":"ab"}]}],"person_name":[{"narrative":[{"narrative":"contact-info1-person-name-narrative1","language":"ae"}]}],"job_title":[{"narrative":[{"narrative":"contact-info1-job-title-narrative1","language":"af"}]}],"telephone":[{"telephone":"+977-0044111222333444"}],"email":[{"email":"manish.pradhan@yipl.com.np"}],"website":[{"website":"https:\/\/www.google.com"}],"mailing_address":[{"narrative":[{"narrative":"contact-info1-mailing-address-narrative1","language":"am"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $activity = new Activity(); + $data = '[{"type":"1","organisation":[{"narrative":[{"narrative":"Org name","language":"en"}]}],"department":[{"narrative":[{"narrative":"Dept","language":"en"}]}],"person_name":[{"narrative":[{"narrative":"John","language":"en"}]}],"job_title":[{"narrative":[{"narrative":"PM","language":"en"}]}],"telephone":[{"telephone":"123456789"}],"email":[{"email":"test@example.com"}],"website":[{"website":"https://example.com"}],"mailing_address":[{"narrative":[{"narrative":"Address","language":"en"}]}]}, {"type":"1","organisation":[{"narrative":[{"narrative":"narr 1","language":"en"}]}],"department":[{"narrative":[{"narrative":null,"language":null}]}],"person_name":[{"narrative":[{"narrative":null,"language":null}]}],"job_title":[{"narrative":[{"narrative":null,"language":null}]}],"telephone":[{"telephone":null}],"email":[{"email":null}],"website":[{"website":null}],"mailing_address":[{"narrative":[{"narrative":null,"language":null}]}]}]'; + $actualData = json_decode($data, true, 512, JSON_THROW_ON_ERROR); + $activity->contact_info = $actualData; - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isContactInfoElementCompleted($activity)); } } diff --git a/tests/Feature/Element/CountryBudgetItemTest.php b/tests/Feature/Element/CountryBudgetItemTest.php index 3bd0a199e0..244692494b 100644 --- a/tests/Feature/Element/CountryBudgetItemTest.php +++ b/tests/Feature/Element/CountryBudgetItemTest.php @@ -4,11 +4,17 @@ namespace Tests\Feature\Element; +use App\IATI\Models\Activity\Activity; +use Illuminate\Support\Arr; +use Tests\Traits\FilterMandatoryItemsTrait; + /** * Class CountryBudgetItemTest. */ class CountryBudgetItemTest extends ElementCompleteTest { + use FilterMandatoryItemsTrait; + /** * Element country_budget_items. * @@ -17,249 +23,344 @@ class CountryBudgetItemTest extends ElementCompleteTest private string $element = 'country_budget_items'; /** - * Mandatory attribute test. - * - * @return void - * @throws \JsonException + * @var array|string[] */ - public function test_country_budget_items_mandatory_attributes(): void - { - $this->test_mandatory_attributes($this->element, ['country_budget_vocabulary']); - } + private array $mandatorySubelements = ['sub_elements.budget_item.attributes.code.criteria' => 'mandatory']; /** - * Mandatory sub element test. + * @var array|string[] + */ + private array $mandatoryAttributes = ['attributes.country_budget_vocabulary.criteria' => 'mandatory']; + + /** + * Test for ensuring mandatory attributes have not changed since the time of writing this test. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_mandatory_sub_elements(): void + public function test_contact_info_mandatory_attributes_have_not_changed(): void { - $this->test_mandatory_sub_elements($this->element, ['budget_item' => ['code']]); + $countryBudgetItemSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $countryBudgetItemFlattened = flattenArrayWithKeys($countryBudgetItemSchema); + $countryBudgetItemFlattened = getItemsWhereKeyContains($countryBudgetItemFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $countryBudgetItemFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatorySubelements($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatoryAttributes); } /** - * Empty all element test. + * Test for ensuring mandatory subelements have not changed since the time of writing this test. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_all_empty(): void + public function test_contact_info_subelements_have_not_changed(): void { - $actualData = json_decode( - '{"country_budget_vocabulary":"","budget_item":[{"code":"","percentage":"50","description":[{"narrative":[{"narrative":"","language":"aa"}]}]}]}', - true, - 512, - JSON_THROW_ON_ERROR + $countryBudgetItemSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $countryBudgetItemFlattened = flattenArrayWithKeys($countryBudgetItemSchema); + $countryBudgetItemFlattened = getItemsWhereKeyContains($countryBudgetItemFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $countryBudgetItemFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' ); - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $this->unsetMandatoryAttributes($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatorySubelements); } /** - * Attribute country_budget_vocabulary empty test. + * Test for ensuring the contact info is not complete with null value. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_attribute_empty_country_budget_vocabulary(): void + public function test_contact_info_is_not_complete_in_empty_null(): void { - $actualData = json_decode( - '{"country_budget_vocabulary":"","budget_item":[{"code":"12","percentage":"50","description":[{"narrative":[{"narrative":"asdas","language":"aa"}]}]}]}', - true, - 512, - JSON_THROW_ON_ERROR - ); + $actualData = null; + $activity = new Activity(); + $activity->country_budget_items = $actualData; - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item empty data test. + * Test for ensuring the contact info is not complete with empty array as value. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_sub_element_empty_budget_item(): void + public function test_contact_info_is_not_complete_in_empty_array(): void { - $actualData = json_decode('{"country_budget_vocabulary":"2","budget_item":""}', true, 512, JSON_THROW_ON_ERROR); + $actualData = []; + $activity = new Activity(); + $activity->country_budget_items = $actualData; - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item empty array test. + * Test for ensuring the contact info is not complete with empty json array as value. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_sub_element_empty_budget_item_array(): void + public function test_contact_info_is_not_complete_in_empty_json_array(): void { - $actualData = json_decode('{"country_budget_vocabulary":"2","budget_item":[]}', true, 512, JSON_THROW_ON_ERROR); + $actualData = json_decode('[{}]'); + $activity = new Activity(); + $activity->country_budget_items = $actualData; - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item empty json array test. + * Test for ensuring the contact info is not complete when country budget vocabulary key is missing. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_sub_element_empty_budget_item_json_array(): void + public function test_country_budget_item_incomplete_when_country_budget_vocab_key_missing(): void { - $actualData = json_decode('{"country_budget_vocabulary":"2","budget_item":[{}]}', true, 512, JSON_THROW_ON_ERROR); + $actualData = json_decode( + '{"budget_item":[{"code":null,"percentage":null,"description":[{"narrative":[{"narrative":null,"language":null}]}]}]}', + true, + 512, + JSON_THROW_ON_ERROR + ); - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->country_budget_items = $actualData; + + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item attribute empty code test. + * Test for ensuring the contact info is not complete when budget item key is missing. * * @return void * @throws \JsonException */ - public function test_country_budget_items_sub_element_budget_item_attribute_empty_code(): void + public function test_country_budget_item_incomplete_when_budget_item_key_missing(): void { $actualData = json_decode( - '{"country_budget_vocabulary":"2","budget_item":[{"code":"","percentage":"50","description":[{"narrative":[{"narrative":"asdas","language":"aa"}]}]}]}', + '{"country_budget_vocabulary":null}', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->country_budget_items = $actualData; + + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item sub element empty description test. + * Test for ensuring the contact info is not complete when all values are null. * * @return void * @throws \JsonException */ - public function test_country_budget_items_sub_element_budget_item_sub_element_empty_description(): void + public function test_country_budget_item_incomplete_when_all_null(): void { - $actualData = json_decode('{"country_budget_vocabulary":"2","budget_item":[{"code":"123","percentage":"50","description":""}]}', true, 512, JSON_THROW_ON_ERROR); + $actualData = json_decode( + '{"country_budget_vocabulary":null,"budget_item":[{"code":null,"percentage":null,"description":[{"narrative":[{"narrative":null,"language":null}]}]}]}', + true, + 512, + JSON_THROW_ON_ERROR + ); - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->country_budget_items = $actualData; + + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item sub element empty description array test. + * Test for ensuring the contact info is not complete when only country budget vocab is filled. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_sub_element_budget_item_sub_element_empty_description_array(): void + public function test_country_budget_item_incomplete_when_only_attribute_is_filled(): void { - $actualData = json_decode('{"country_budget_vocabulary":"2","budget_item":[{"code":"123","percentage":"50","description":[]}]}', true, 512, JSON_THROW_ON_ERROR); + $actualData = json_decode( + '{"country_budget_vocabulary":"2","budget_item":[{"code":null,"percentage":null,"description":[{"narrative":[{"narrative":null,"language":null}]}]}]}', + true, + 512, + JSON_THROW_ON_ERROR + ); + + $activity = new Activity(); + $activity->country_budget_items = $actualData; - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item sub element empty description json array test. + * Test for ensuring the contact info is not complete when all mandatory empty string. * * @return void * @throws \JsonException */ - public function test_country_budget_items_sub_element_budget_item_sub_element_empty_description_json_array(): void + public function test_country_budget_items_when_all_mandatory_fields_are_empty_string(): void { - $actualData = json_decode('{"country_budget_vocabulary":"2","budget_item":[{"code":"123","percentage":"50","description":[{}]}]}', true, 512, JSON_THROW_ON_ERROR); + $actualData = json_decode( + '{"country_budget_vocabulary":"","budget_item":[{"code":"","percentage":null,"description":[{"narrative":[{"narrative":null,"language":null}]}]}]}', + true, + 512, + JSON_THROW_ON_ERROR + ); - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->country_budget_items = $actualData; + + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item sub element description empty narrative test. + * Test for ensuring the contact info is not complete when some mandatory empty string. * * @return void * @throws \JsonException */ - public function test_country_budget_items_sub_element_budget_item_sub_element_description_empty_narrative(): void + public function test_country_budget_items_when_some_mandatory_fields_are_empty_string(): void { - $actualData = json_decode('{"country_budget_vocabulary":"2","budget_item":[{"code":"123","percentage":"50","description":[{"narrative":""}]}]}', true, 512, JSON_THROW_ON_ERROR); + $actualData = json_decode( + '{"country_budget_vocabulary":"2","budget_item":[{"code":"","percentage":null,"description":[{"narrative":[{"narrative":null,"language":null}]}]}]}', + true, + 512, + JSON_THROW_ON_ERROR + ); + + $activity = new Activity(); + $activity->country_budget_items = $actualData; - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item sub element description empty narrative array test. + * Test for ensuring the contact info is complete when mandatory fields are filled + percentage is null. * * @return void * @throws \JsonException */ - public function test_country_budget_items_sub_element_budget_item_sub_element_description_empty_narrative_array(): void + public function test_country_budget_items_when_mandatory_fields_are_filled_and_percentage_is_null(): void { - $actualData = json_decode('{"country_budget_vocabulary":"2","budget_item":[{"code":"123","percentage":"50","description":[{"narrative":[]}]}]}', true, 512, JSON_THROW_ON_ERROR); + $actualData = json_decode( + '{"country_budget_vocabulary":"2","budget_item":[{"code":"1.2.1","percentage":null,"description":[{"narrative":[{"narrative":null,"language":null}]}]}]}', + true, + 512, + JSON_THROW_ON_ERROR + ); - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->country_budget_items = $actualData; + + $this->assertTrue($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item sub element description empty narrative json array test. + * Test for ensuring the contact info is complete when mandatory fields are filled + percentage is 100. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_sub_element_budget_item_sub_element_description_empty_narrative_json_array(): void + public function test_country_budget_items_when_mandatory_fields_are_filled_and_percentage_is_100(): void { - $actualData = json_decode('{"country_budget_vocabulary":"2","budget_item":[{"code":"123","percentage":"50","description":[{"narrative":[{}]}]}]}', true, 512, JSON_THROW_ON_ERROR); + $actualData = json_decode( + '{"country_budget_vocabulary":"2","budget_item":[{"code":"1.2.1","percentage":"100","description":[{"narrative":[{"narrative":null,"language":null}]}]}]}', + true, + 512, + JSON_THROW_ON_ERROR + ); + + $activity = new Activity(); + $activity->country_budget_items = $actualData; - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item sub element description no narrative key test. + * Test for ensuring the contact info is not complete when + * multiple budget item are filled but some of them are incomplete. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_sub_element_budget_item_sub_element_description_sub_element_narrative_no_narrative_key(): void - { + public function test_country_budget_items_when_multiple_budget_items_are_filled_with_some_mandatory_fields_not_filled( + ): void { $actualData = json_decode( - '{"country_budget_vocabulary":"2","budget_item":[{"code":"123","percentage":"50","description":[{"narrative":[{"language":"en"}]}]}]}', + '{"country_budget_vocabulary":"2","budget_item":[{"code":"1.2.1","percentage":"50","description":[{"narrative":[{"narrative":null,"language":null}]}]},{"code":null,"percentage":"50","description":[{"narrative":[{"narrative":null,"language":null}]}]}]}', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->country_budget_items = $actualData; + + $this->assertFalse($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Sub element budget_item sub element description empty narrative test. + * Test for ensuring the contact info is not complete when + * multiple budget item are filled and all their required fields are filled. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_sub_element_budget_item_sub_element_description_sub_element_narrative_empty_narrative(): void + public function test_country_budget_items_when_multiple_budget_items_are_filled_with_mandatory_fields_filled(): void { $actualData = json_decode( - '{"country_budget_vocabulary":"2","budget_item":[{"code":"123","percentage":"50","description":[{"narrative":[{"narrative":"","language":"en"}]}]}]}', + '{"country_budget_vocabulary":"2","budget_item":[{"code":"1.2.1","percentage":"50","description":[{"narrative":[{"narrative":null,"language":null}]}]},{"code":"1.1.1","percentage":"50","description":[{"narrative":[{"narrative":null,"language":null}]}]}]}', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_three_single_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->country_budget_items = $actualData; + + $this->assertTrue($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } /** - * Country Budget Items element complete test. + * Test for ensuring the contact info is not complete when + * multiple budget item are filled and all their required fields are filled. * * @return void + * * @throws \JsonException */ - public function test_country_budget_items_element_complete(): void + public function test_country_budget_items_when_multiple_budget_items_are_filled_and_everything_is_filled(): void { $actualData = json_decode( - '{"country_budget_vocabulary":"2","budget_item":[{"code":"asdasd","percentage":"50","description":[{"narrative":[{"narrative":"asdas","language":"aa"}]}]},{"code":"asdad","percentage":"50","description":[{"narrative":[{"narrative":"asdadasddad","language":"ae"}]}]}]}', + '{"country_budget_vocabulary":"2","budget_item":[{"code":"1.2.1","percentage":"41","description":[{"narrative":[{"narrative":null,"language":null}]}]},{"code":"1.2.1","percentage":"59","description":[{"narrative":[{"narrative":"budget item 2 description","language":"ak"}]}]}]}', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_three_single_dimensional_element_complete($this->element, $actualData); + $activity = new Activity(); + $activity->country_budget_items = $actualData; + + $this->assertTrue($this->elementCompleteService->isCountryBudgetItemsElementCompleted($activity)); } } diff --git a/tests/Feature/Element/ElementCompleteTest.php b/tests/Feature/Element/ElementCompleteTest.php index d56e038fb8..997a4a70b6 100644 --- a/tests/Feature/Element/ElementCompleteTest.php +++ b/tests/Feature/Element/ElementCompleteTest.php @@ -5,6 +5,7 @@ namespace Tests\Feature\Element; use App\IATI\Services\ElementCompleteService; +use Illuminate\Support\Arr; use Tests\TestCase; /** @@ -44,12 +45,12 @@ protected function arrayStructure($actual, $expected): bool } foreach ($expected as $key => $value) { - if (!$this->arrayStructure($actual[$key], $value)) { + if (!$this->arrayStructure(Arr::get($actual, $key, []), $value)) { return false; } } foreach ($actual as $key => $value) { - if (!$this->arrayStructure($value, $expected[$key])) { + if (!$this->arrayStructure($value, Arr::get($expected, $key, []))) { return false; } } diff --git a/tests/Feature/Element/LocationCompleteTest.php b/tests/Feature/Element/LocationCompleteTest.php index 9aceb910a8..3c5c1000db 100644 --- a/tests/Feature/Element/LocationCompleteTest.php +++ b/tests/Feature/Element/LocationCompleteTest.php @@ -4,11 +4,17 @@ namespace Tests\Feature\Element; +use App\IATI\Models\Activity\Activity; +use Illuminate\Support\Arr; +use Tests\Traits\FilterMandatoryItemsTrait; + /** * Class LocationCompleteTest. */ class LocationCompleteTest extends ElementCompleteTest { + use FilterMandatoryItemsTrait; + /** * Element location. * @@ -17,1043 +23,400 @@ class LocationCompleteTest extends ElementCompleteTest private string $element = 'location'; /** - * Mandatory attribute test. - * - * @return void - * @throws \JsonException + * @var array */ - public function test_location_mandatory_attributes(): void - { - $this->test_mandatory_attributes($this->element, []); - } + private array $mandatoryAttributes = []; /** - * Mandatory sub element test. - * - * @return void - * @throws \JsonException + * @var array */ - public function test_location_mandatory_sub_elements(): void - { - $this->test_mandatory_sub_elements($this->element, [ - 'location_reach' => ['code'], - 'administrative' => ['vocabulary', 'code'], - 'location_id' => ['vocabulary', 'code'], - 'point' => ['srs_name'], - 'location_class' => ['code'], - 'exactness' => ['code'], - 'feature_designation' => ['code'], - ]); - } + private array $mandatorySubelements = []; /** - * Empty data test. + * Test that mandatory attributes for location have not changed since the time of writing this test. * * @return void - * @throws \JsonException - */ - public function test_location_empty_data(): void - { - $actualData = ''; - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Empty array test. * - * @return void * @throws \JsonException */ - public function test_location_empty_array(): void + public function test_location_mandatory_attributes_have_not_changed(): void { - $actualData = json_decode('[]', true, 512, JSON_THROW_ON_ERROR); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } + $locationSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $locationFlattened = flattenArrayWithKeys($locationSchema); + $locationFlattened = getItemsWhereKeyContains($locationFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter($locationFlattened, fn ($item) => !empty($item) && $item == 'mandatory'); - /** - * Empty json array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_empty_json_array(): void - { - $actualData = json_decode('[{}]', true, 512, JSON_THROW_ON_ERROR); + $this->unsetMandatorySubelements($mandatoryItemsInSchema); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertEquals($mandatoryItemsInSchema, $this->mandatoryAttributes); } /** - * Sub element location_id empty test. + * Test that mandatory subelements for location have not changed since the time of writing this test. * * @return void - * @throws \JsonException - */ - public function test_location_sub_element_empty_location_id(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":"","name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element location_id empty array test. * - * @return void * @throws \JsonException */ - public function test_location_sub_element_empty_location_id_array(): void + public function test_location_sub_elements_have_not_changed(): void { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $locationSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $locationFlattened = flattenArrayWithKeys($locationSchema); + $locationFlattened = getItemsWhereKeyContains($locationFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter($locationFlattened, fn ($item) => !empty($item) && $item == 'mandatory'); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element location_id empty json array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_empty_location_id_json_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $this->unsetMandatoryAttributes($mandatoryItemsInSchema); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertEquals($mandatoryItemsInSchema, $this->mandatorySubelements); } /** - * Sub element location_id attribute vocabulary empty test. + * Test that 'location' is not complete when data is empty. * * @return void - * @throws \JsonException - */ - public function test_location_sub_element_location_id_empty_attribute_vocabulary(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element location_id attribute code empty test. * - * @return void * @throws \JsonException */ - public function test_location_sub_element_location_id_empty_attribute_code(): void + public function test_location_is_not_complete_in_empty_data(): void { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":""}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $actualData = []; $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); } /** - * Sub element name no key test. + * Test that 'location' is not complete when the data is an empty JSON array. * * @return void - * @throws \JsonException - */ - public function test_location_sub_element_no_name_key(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element name empty test. * - * @return void * @throws \JsonException */ - public function test_location_sub_element_name_empty(): void + public function test_location_empty_json_array(): void { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":"","description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $actualData = json_decode('[{}]', true, 512, JSON_THROW_ON_ERROR); $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); } /** - * Sub element name empty array test. + * Test that 'location' is incomplete when an attribute is filled. * * @return void - * @throws \JsonException - */ - public function test_location_sub_element_name_empty_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element name empty json array test. * - * @return void * @throws \JsonException */ - public function test_location_sub_element_name_empty_json_array(): void + public function test_location_is_incomplete_when_attribute_is_filled(): void { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } + $activity = new Activity(); - /** - * Sub element name empty narrative test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_name_empty_narrative(): void - { $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":""}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":null,"location_reach":[{"code":null}],"location_id":null,"name":[{"narrative":[{"narrative":null,"language":null}]}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"activity_description":[{"narrative":[{"narrative":null,"language":null}]}],"administrative":[{"vocabulary":null,"code":null,"level":null}],"point":[{"srs_name":null,"pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":null}],"location_class":[{"code":null}],"feature_designation":[{"code":null}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element name empty narrative array test. + * Test that 'location' is complete when an attribute is filled. * * @return void - * @throws \JsonException - */ - public function test_location_sub_element_name_empty_narrative_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element name empty narrative json array test. * - * @return void * @throws \JsonException */ - public function test_location_sub_element_name_empty_narrative_json_array(): void + public function test_location_is_complete_when_attribute_is_filled(): void { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } + $activity = new Activity(); - /** - * Sub element name sub element narrative empty narrative test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_name_sub_element_narrative_empty_narrative(): void - { $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":"this is reference text","location_reach":[{"code":null}],"location_id":null,"name":[{"narrative":[{"narrative":null,"language":null}]}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"activity_description":[{"narrative":[{"narrative":null,"language":null}]}],"administrative":[{"vocabulary":null,"code":null,"level":null}],"point":[{"srs_name":null,"pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":null}],"location_class":[{"code":null}],"feature_designation":[{"code":null}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element name sub element narrative no narrative key test. + * Test that 'location' is complete when any sub-element is filled - 1. * * @return void * @throws \JsonException */ - public function test_location_sub_element_name_sub_element_narrative_no_narrative_key(): void + public function test_location_is_complete_when_any_sub_element_is_filled_1(): void { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } + $activity = new Activity(); - /** - * Sub element description no key test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_no_description_key(): void - { $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http:\/\/www.opengis.net\/def\/crs\/EPSG\/0\/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":null,"location_reach":[{"code":"1"}],"location_id":null,"name":[{"narrative":[{"narrative":null,"language":null}]}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"activity_description":[{"narrative":[{"narrative":null,"language":null}]}],"administrative":[{"vocabulary":null,"code":null,"level":null}],"point":[{"srs_name":null,"pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":null}],"location_class":[{"code":null}],"feature_designation":[{"code":null}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element description empty test. + * Test that 'location' is complete when any sub-element is filled - 2. * * @return void - * @throws \JsonException - */ - public function test_location_sub_element_description_empty(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":"","activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element description empty array test. * - * @return void * @throws \JsonException */ - public function test_location_sub_element_description_empty_array(): void + public function test_location_is_complete_when_any_sub_element_is_filled_2(): void { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } + $activity = new Activity(); - /** - * Sub element description empty json array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_description_empty_json_array(): void - { $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":null,"location_reach":[{"code":null}],"location_id":[{"vocabulary": "A1", "code":"123"}],"name":[{"narrative":[{"narrative":null,"language":null}]}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"activity_description":[{"narrative":[{"narrative":null,"language":null}]}],"administrative":[{"vocabulary":null,"code":null,"level":null}],"point":[{"srs_name":null,"pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":null}],"location_class":[{"code":null}],"feature_designation":[{"code":null}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element description sub element narrative empty test. + * Test that 'location' is complete when any sub-element is filled - 3. * * @return void - * @throws \JsonException - */ - public function test_location_sub_element_description_empty_narrative(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":""}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element description sub element narrative empty array test. * - * @return void * @throws \JsonException */ - public function test_location_sub_element_description_empty_narrative_array(): void + public function test_location_is_complete_when_any_sub_element_is_filled_3(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":"","location_reach":[{"code":""}],"location_id":[{"vocabulary":"","code":""}],"name":[{"narrative":[{"narrative":"Place","language":"ng"}]}],"description":[{"narrative":[{"narrative":"","language":""}]}],"activity_description":[{"narrative":[{"narrative":"","language":""}]}],"administrative":[{"vocabulary":"","code":"","level":""}],"point":[{"srs_name":"","pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":""}],"location_class":[{"code":""}],"feature_designation":[{"code":""}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element description sub element narrative empty json array test. + * Test that 'location' is complete when any sub-element is filled - 4. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_description_empty_narrative_json_array(): void + public function test_location_is_complete_when_any_sub_element_is_filled_4(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref": null,"location_reach": [{"code": null}],"location_id": [{"vocabulary": null,"code": null}],"name": [{"narrative": [{"narrative": null,"language": null}]}],"description": [{"narrative": [{"narrative": "Description narr","language": "ng"}]}],"activity_description": [{"narrative": [{"narrative": null,"language": null}]}],"administrative": [{"vocabulary": null,"code": null,"level": null}],"point": [{"srs_name": null,"pos": [{"latitude": null,"longitude": null}]}],"exactness": [{"code": null}],"location_class": [{"code": null}],"feature_designation": [{"code": null}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element description sub element narrative empty narrative test. + * Test that 'location' is complete when any sub-element is filled - 5. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_description_sub_element_narrative_empty_narrative(): void + public function test_location_is_complete_when_any_sub_element_is_filled_5(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"","language":"en"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":"","location_reach":[{"code":""}],"location_id":[{"vocabulary":"","code":""}],"name":[{"narrative":[{"narrative":"","language":""}]}],"description":[{"narrative":[{"narrative":"","language":""}]}],"activity_description":[{"narrative":[{"narrative":"Act desc","language":"ng"}]}],"administrative":[{"vocabulary":"","code":"","level":""}],"point":[{"srs_name":"","pos":[{"latitude":0.0,"longitude":0.0}]}],"exactness":[{"code":""}],"location_class":[{"code":""}],"feature_designation":[{"code":""}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element description sub element narrative no narrative key test. + * Test that 'location' is complete when any sub-element is filled - 6. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_description_sub_element_narrative_no_narrative_key(): void + public function test_location_is_complete_when_any_sub_element_is_filled_6(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"language":"en"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":"","location_reach":[{"code":""}],"location_id":[{"vocabulary":"","code":""}],"name":[{"narrative":[{"narrative":"","language":""}]}],"description":[{"narrative":[{"narrative":"","language":""}]}],"activity_description":[{"narrative":[{"narrative":"","language":""}]}],"administrative":[{"vocabulary":"A1","code":"AF","level":""}],"point":[{"srs_name":"","pos":[{"latitude":0.0,"longitude":0.0}]}],"exactness":[{"code":""}],"location_class":[{"code":""}],"feature_designation":[{"code":""}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element description no key test. + * Test that 'location' is complete when any sub-element is filled - 7. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_no_activity_description_key(): void + public function test_location_is_complete_when_any_sub_element_is_filled_7(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":"","location_reach":[{"code":""}],"location_id":[{"vocabulary":"","code":""}],"name":[{"narrative":[{"narrative":"","language":""}]}],"description":[{"narrative":[{"narrative":"","language":""}]}],"activity_description":[{"narrative":[{"narrative":"","language":""}]}],"administrative":[{"vocabulary":"","code":"","level":""}],"point":[{"srs_name":"asd","pos":[{"latitude":84.2,"longitude":28.1}]}],"exactness":[{"code":""}],"location_class":[{"code":""}],"feature_designation":[{"code":""}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element activity_description empty test. + * Test that 'location' is complete when any sub-element is filled - 8. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_activity_description_empty(): void + public function test_location_is_complete_when_any_sub_element_is_filled_8(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":"","administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":"","location_reach":[{"code":""}],"location_id":[{"vocabulary":"","code":""}],"name":[{"narrative":[{"narrative":"","language":""}]}],"description":[{"narrative":[{"narrative":"","language":""}]}],"activity_description":[{"narrative":[{"narrative":"","language":""}]}],"administrative":[{"vocabulary":"","code":"","level":""}],"point":[{"srs_name":"","pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":"1"}],"location_class":[{"code":""}],"feature_designation":[{"code":""}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element activity_description empty array test. + * Test that 'location' is complete when any sub-element is filled - 9. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_activity_description_empty_array(): void + public function test_location_is_complete_when_any_sub_element_is_filled_9(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":"","location_reach":[{"code":""}],"location_id":[{"vocabulary":"","code":""}],"name":[{"narrative":[{"narrative":"","language":""}]}],"description":[{"narrative":[{"narrative":"","language":""}]}],"activity_description":[{"narrative":[{"narrative":"","language":""}]}],"administrative":[{"vocabulary":"","code":"","level":""}],"point":[{"srs_name":"","pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":""}],"location_class":[{"code":"1"}],"feature_designation":[{"code":""}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element activity_description empty json array test. + * Test that 'location' is complete when any sub-element is filled - 10. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_activity_description_empty_json_array(): void + public function test_location_is_complete_when_any_sub_element_is_filled_10(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":null,"location_reach":[{"code":null}],"location_id":[{"vocabulary":null,"code":null}],"name":[{"narrative":[{"narrative":null,"language":null}]}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"activity_description":[{"narrative":[{"narrative":null,"language":null}]}],"administrative":[{"vocabulary":null,"code":null,"level":null}],"point":[{"srs_name":null,"pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":null}],"location_class":[{"code":null}],"feature_designation":[{"code":"AIRQ"}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element activity_description sub element narrative empty test. + * Test location is incomplete when one of many location instance is incomplete. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_activity_description_empty_narrative(): void + public function test_multiple_location_is_incomplete_when_one_is_incomplete(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":""}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":null,"location_reach":[{"code":null}],"location_id":[{"vocabulary":null,"code":null}],"name":[{"narrative":[{"narrative":null,"language":null}]}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"activity_description":[{"narrative":[{"narrative":null,"language":null}]}],"administrative":[{"vocabulary":null,"code":null,"level":null}],"point":[{"srs_name":null,"pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":null}],"location_class":[{"code":null}],"feature_designation":[{"code":"AIRQ"}]}, {"ref":null,"location_reach":[{"code":null}],"location_id":[{"vocabulary":null,"code":null}],"name":[{"narrative":[{"narrative":null,"language":null}]}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"activity_description":[{"narrative":[{"narrative":null,"language":null}]}],"administrative":[{"vocabulary":null,"code":null,"level":null}],"point":[{"srs_name":null,"pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":null}],"location_class":[{"code":null}],"feature_designation":[{"code":null}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element activity_description sub element narrative empty array test. + * Test location is complete when all of the location instances are incomplete. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_activity_description_empty_narrative_array(): void + public function test_multiple_location_is_complete_when_all_are_complete(): void { + $activity = new Activity(); + $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', + '[{"ref":null,"location_reach":[{"code":null}],"location_id":[{"vocabulary":null,"code":null}],"name":[{"narrative":[{"narrative":null,"language":null}]}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"activity_description":[{"narrative":[{"narrative":null,"language":null}]}],"administrative":[{"vocabulary":null,"code":null,"level":null}],"point":[{"srs_name":null,"pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":null}],"location_class":[{"code":null}],"feature_designation":[{"code":"AIRQ"}]}, {"ref":null,"location_reach":[{"code":null}],"location_id":[{"vocabulary":null,"code":null}],"name":[{"narrative":[{"narrative":null,"language":null}]}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"activity_description":[{"narrative":[{"narrative":null,"language":null}]}],"administrative":[{"vocabulary":null,"code":null,"level":null}],"point":[{"srs_name":null,"pos":[{"latitude":null,"longitude":null}]}],"exactness":[{"code":null}],"location_class":[{"code":null}],"feature_designation":[{"code":"AIRQ"}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity->location = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isLocationElementCompleted($activity)); } /** - * Sub element activity_description sub element narrative empty json array test. + * Test location is incomplete when null. * * @return void + * * @throws \JsonException */ - public function test_location_sub_element_activity_description_empty_narrative_json_array(): void + public function test_contact_info_is_incomplete_when_contact_info_element_is_missing() { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element activity_description sub element narrative empty narrative test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_activity_description_sub_element_narrative_empty_narrative(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element activity_description sub element narrative no narrative key test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_activity_description_sub_element_narrative_no_narrative_key(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point no key test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_no_point_key(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point empty test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_empty(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":"","exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point empty array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_empty_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point empty json array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_empty_json_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point attribute srs_name empty test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_empty_attribute_srs_name(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point sub_element pos no key test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_sub_element_no_pos_key(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326"}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point sub_element pos empty test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_sub_element_pos_empty(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":""}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point sub_element pos empty array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_sub_element_pos_empty_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point sub_element pos empty json array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_sub_element_pos_empty_json_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point sub_element pos no latitude test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_sub_element_pos_attribute_no_latitude_key(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"longitude":"27"}] }],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element point sub_element pos empty latitude test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_point_sub_element_pos_attribute_empty_latitude(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"","longitude":"27"}] }],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element location_class empty test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_location_class_empty(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":""}]}],"exactness":[{"code":"1"}],"location_class":"","feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element location_class no key test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_no_location_class_key(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element location_class empty array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_location_class_empty_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element location_class empty json array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_location_class_empty_json_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element location_class attribute code empty test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_location_class_attribute_code_empty(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":""}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element location_class attribute code empty test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_feature_designation_empty(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":""}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element feature_designation no key test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_no_feature_designation_key(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element feature_designation empty array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_feature_designation_empty_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element feature_designation empty json array test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_feature_designation_empty_json_array(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element feature_designation attribute code empty test. - * - * @return void - * @throws \JsonException - */ - public function test_location_sub_element_feature_designation_attribute_code_empty(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":""}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Location element complete test. - * - * @return void - * @throws \JsonException - */ - public function test_location_element_complete(): void - { - $actualData = json_decode( - '[{"ref":"ref 1","location_reach":[{"code":"1"}],"location_id":[{"vocabulary":"A2","code":"vocab code"}],"name":[{"narrative":[{"narrative":"name 1","language":"aa"}]}],"description":[{"narrative":[{"narrative":"description 1","language":"aa"}]}],"activity_description":[{"narrative":[{"narrative":"activity description 1","language":"ab"}]}],"administrative":[{"vocabulary":"A2","code":"DZ","level":"1236"}],"point":[{"srs_name":"http://www.opengis.net/def/crs/EPSG/0/4326","pos":[{"latitude":"56","longitude":"27"}]}],"exactness":[{"code":"1"}],"location_class":[{"code":"2"}],"feature_designation":[{"code":"CMPQ"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $activity = new Activity(); + $activity->location = null; - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isContactInfoElementCompleted($activity)); } } diff --git a/tests/Feature/Element/PlannedDisbursementTest.php b/tests/Feature/Element/PlannedDisbursementTest.php index 242d3bb3dc..db524ac85a 100644 --- a/tests/Feature/Element/PlannedDisbursementTest.php +++ b/tests/Feature/Element/PlannedDisbursementTest.php @@ -4,11 +4,17 @@ namespace Tests\Feature\Element; +use App\IATI\Models\Activity\Activity; +use Illuminate\Support\Arr; +use Tests\Traits\FilterMandatoryItemsTrait; + /** * Class PlannedDisbursementTest. */ class PlannedDisbursementTest extends ElementCompleteTest { + use FilterMandatoryItemsTrait; + /** * Element planned_disbursement. * @@ -16,6 +22,21 @@ class PlannedDisbursementTest extends ElementCompleteTest */ private string $element = 'planned_disbursement'; + /** + * @var array|string[] + */ + private array $mandatorySubelements = [ + 'sub_elements.period_start.attributes.date.criteria' => 'mandatory', + 'sub_elements.value.attributes.amount.criteria' => 'mandatory', + 'sub_elements.value.attributes.currency.criteria' => 'mandatory', + 'sub_elements.value.attributes.value_date.criteria' => 'mandatory', + ]; + + /** + * @var array|string[] + */ + private array $mandatoryAttributes = []; + /** * Mandatory attribute test. * @@ -24,7 +45,17 @@ class PlannedDisbursementTest extends ElementCompleteTest */ public function test_humanitarian_scope_mandatory_attributes(): void { - $this->test_mandatory_attributes($this->element, []); + $countryBudgetItemSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $countryBudgetItemFlattened = flattenArrayWithKeys($countryBudgetItemSchema); + $countryBudgetItemFlattened = getItemsWhereKeyContains($countryBudgetItemFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $countryBudgetItemFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatorySubelements($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatoryAttributes); } /** @@ -35,7 +66,27 @@ public function test_humanitarian_scope_mandatory_attributes(): void */ public function test_humanitarian_scope_mandatory_sub_elements(): void { - $this->test_mandatory_sub_elements($this->element, ['period_start' => ['date'], 'period_end' => ['date'], 'value' => ['amount', 'currency', 'value_date']]); + $countryBudgetItemSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $countryBudgetItemFlattened = flattenArrayWithKeys($countryBudgetItemSchema); + $countryBudgetItemFlattened = getItemsWhereKeyContains($countryBudgetItemFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $countryBudgetItemFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatoryAttributes($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatorySubelements); + } + + public function test_planned_disbursement_null_value(): void + { + $actualData = null; + $activity = new Activity(); + + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** @@ -44,11 +95,14 @@ public function test_humanitarian_scope_mandatory_sub_elements(): void * @return void * @throws \JsonException */ - public function test_planned_disbursement_empty_data(): void + public function test_planned_disbursement_empty_string(): void { $actualData = ''; + $activity = new Activity(); + + $activity->{$this->element} = $actualData; - $this->test_level_one_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** @@ -59,9 +113,11 @@ public function test_planned_disbursement_empty_data(): void */ public function test_planned_disbursement_empty_array(): void { - $actualData = json_decode('[]', true); + $actualData = []; + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_one_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** @@ -72,386 +128,414 @@ public function test_planned_disbursement_empty_array(): void */ public function test_planned_disbursement_empty_json_array(): void { - $actualData = json_decode('[{}]', true); + $actualData = json_decode('[{}]'); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element period_start no key test. + * Test incomplete when mandatory subelements are null. * * @return void - * @throws \JsonException - */ - public function test_planned_disbursement_sub_element_no_period_start_key(): void - { - $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_end":[{"date":"2022-07-27"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element period_end no key test. * - * @return void * @throws \JsonException */ - public function test_planned_disbursement_sub_element_no_period_end_key(): void + public function test_planned_disbursement_incomplete_when_mandatory_subelement_keys_are_null(): void { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":null,"period_end":[{"date":"2022-07-27"}],"value":null,"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element value no key test. + * Test incomplete when mandatory subelements are empty array. * * @return void - * @throws \JsonException - */ - public function test_planned_disbursement_sub_element_no_value_key(): void - { - $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); - - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); - } - - /** - * Sub element receiver_org no key test. * - * @return void * @throws \JsonException */ - public function test_planned_disbursement_sub_element_no_receiver_org_key(): void + public function test_planned_disbursement_incomplete_when_mandatory_subelement_keys_are_empty_array(): void { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[],"period_end":[{"date":"2022-07-27"}],"value":[],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * All element empty test. + * Test incomplete when mandatory subelements are null. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_all_element_empty(): void + public function test_planned_disbursement_incomplete_when_mandatory_subelement_keys_are_null_values(): void { $actualData = json_decode( - '[{"planned_disbursement_type":"","period_start":[{"date":""}],"period_end":[{"date":""}],"value":[{"amount":"","currency":"","value_date":""}],"provider_org":[{"ref":"","provider_activity_id":"","type":"","narrative":[{"narrative":"","language":"ab"}]}],"receiver_org":[{"ref":"","provider_activity_id":"","type":"","narrative":[{"narrative":"","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":null}],"period_end":[{"date":"2022-07-27"}],"value":[{"amount":null,"currency":null,"value_date":null}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element period_start empty test. + * Test incomplete when mandatory subelements are missing. * * @return void * @throws \JsonException */ - public function test_planned_disbursement_sub_element_empty_period_start(): void + public function test_planned_disbursement_incomplete_when_mandatory_subelement_keys_are_missing(): void { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":"","period_end":[{"date":"2022-07-27"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_end":[{"date":"2022-07-27"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element period_start empty arary test. + * Sub element period_start key missing test. * * @return void * @throws \JsonException */ - public function test_planned_disbursement_sub_element_empty_period_start_array(): void + public function test_planned_disbursement_incomplete_when_period_start_key_is_missing(): void { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[],"period_end":[{"date":"2022-07-27"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_end":[{"date":"2022-07-27"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element period_start empty json array test. + * Sub element period_end key missing test. * * @return void * @throws \JsonException */ - public function test_planned_disbursement_sub_element_empty_period_start_json_array(): void + public function test_planned_disbursement_complete_even_when_period_end_key_is_missing(): void { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{}],"period_end":[{"date":"2022-07-27"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element period_start empty date test. + * Sub element period_end key missing test. * * @return void * @throws \JsonException */ - public function test_planned_disbursement_sub_element_period_start_attribute_empty_date(): void + public function test_planned_disbursement_incomplete_when_value_key_is_missing(): void { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":""}],"period_end":[{"date":"2022-07-27"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element period_end empty test. + * Sub element provider_org key missing test. * * @return void * @throws \JsonException */ - public function test_planned_disbursement_sub_element_empty_period_end(): void + public function test_planned_disbursement_complete_even_when_provider_org_key_is_missing(): void { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-27"}],"period_end":"","value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $this->assertTrue($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element period_end empty array test. + * Sub element receiver_org key missing test. * * @return void * @throws \JsonException */ - public function test_planned_disbursement_sub_element_empty_period_end_array(): void + public function test_planned_disbursement_complete_even_when_receiver_org_key_is_missing(): void { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-27"}],"period_end":[],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element period_end empty json array test. + * Test incomplete for value amount value is null. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_sub_element_empty_period_end_json_array(): void + public function test_planned_disbursement_is_incomplete_when_value_amount_is_null() { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-27"}],"period_end":[{}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":null,"currency":"AED","value_date":"2024-11-12"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element period_end empty date test. + * Test incomplete for value amount value is empty string. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_sub_element_period_end_attribute_empty_date(): void + public function test_planned_disbursement_is_incomplete_when_value_amount_is_empty_string() { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-27"}],"period_end":[{"date":""}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"","currency":"AED","value_date":"2024-11-12"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element value empty test. + * Test complete for value currency value is zero. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_sub_element_empty_value(): void + public function test_planned_disbursement_is_complete_when_value_amount_is_zero() { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"value":"","provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"0","currency":"AED","value_date":"2024-11-12"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element value empty array test. + * Test incomplete for value currency value null. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_sub_element_empty_value_array(): void + public function test_planned_disbursement_is_incomplete_when_value_currency_is_null() { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"value":[],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"12345","currency":null,"value_date":"2024-11-12"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element value empty json array test. + * Test incomplete for value currency value is empty string. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_sub_element_empty_value_json_array(): void + public function test_planned_disbursement_is_incomplete_when_value_currency_is_empty_string() { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"value":[{}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"12345","currency":"","value_date":"2024-11-12"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element value attributes empty test. + * Test incomplete for value date value null. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_sub_element_value_attribute_empty_amount_and_currency_and_value_date(): void + public function test_planned_disbursement_is_incomplete_when_value_value_date_is_null() { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"value":[{"amount":"","currency":"","value_date":""}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"12345","currency":"AED","value_date":null}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element value attribute amount empty test. + * Test incomplete for value date value empty string. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_sub_element_value_attribute_empty_amount(): void + public function test_planned_disbursement_is_incomplete_when_value_value_date_is_empty_string() { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"value":[{"amount":"","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"12345","currency":"AED","value_date":""}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element value attribute currency empty test. + * Test incomplete for single. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_sub_element_value_attribute_empty_currency(): void + public function test_planned_disbursement_is_complete_when_all_fields_are_filled() { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"value":[{"amount":"1111","currency":"","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"12345","currency":"AED","value_date":"2024-12-13"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Sub element value attribute value_date empty test. + * Test complete for multiple. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_sub_element_value_attribute_empty_value_date(): void + public function test_planned_disbursement_is_complete_when_all_fields_for_multiple_disbursement_are_filled() { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"value":[{"amount":"1111","currency":"AOA","value_date":""}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"12345","currency":"AED","value_date":"2024-12-13"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]},{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"12345","currency":"AED","value_date":"2024-12-13"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_incomplete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } /** - * Planned Disbursement element complete test. + * Test incomplete for multiple. * * @return void + * * @throws \JsonException */ - public function test_planned_disbursement_element_complete(): void - { + public function test_planned_disbursement_is_incomplete_when_some_required_fields_are_not_field_for_multiple_disbursement( + ) { $actualData = json_decode( - '[{"planned_disbursement_type":"1","period_start":[{"date":"2022-07-19"}],"period_end":[{"date":"2022-07-27"}],"value":[{"amount":"1111","currency":"AOA","value_date":"2022-07-30"}],"provider_org":[{"ref":"provider-org-ref","provider_activity_id":"123123123","type":"11","narrative":[{"narrative":"asdasdasdads","language":"ab"}]}],"receiver_org":[{"ref":"receiver-org-ref","provider_activity_id":"5555","type":"23","narrative":[{"narrative":"asdasdadasdasd","language":"af"}]}]}]', + '[{"planned_disbursement_type":"1","period_start":[{"date":null}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"12345","currency":"AED","value_date":"2024-12-13"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]},{"planned_disbursement_type":"1","period_start":[{"date":"2023-11-12"}],"period_end":[{"date":"2023-11-13"}],"value":[{"amount":"12345","currency":"AED","value_date":"2024-12-13"}],"provider_org":[{"ref":"provider ref val","provider_activity_id":"provider-activity-123","type":"10","narrative":[{"narrative":"narr","language":"ng"}]}],"receiver_org":[{"ref":"receiver ref val","receiver_activity_id":"receiver-activity-123","type":"21","narrative":[{"narrative":"narr","language":"ng"}]}]}]', true, 512, JSON_THROW_ON_ERROR ); - $this->test_level_two_multi_dimensional_element_complete($this->element, $actualData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPlannedDisbursementElementCompleted($activity)); } } diff --git a/tests/Feature/Element/PolicyMarkerCompleteTest.php b/tests/Feature/Element/PolicyMarkerCompleteTest.php index a43c88175c..52cc5ee230 100644 --- a/tests/Feature/Element/PolicyMarkerCompleteTest.php +++ b/tests/Feature/Element/PolicyMarkerCompleteTest.php @@ -4,55 +4,418 @@ namespace Tests\Feature\Element; +use App\IATI\Models\Activity\Activity; +use Illuminate\Support\Arr; +use Tests\Traits\FilterMandatoryItemsTrait; + /** - * Class PolicyMarkerCompleteTest. + * @class PolicyMarkerCompleteTest. */ class PolicyMarkerCompleteTest extends ElementCompleteTest { + use FilterMandatoryItemsTrait; + + protected array $mandatorySubelements = []; + + protected array $mandatoryAttributes = [ + 'attributes.policy_marker.criteria' => 'mandatory', + 'attributes.policy_marker_text.criteria' => 'mandatory', + ]; + /** - * Element policy_marker. + * Mandatory attributes have not changed. * * @var string */ private string $element = 'policy_marker'; + public function test_policy_marker_mandatory_attributes_have_not_changed(): void + { + $policyMarkerSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $policyMarkerFlattened = flattenArrayWithKeys($policyMarkerSchema); + $policyMarkerFlattened = getItemsWhereKeyContains($policyMarkerFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $policyMarkerFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatorySubelements($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatoryAttributes); + } + + /** + * Mandatory subelements have not changed. + * + * @return void + * + * @throws \JsonException + */ + public function test_policy_marker_subelements_have_not_changed(): void + { + $policyMarkerSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $policyMarkerFlattened = flattenArrayWithKeys($policyMarkerSchema); + $policyMarkerFlattened = getItemsWhereKeyContains($policyMarkerFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $policyMarkerFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatoryAttributes($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatorySubelements); + } + + /** + * Test incomplete when null. + * + * @return void + * + * @throws \JsonException + */ + public function test_policy_marker_is_not_complete_when_null(): void + { + $actualData = null; + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test incomplete when empty string. + * + * @return void + * + * @throws \JsonException + */ + public function test_policy_marker_is_not_complete_when_empty_string(): void + { + $actualData = ''; + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + /** - * Mandatory attribute test. + * Test incomplete when empty array. * * @return void + * * @throws \JsonException */ - public function test_policy_marker_type_mandatory_attributes(): void + public function test_policy_marker_is_not_complete_when_empty_data(): void { - $this->test_mandatory_attributes($this->element, ['policy_marker', 'policy_marker_text']); + $actualData = []; + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); } /** - * Mandatory sub element test. + * Test incomplete when empty json array. * * @return void + * * @throws \JsonException */ - public function test_policy_marker_mandatory_sub_elements(): void + public function test_policy_marker_is_not_complete_when_empty_json_array(): void { - $this->test_mandatory_sub_elements($this->element, []); + $actualData = json_decode('[{}]'); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); } /** - * Polic Marker element complete test. + * Test incomplete when policy_marker key is missing. * * @return void * @throws \JsonException */ - public function test_policy_marker_element_complete(): void + public function test_policy_marker_is_incomplete_when_not_custom_vocab_and_policy_marker_code_is_missing() { - $sector_typeData = json_decode( - '[{"policy_marker_vocabulary":"1","significance":"1","policy_marker":"1","narrative":[{"narrative":"policy-marker-1-narrative1","language":"aa"}]},{"policy_marker_vocabulary":"99","vocabulary_uri":"https:\/\/google.com","significance":"2","policy_marker_text":"vocab-99","narrative":[{"narrative":"policy-marker-99-narrative1","language":"ak"}]}]', - true, - 512, - JSON_THROW_ON_ERROR + $actualData = json_decode( + '[{"policy_marker_vocabulary":"1","significance":"2","narrative":[{"narrative":"Narr onea","language":"ng"}]}]', + true ); - $this->test_level_one_multi_dimensional_element_complete($this->element, $sector_typeData); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test incomplete when policy_marker value is null. + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_incomplete_when_not_custom_vocab_and_policy_marker_code_is_null() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"1","significance":"2","policy_marker":null,"narrative":[{"narrative":"Narr onea","language":"ng"}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test incomplete when policy_marker value is empty string. + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_incomplete_when_not_custom_vocab_and_policy_marker_code_is_empty_string() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"1","significance":"2","policy_marker":"","narrative":[{"narrative":"Narr onea","language":"ng"}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test complete when policy_marker value is 0. + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_complete_when_not_custom_vocab_and_policy_marker_code_is_zero() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"1","significance":"2","policy_marker":"0","narrative":[{"narrative":"Narr onea","language":"ng"}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test complete when only policy_marker is filled (single). + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_complete_when_only_policy_marker_code_is_filled() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"1","significance":null,"policy_marker":"2","narrative":[{"narrative":null,"language":null}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test complete when only policy_marker is filled (multiple). + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_complete_when_only_policy_marker_code_is_filled_multiple() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"1","significance":null,"policy_marker":"2","narrative":[{"narrative":null,"language":null}]}, {"policy_marker_vocabulary":"1","significance":null,"policy_marker":"1","narrative":[{"narrative":null,"language":null}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test complete when only custom vocab policy_marker_text is filled (multiple). + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_complete_when_only_custom_vocab_policy_marker_text_is_filled_multiple() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":null,"vocabulary_uri":null,"significance":null,"policy_marker_text":"text 1","narrative":[{"narrative":null,"language":null}]},{"policy_marker_vocabulary":null,"vocabulary_uri":null,"significance":null,"policy_marker_text":"text 2","narrative":[{"narrative":null,"language":null}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test complete when only custom vocab policy_marker_text is filled (single). + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_complete_when_only_custom_vocab_policy_marker_text_is_filled() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":null,"vocabulary_uri":null,"significance":null,"policy_marker_text":"text 1","narrative":[{"narrative":null,"language":null}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test incomplete when policy_marker_text key is missing in custom vocab case. + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_incomplete_when_custom_vocab_and_policy_marker_text_is_missing() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"99","vocabulary_uri":"https://github.com/younginnovations/iatipublisher","significance":"2","narrative":[{"narrative":"Narr one","language":"ng"}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test incomplete when policy_marker_text value is null in custom vocab case. + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_incomplete_when_custom_vocab_and_policy_marker_text_is_null() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"99","vocabulary_uri":"https://github.com/younginnovations/iatipublisher","significance":"2","policy_marker_text":null,"narrative":[{"narrative":"Narr one","language":"ng"}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test incomplete when policy_marker_text value is empty string in custom vocab case. + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_incomplete_when_custom_vocab_and_policy_marker_text_is_empty_string() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"99","vocabulary_uri":"https://github.com/younginnovations/iatipublisher","significance":"2","policy_marker_text":"","narrative":[{"narrative":"Narr one","language":"ng"}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test complete when policy_marker_text value is 0 in custom vocab case. + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_complete_when_custom_vocab_and_policy_marker_text_is_zero() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"99","vocabulary_uri":"https://github.com/younginnovations/iatipublisher","significance":"2","policy_marker_text":"0","narrative":[{"narrative":"Narr one","language":"ng"}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test complete when everything is filled. + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_complete_when_custom_vocab_and_all_filled() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"99","vocabulary_uri":"https://github.com/younginnovations/iatipublisher","significance":"2","policy_marker_text":"12345","narrative":[{"narrative":"Narr one","language":"ng"}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test complete when everything is filled (multiple). + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_complete_when_all_filled_multiple() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"99","vocabulary_uri":"https://github.com/younginnovations/iatipublisher","significance":"2","policy_marker_text":"12345","narrative":[{"narrative":"Narr one","language":"ng"}]},{"policy_marker_vocabulary":"1","significance":"2","policy_marker":"1","narrative":[{"narrative":"Another narr","language":"ng"}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); + } + + /** + * Test complete when only required fields are filled (multiple). + * + * @return void + * @throws \JsonException + */ + public function test_policy_marker_is_complete_when_only_required_filled_multiple() + { + $actualData = json_decode( + '[{"policy_marker_vocabulary":"1","significance":null,"policy_marker":"1","narrative":[{"narrative":null,"language":null}]},{"policy_marker_vocabulary":"99","vocabulary_uri":null,"significance":null,"policy_marker_text":"Code 1","narrative":[{"narrative":"Nar required","language":"ng"}]},{"policy_marker_vocabulary":"1","significance":null,"policy_marker":"2","narrative":[{"narrative":null,"language":null}]}]', + true + ); + + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isPolicyMarkerElementCompleted($activity)); } } diff --git a/tests/Feature/Element/SectorCompleteTest.php b/tests/Feature/Element/SectorCompleteTest.php index e089c38d33..5a8332abdb 100644 --- a/tests/Feature/Element/SectorCompleteTest.php +++ b/tests/Feature/Element/SectorCompleteTest.php @@ -4,11 +4,17 @@ namespace Tests\Feature\Element; +use App\IATI\Models\Activity\Activity; +use Illuminate\Support\Arr; +use Tests\Traits\FilterMandatoryItemsTrait; + /** * Class SectorCompleteTest. */ class SectorCompleteTest extends ElementCompleteTest { + use FilterMandatoryItemsTrait; + /** * Element sector. * @@ -16,6 +22,22 @@ class SectorCompleteTest extends ElementCompleteTest */ private string $element = 'sector'; + /** + * @var array|string[] + */ + private array $mandatoryAttributes = [ + 'attributes.code.criteria' => 'mandatory', + 'attributes.text.criteria' => 'mandatory', + 'attributes.category_code.criteria' => 'mandatory', + 'attributes.sdg_goal.criteria' => 'mandatory', + 'attributes.sdg_target.criteria' => 'mandatory', + ]; + + /** + * @var array + */ + private array $mandatorySubelements = []; + /** * Mandatory attribute test. * @@ -24,53 +46,982 @@ class SectorCompleteTest extends ElementCompleteTest */ public function test_sector_type_mandatory_attributes(): void { - $this->test_mandatory_attributes($this->element, ['code', 'text', 'category_code', 'sdg_goal', 'sdg_target']); + $sectorSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $sectorFlattened = flattenArrayWithKeys($sectorSchema); + $sectorFlattened = getItemsWhereKeyContains($sectorFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $sectorFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatorySubelements($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatoryAttributes); } /** - * Mandatory sub element test. + * Test for ensuring mandatory subelements have not changed since the time of writing this test. * * @return void + * + * @throws \JsonException + */ + public function test_sector_subelements_have_not_changed(): void + { + $sectorSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $sectorFlattened = flattenArrayWithKeys($sectorSchema); + $sectorFlattened = getItemsWhereKeyContains($sectorFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $sectorFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatoryAttributes($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatorySubelements); + } + + /** + * Test incomplete when null. + * * @throws \JsonException */ - public function test_sector_type_mandatory_sub_elements(): void + public function test_incomplete_when_null() { - $this->test_mandatory_sub_elements($this->element, []); + $actualData = null; + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); } /** - * Sector element complete with all filled. + * Test incomplete when null. * - * @return void * @throws \JsonException */ - public function test_sector_type_element_complete(): void + public function test_incomplete_when_empty_string() { - $sector_typeData = json_decode( - '[{"sector_vocabulary":"1","code":"11110","percentage":"100","narrative":[{"narrative":"sector-1-narrative1","language":"aa"}]},{"sector_vocabulary":"2","category_code":"111","percentage":"100","narrative":[{"narrative":"sector-2-narrative1","language":"ab"}]},{"sector_vocabulary":"3","text":"vocab-3","percentage":"100","narrative":[{"narrative":"sector-3-narrative1","language":"am"}]},{"sector_vocabulary":"4","text":"vocab-4","percentage":"100","narrative":[{"narrative":"sector-4-narrative1","language":"ba"}]},{"sector_vocabulary":"5","text":"vocab-5","percentage":"100","narrative":[{"narrative":"sector-5-narrative1","language":"bn"}]},{"sector_vocabulary":"6","text":"vocab-6","percentage":"100","narrative":[{"narrative":null,"language":"en"}]},{"sector_vocabulary":"7","sdg_goal":"1","percentage":"100","narrative":[{"narrative":null,"language":"fr"}]},{"sector_vocabulary":"8","sdg_target":"1.1","percentage":"100","narrative":[{"narrative":null,"language":"gr"}]},{"sector_vocabulary":"9","text":"vocab-9","percentage":"100","narrative":[{"narrative":null,"language":"sp"}]},{"sector_vocabulary":"10","text":"vocab-10","percentage":"100","narrative":[{"narrative":null,"language":"hr"}]},{"sector_vocabulary":"99","vocabulary_uri":"https:\/\/www.google.com","text":"vocab-99","percentage":"100","narrative":[{"narrative":null,"language":"aa"}]}]', - true, - 512, - JSON_THROW_ON_ERROR - ); + $actualData = ''; + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_one_multi_dimensional_element_complete($this->element, $sector_typeData); + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); } /** - * Sector element complete test for 'text' attribute. + * Test incomplete when null. * - * @return void * @throws \JsonException */ - public function test_sector_type_element_complete_with_empty_vocabulary_and_field_is_condisdered_text(): void + public function test_incomplete_when_empty_array() + { + $actualData = []; + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + /** + * Test incomplete when null. + * + * @throws \JsonException + */ + public function test_incomplete_when_empty_json_array() + { + $actualData = json_decode('[{}]', true); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_null() + { + $actualData = json_decode( + '[{"sector_vocabulary":null,"text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_null() + { + $actualData = json_decode( + '[{"sector_vocabulary":null,"text":"112","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_1() + { + $actualData = json_decode( + '[{"sector_vocabulary":"1","code":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_2() + { + $actualData = json_decode( + '[{"sector_vocabulary":"2","category_code":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_3() + { + $actualData = json_decode( + '[{"sector_vocabulary":"3","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_4() + { + $actualData = json_decode( + '[{"sector_vocabulary":"4","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_5() + { + $actualData = json_decode( + '[{"sector_vocabulary":"5","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_6() + { + $actualData = json_decode( + '[{"sector_vocabulary":"6","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_7() + { + $actualData = json_decode( + '[{"sector_vocabulary":"7","sdg_goal":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_8() + { + $actualData = json_decode( + '[{"sector_vocabulary":"8","sdg_target":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_9() + { + $actualData = json_decode( + '[{"sector_vocabulary":"9","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_10() + { + $actualData = json_decode( + '[{"sector_vocabulary":"10","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_11() + { + $actualData = json_decode( + '[{"sector_vocabulary":"11","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_12() + { + $actualData = json_decode( + '[{"sector_vocabulary":"12","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_99() + { + $actualData = json_decode( + '[{"sector_vocabulary":"99","vocabulary_uri":null,"text":null,"percentage":null,"narrative":[{"narrative":"Narrative required","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_98() + { + $actualData = json_decode( + '[{"sector_vocabulary":"98","vocabulary_uri":null,"text":null,"percentage":null,"narrative":[{"narrative":"Narrative required","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_1_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"1","code":"11110","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"1","code":"11120","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_2_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"2","category_code":"111","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"2","category_code":"112","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_3_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"3","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"3","text":"1234","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_4_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"4","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"4","text":"1234","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_5_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"5","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"5","text":"1234","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_6_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"6","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"6","text":"1234","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_7_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"7","sdg_goal":"1","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"7","sdg_goal":"2","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_8_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"8","sdg_target":"1.1","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"8","sdg_target":"1.2","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_9_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"9","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"9","text":"1234","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_10_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"10","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"10","text":"1234","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_11_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"11","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"11","text":"1234","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_12_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"12","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"12","text":"1234","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_99_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"99","vocabulary_uri":null,"text":"123","percentage":null,"narrative":[{"narrative":"required narr 1","language":"ne"}]},{"sector_vocabulary":"99","vocabulary_uri":null,"text":"1234","percentage":null,"narrative":[{"narrative":"required narr 2","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_98_multiple_when_only_code_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"98","vocabulary_uri":null,"text":"123","percentage":null,"narrative":[{"narrative":"Narrative required","language":"ne"}]},{"sector_vocabulary":"98","vocabulary_uri":null,"text":"1234","percentage":null,"narrative":[{"narrative":"Narrative required","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_1_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"1","code":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}, {"sector_vocabulary":"1","code":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_2_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"2","category_code":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"2","category_code":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_3_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"3","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"3","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_4_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"4","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"4","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_5_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"5","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"5","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_6_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"6","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"6","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_7_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"7","sdg_goal":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"7","sdg_goal":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_8_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"8","sdg_target":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"8","sdg_target":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_9_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"9","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"9","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_10_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"10","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"10","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_11_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"11","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"11","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_12_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"12","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"12","text":null,"percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_99_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"99","vocabulary_uri":null,"text":null,"percentage":"50","narrative":[{"narrative":"Narrative required","language":"ne"}]},{"sector_vocabulary":"99","vocabulary_uri":null,"text":null,"percentage":"50","narrative":[{"narrative":"Narrative required","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_sector_vocab_98_multiple_when_only_percentage_is_filled() + { + $actualData = json_decode( + '[{"sector_vocabulary":"98","vocabulary_uri":null,"text":null,"percentage":"50","narrative":[{"narrative":"Narrative required","language":"ne"}]},{"sector_vocabulary":"98","vocabulary_uri":null,"text":null,"percentage":"50","narrative":[{"narrative":"Narrative required","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_1() + { + $actualData = json_decode( + '[{"sector_vocabulary":"1","code":"11110","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_2() + { + $actualData = json_decode( + '[{"sector_vocabulary":"2","category_code":"111","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_3() + { + $actualData = json_decode( + '[{"sector_vocabulary":"3","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_4() + { + $actualData = json_decode( + '[{"sector_vocabulary":"4","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_5() + { + $actualData = json_decode( + '[{"sector_vocabulary":"5","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_6() + { + $actualData = json_decode( + '[{"sector_vocabulary":"6","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_7() + { + $actualData = json_decode( + '[{"sector_vocabulary":"7","sdg_goal":"1","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_8() + { + $actualData = json_decode( + '[{"sector_vocabulary":"8","sdg_target":"1.1","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_9() + { + $actualData = json_decode( + '[{"sector_vocabulary":"9","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_10() + { + $actualData = json_decode( + '[{"sector_vocabulary":"10","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_11() + { + $actualData = json_decode( + '[{"sector_vocabulary":"11","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_12() + { + $actualData = json_decode( + '[{"sector_vocabulary":"12","text":"123","percentage":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_99() + { + $actualData = json_decode( + '[{"sector_vocabulary":"99","vocabulary_uri":null,"text":"123","percentage":null,"narrative":[{"narrative":"Narrative required","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_98() + { + $actualData = json_decode( + '[{"sector_vocabulary":"98","vocabulary_uri":null,"text":"123","percentage":null,"narrative":[{"narrative":"Narrative required","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_1_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"1","code":"11110","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"1","code":"11120","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_2_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"2","category_code":"111","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"2","category_code":"112","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_3_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"3","text":"123","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"3","text":"1234","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_4_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"4","text":"123","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"4","text":"1234","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_5_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"5","text":"123","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"5","text":"1234","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_6_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"6","text":"123","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"6","text":"1234","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_7_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"7","sdg_goal":"1","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"7","sdg_goal":"2","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_8_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"8","sdg_target":"1.1","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"8","sdg_target":"1.2","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_9_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"9","text":"123","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"9","text":"1234","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_10_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"10","text":"123","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"10","text":"1234","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_11_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"11","text":"123","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"11","text":"1234","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_12_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"12","text":"123","percentage":"50","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"12","text":"1234","percentage":"50","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_99_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"99","vocabulary_uri":null,"text":"123","percentage":"50","narrative":[{"narrative":"required narr 1","language":"ne"}]},{"sector_vocabulary":"99","vocabulary_uri":null,"text":"1234","percentage":"50","narrative":[{"narrative":"required narr 2","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_sector_vocab_98_multiple() + { + $actualData = json_decode( + '[{"sector_vocabulary":"98","vocabulary_uri":null,"text":"123","percentage":"50","narrative":[{"narrative":"Narrative required","language":"ne"}]},{"sector_vocabulary":"98","vocabulary_uri":null,"text":"1234","percentage":"50","narrative":[{"narrative":"Narrative required","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_incomplete_for_mix_all() + { + $actualData = json_decode( + '[{"sector_vocabulary":"1","code":null,"percentage":"50","narrative":[{"narrative":"required narr 1","language":"ne"}]},{"sector_vocabulary":"2","category_code":null,"percentage":"50","narrative":[{"narrative":"required narr 2","language":"ne"}]},{"sector_vocabulary":"3","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"4","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"5","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"6","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"7","sdg_goal":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"8","sdg_target":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"9","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"10","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"11","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"12","text":null,"percentage":null,"narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"99","vocabulary_uri":null,"text":null,"percentage":null,"narrative":[{"narrative":"required narr","language":"ne"}]},{"sector_vocabulary":"98","vocabulary_uri":null,"text":null,"percentage":null,"narrative":[{"narrative":"required narr","language":"ne"}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isSectorElementCompleted($activity)); + } + + public function test_sector_is_complete_for_mix_all() { - $sector_typeData = json_decode( - '[{"sector_vocabulary":"","text":"11110-aaa","percentage":"100","narrative":[{"narrative":"narrative test","language":"en"}]}]', - true, - 512, - JSON_THROW_ON_ERROR + $actualData = json_decode( + '[{"sector_vocabulary":"1","code":"11110","percentage":"7.14","narrative":[{"narrative":"required narr 1","language":"ne"}]},{"sector_vocabulary":"2","category_code":"112","percentage":"7.14","narrative":[{"narrative":"required narr 2","language":"ne"}]},{"sector_vocabulary":"3","text":"123","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"4","text":"1234","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"5","text":"12345","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"6","text":"123456","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"7","sdg_goal":"1","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"8","sdg_target":"1.3","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"9","text":"6789","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"10","text":"78910","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"11","text":"891011","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"12","text":"9101112","percentage":"7.14","narrative":[{"narrative":null,"language":null}]},{"sector_vocabulary":"99","vocabulary_uri":null,"text":"99code","percentage":"7.14","narrative":[{"narrative":"required narr","language":"ne"}]},{"sector_vocabulary":"98","vocabulary_uri":null,"text":"98code","percentage":"7.14","narrative":[{"narrative":"required narr","language":"ne"}]}]', + true ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_one_multi_dimensional_element_complete($this->element, $sector_typeData); + $this->assertTrue($this->elementCompleteService->isSectorElementCompleted($activity)); } } diff --git a/tests/Feature/Element/TagCompleteTest.php b/tests/Feature/Element/TagCompleteTest.php index 1e804cb7fb..4aa2c596c4 100644 --- a/tests/Feature/Element/TagCompleteTest.php +++ b/tests/Feature/Element/TagCompleteTest.php @@ -4,11 +4,17 @@ namespace Tests\Feature\Element; +use App\IATI\Models\Activity\Activity; +use Illuminate\Support\Arr; +use Tests\Traits\FilterMandatoryItemsTrait; + /** * Class TagCompleteTest. */ class TagCompleteTest extends ElementCompleteTest { + use FilterMandatoryItemsTrait; + /** * Element tag. * @@ -16,43 +22,442 @@ class TagCompleteTest extends ElementCompleteTest */ private string $element = 'tag'; + /** + * @var array|string[] + */ + private array $mandatoryAttributes = [ + 'attributes.tag_vocabulary.criteria' => 'mandatory', + 'attributes.goals_tag_code.criteria' => 'mandatory', + 'attributes.targets_tag_code.criteria' => 'mandatory', + 'attributes.tag_text.criteria' => 'mandatory', + ]; + + /** + * @var array + */ + private array $mandatorySubelements = []; + /** * Mandatory attribute test. * * @return void * @throws \JsonException */ - public function test_tag_type_mandatory_attributes(): void + public function test_sector_type_mandatory_attributes(): void { - $this->test_mandatory_attributes($this->element, ['goals_tag_code', 'targets_tag_code', 'tag_text']); + $tagSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $tagFlattened = flattenArrayWithKeys($tagSchema); + $tagFlattened = getItemsWhereKeyContains($tagFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $tagFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatorySubelements($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatoryAttributes); } /** - * Mandatory sub element test. + * Test for ensuring mandatory subelements have not changed since the time of writing this test. * * @return void + * * @throws \JsonException */ - public function test_tag_mandatory_sub_elements(): void + public function test_sector_subelements_have_not_changed(): void { - $this->test_mandatory_sub_elements($this->element, []); + $tagSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $tagFlattened = flattenArrayWithKeys($tagSchema); + $tagFlattened = getItemsWhereKeyContains($tagFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $tagFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatoryAttributes($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatorySubelements); } - /** - * Tag element complete test. - * - * @return void - * @throws \JsonException - */ - public function test_tag_element_complete(): void + public function test_tag_is_incomplete_when_null() + { + $actualData = null; + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_when_empty_string() + { + $actualData = ''; + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_when_empty_array() + { + $actualData = []; + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_when_empty_json_array() + { + $actualData = json_decode('[{}]'); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_null() + { + $actualData = json_decode( + '[{"tag_vocabulary":null,"tag_text":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_1_when_only_vocab_is_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"1","tag_text":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_1_when_only_vocab_is_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"1","tag_text":"1234","narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_2_when_only_vocab_is_null() + { + $actualData = json_decode( + '[{"tag_vocabulary":null,"goals_tag_code":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_2_when_only_vocab_is_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"2","goals_tag_code":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_2_both_are_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"2","goals_tag_code":"1","narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_3_when_only_vocab_is_null() + { + $actualData = json_decode( + '[{"tag_vocabulary":null,"targets_tag_code":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_3_when_only_vocab_is_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"3","targets_tag_code":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_3_both_are_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"3","targets_tag_code":"1.1","narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_4_when_only_vocab_is_null() + { + $actualData = json_decode( + '[{"tag_vocabulary":null,"tag_text":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_4_when_only_vocab_is_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"4","tag_text":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_4_both_are_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"4","tag_text":"1ab","narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_99_when_only_vocab_is_null() + { + $actualData = json_decode( + '[{"tag_vocabulary":null","tag_text":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_99_when_only_vocab_is_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"99","tag_text":null,"narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_99_both_are_filled() + { + $actualData = json_decode( + '[{"tag_vocabulary":"99","tag_text":"1ab","narrative":[{"narrative":null,"language":null}]}]' + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_null_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":null,"tag_text":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":null,"tag_text":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_1_when_only_vocab_is_filled_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":"1","tag_text":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"1","tag_text":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_1_when_only_vocab_is_filled_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":"1","tag_text":"1234","narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"1","tag_text":"1234","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_2_when_only_vocab_is_null_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":null,"goals_tag_code":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":null,"goals_tag_code":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_2_when_only_vocab_is_filled_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":"2","goals_tag_code":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"2","goals_tag_code":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_2_both_are_filled_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":"2","goals_tag_code":"1","narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"2","goals_tag_code":"1","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_3_when_only_vocab_is_null_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":null,"targets_tag_code":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":null,"targets_tag_code":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_3_when_only_vocab_is_filled_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":"3","targets_tag_code":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"3","targets_tag_code":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_3_both_are_filled_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":"3","targets_tag_code":"1.1","narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"3","targets_tag_code":"1.1","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_4_when_only_vocab_is_null_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":null,"tag_text":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":null,"tag_text":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_4_when_only_vocab_is_filled_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":"4","tag_text":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"4","tag_text":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_4_both_are_filled_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":"4","tag_text":"1ab","narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"4","tag_text":"1ab","narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_99_when_only_vocab_is_null_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":null","tag_text":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":null","tag_text":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_incomplete_for_vocab_99_when_only_vocab_is_filled_multiple() + { + $actualData = json_decode( + '[{"tag_vocabulary":"99","tag_text":null,"narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"99","tag_text":null,"narrative":[{"narrative":null,"language":null}]}]', + true + ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; + + $this->assertFalse($this->elementCompleteService->isTagElementCompleted($activity)); + } + + public function test_tag_is_complete_for_vocab_99_both_are_filled_multiple() { - $sector_typeData = json_decode( - '[{"tag_vocabulary":"1","tag_text":"vocab-1","narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"2","goals_tag_code":"1","narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"3","targets_tag_code":"1.1","narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"99","tag_text":"vocab-99","vocabulary_uri":"https:\/\/www.google.com","narrative":[{"narrative":null,"language":null}]}]', - true, - 512, - JSON_THROW_ON_ERROR + $actualData = json_decode( + '[{"tag_vocabulary":"99","tag_text":"1ab","narrative":[{"narrative":null,"language":null}]},{"tag_vocabulary":"99","tag_text":"1ab","narrative":[{"narrative":null,"language":null}]}]', + true ); + $activity = new Activity(); + $activity->{$this->element} = $actualData; - $this->test_level_one_multi_dimensional_element_complete($this->element, $sector_typeData); + $this->assertTrue($this->elementCompleteService->isTagElementCompleted($activity)); } } diff --git a/tests/Feature/Element/TransactionCompleteTest.php b/tests/Feature/Element/TransactionCompleteTest.php index 56a7bd22d9..74c45e391c 100644 --- a/tests/Feature/Element/TransactionCompleteTest.php +++ b/tests/Feature/Element/TransactionCompleteTest.php @@ -4,60 +4,275 @@ namespace Tests\Feature\Element; +use Illuminate\Support\Arr; +use Tests\Traits\FilterMandatoryItemsTrait; +use Tests\Traits\TestDataTrait; + /** * Class TransactionCompleteTest. */ class TransactionCompleteTest extends ElementCompleteTest { + use FilterMandatoryItemsTrait; + use TestDataTrait; + + protected array $mandatorySubelements = [ + 'sub_elements.transaction_type.attributes.transaction_type_code.criteria' => 'mandatory', + 'sub_elements.transaction_date.attributes.date.criteria' => 'mandatory', + 'sub_elements.value.attributes.amount.criteria' => 'mandatory', + 'sub_elements.value.attributes.date.criteria' => 'mandatory', + 'sub_elements.value.attributes.currency.criteria' => 'mandatory', + ]; + + protected array $mandatoryAttributes = []; + /** * Element transactions. * * @var string */ - private string $element = 'transactions'; + private string $element = 'transactions'; /** - * Mandatory attribute test. + * Test for ensuring mandatory attributes have not changed since the time of writing this test. * * @return void + * * @throws \JsonException */ - public function test_transaction_mandatory_attributes(): void + public function test_contact_info_mandatory_attributes_have_not_changed(): void { - $this->test_mandatory_attributes($this->element, []); + $transactionSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $transactionFlattened = flattenArrayWithKeys($transactionSchema); + $transactionFlattened = getItemsWhereKeyContains($transactionFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $transactionFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatorySubelements($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatoryAttributes); } /** - * Mandatory sub element test. + * Test for ensuring mandatory subelements have not changed since the time of writing this test. * * @return void + * * @throws \JsonException */ - public function test_transaction_mandatory_sub_elements(): void + public function test_contact_info_subelements_have_not_changed(): void { - $this->test_mandatory_sub_elements($this->element, [ - 'transaction_type' => ['transaction_type_code'], - 'transaction_date' => ['date'], - 'value' => ['amount', 'date', 'currency'], - ]); + $transactionSchema = Arr::get(readElementJsonSchema(), $this->element, []); + $transactionFlattened = flattenArrayWithKeys($transactionSchema); + $transactionFlattened = getItemsWhereKeyContains($transactionFlattened, '.criteria'); + $mandatoryItemsInSchema = array_filter( + $transactionFlattened, + fn ($item) => !empty($item) && $item == 'mandatory' + ); + + $this->unsetMandatoryAttributes($mandatoryItemsInSchema); + + $this->assertEquals($mandatoryItemsInSchema, $this->mandatorySubelements); } - /** - * Transaction element complete test. - * - * @return void - * @throws \JsonException - */ - public function test_transaction_element_complete(): void - { - $elementSchema = getElementSchema($this->element); - $actualData = json_decode( - '{"reference":"ref test1","humanitarian":"1","transaction_type":[{"transaction_type_code":"1"}],"transaction_date":[{"date":"2022-07-08"}],"value":[{"amount":"5000","date":"2022-07-08","currency":"AED"}],"description":[{"narrative":[{"narrative":"test description","language":"ab"},{"narrative":"description 2","language":"af"}]}],"provider_organization":[{"organization_identifier_code":"provider ref","provider_activity_id":"15","type":"15","narrative":[{"narrative":"narative 1","language":"ae"},{"narrative":"narrative 2","language":"am"}]}],"receiver_organization":[{"organization_identifier_code":"receiver org","receiver_activity_id":"16","type":"15","narrative":[{"narrative":"receiver narrative 1","language":"ab"},{"narrative":"receiver narrative 2","language":"ak"}]}],"disbursement_channel":[{"disbursement_channel_code":null}],"sector":[{"sector_vocabulary":"2","category_code":"112","narrative":[{"narrative":"test narrative","language":"ab"},{"narrative":"test narrative 2","language":"am"}]},{"sector_vocabulary":"4","text":"5638","narrative":[{"narrative":"narrative 22","language":"af"},{"narrative":"narrative 23","language":"am"}]}],"recipient_country":[{"country_code":"AL","narrative":[{"narrative":"test narrative","language":"ab"},{"narrative":"test narrative recipient","language":"am"}]}],"recipient_region":[{"region_vocabulary":"99","custom_code":"test code","vocabulary_uri":"https:\/\/github.com\/younginnovations\/iatipublisher\/runs\/6980821807?check_suite_focus=true","narrative":[{"narrative":"narrative region 1","language":"aa"},{"narrative":"narrative region 2","language":"am"}]}],"flow_type":[{"flow_type":"10"}],"finance_type":[{"finance_type":"210"}],"aid_type":[{"aid_type_vocabulary":"1","aid_type_code":"A02"},{"aid_type_vocabulary":"4","cash_and_voucher_modalities":"1"}],"tied_status":[{"tied_status_code":"3"}]}', - true, - 512, - JSON_THROW_ON_ERROR - ); + public function test_transaction_incomplete_when_doesnt_exist() + { + $activity = $this->createDummyActivity(); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_incomplete_when_all_transactions_value_is_null() + { + $actualData = [$this->getEmptyTransactionData()]; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_complete_when_all_transactions_value_is_filled() + { + $actualData = [$this->getCompleteTransactionData()]; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertTrue($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_incomplete_when_transaction_type_is_null() + { + $actualData = [$this->getCompleteTransactionData()]; + $actualData[0]['transaction_type'] = null; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_incomplete_when_transaction_type_transaction_type_code_is_null() + { + $actualData = [$this->getCompleteTransactionData()]; + $actualData[0]['transaction_type'][0]['transaction_type_code'] = null; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_incomplete_when_transaction_date_is_null() + { + $actualData = [$this->getCompleteTransactionData()]; + $actualData[0]['transaction_date'] = null; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_incomplete_when_transaction_date_date_is_null() + { + $actualData = [$this->getCompleteTransactionData()]; + $actualData[0]['transaction_date'][0]['date'] = null; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_incomplete_when_transaction_value_is_null() + { + $actualData = [$this->getCompleteTransactionData()]; + $actualData[0]['value'] = null; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_incomplete_when_transaction_value_amount_is_null() + { + $actualData = [$this->getCompleteTransactionData()]; + $actualData[0]['value'][0]['amount'] = null; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_incomplete_when_transaction_value_date_is_null() + { + $actualData = [$this->getCompleteTransactionData()]; + $actualData[0]['value'][0]['date'] = null; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_transaction_incomplete_when_transaction_value_currency_is_null() + { + $actualData = [$this->getCompleteTransactionData()]; + $actualData[0]['value'][0]['currency'] = null; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $this->assertFalse($this->elementCompleteService->isTransactionsElementCompleted($activity)); + } + + public function test_activity_RR_and_RC_incomplete_when_transaction_RR_is_not_filled() + { + $actualData = [$this->getCompleteTransactionData()]; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $elementStatus = $activity->element_status; + + $this->assertTrue($elementStatus['transactions'], 'Transactions is incomplete.'); + $this->assertFalse($elementStatus['recipient_country'], 'Recipient country is complete. It should be incomplete.'); + $this->assertFalse($elementStatus['recipient_region'], 'Recipient region is complete. It should be incomplete.'); + } + + public function test_activity_RR_and_RC_complete_when_transaction_RR_is_filled() + { + $actualData = [$this->getCompleteTransactionData(withRR: true)]; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $elementStatus = $activity->element_status; + + $this->assertTrue($elementStatus['transactions'], 'Transactions is incomplete.'); + $this->assertTrue($elementStatus['recipient_country'], 'Recipient country is incomplete. It should be complete.'); + $this->assertTrue($elementStatus['recipient_region'], 'Recipient region is incomplete. It should be complete.'); + } + + public function test_activity_RR_and_RC_incomplete_when_transaction_RC_is_not_filled() + { + $actualData = [$this->getCompleteTransactionData()]; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $elementStatus = $activity->element_status; + + $this->assertTrue($elementStatus['transactions'], 'Transactions is incomplete.'); + $this->assertFalse($elementStatus['recipient_country'], 'Recipient country is complete. It should be incomplete.'); + $this->assertFalse($elementStatus['recipient_region'], 'Recipient region is complete. It should be incomplete.'); + } + + public function test_activity_RR_and_RC_complete_when_transaction_RC_is_filled() + { + $actualData = [$this->getCompleteTransactionData(withRC: true)]; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $elementStatus = $activity->element_status; + + $this->assertTrue($elementStatus['transactions'], 'Transactions is incomplete.'); + $this->assertTrue($elementStatus['recipient_country'], 'Recipient country is incomplete. It should be complete.'); + $this->assertTrue($elementStatus['recipient_region'], 'Recipient region is incomplete. It should be complete.'); + } + + public function test_activity_sector_incomplete_when_transaction_sector_is_not_filled() + { + $actualData = [$this->getCompleteTransactionData()]; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $elementStatus = $activity->element_status; + + $this->assertTrue($elementStatus['transactions'], 'Transactions is incomplete.'); + $this->assertFalse($elementStatus['recipient_country'], 'Recipient country is complete. It should be incomplete.'); + $this->assertFalse($elementStatus['recipient_region'], 'Recipient region is complete. It should be incomplete.'); + } + + public function test_activity_sector_complete_when_transaction_sector_is_filled() + { + $actualData = [$this->getCompleteTransactionData(withRC: true)]; + + $activity = $this->createDummyActivity(); + $activity = $this->setTransactionValue($activity, $actualData); + + $elementStatus = $activity->element_status; - $this->test_transaction_data_complete($elementSchema['sub_elements'], $actualData); + $this->assertTrue($elementStatus['transactions'], 'Transactions is incomplete.'); + $this->assertTrue($elementStatus['recipient_country'], 'Recipient country is incomplete. It should be complete.'); + $this->assertTrue($elementStatus['recipient_region'], 'Recipient region is incomplete. It should be complete.'); } } diff --git a/tests/Traits/FilterMandatoryItemsTrait.php b/tests/Traits/FilterMandatoryItemsTrait.php new file mode 100644 index 0000000000..e43289bd70 --- /dev/null +++ b/tests/Traits/FilterMandatoryItemsTrait.php @@ -0,0 +1,25 @@ +mandatorySubelements as $unsetableKey => $valueDoesNotMatterHere) { + unset($mandatoryItemsInSchema[$unsetableKey]); + } + } + + public function unsetMandatoryAttributes(array &$mandatorySubelementsInSchema): void + { + foreach ($this->mandatoryAttributes as $unsetableKey => $valueDoesNotMatterHere) { + unset($mandatorySubelementsInSchema[$unsetableKey]); + } + } +} diff --git a/tests/Traits/TestDataTrait.php b/tests/Traits/TestDataTrait.php new file mode 100644 index 0000000000..cb3c73bcad --- /dev/null +++ b/tests/Traits/TestDataTrait.php @@ -0,0 +1,213 @@ +create())->id; + + $emptyActivityData = [ + 'iati_identifier' => [ + 'activity_identifier' => 'TAN', + 'iati_identifier_text' => 'NP-SWC-0987-TAN', + 'present_organization_identifier' => 'NP-SWC-0987', + ], + 'other_identifier' => null, + 'title' => [ + [ + 'narrative' => 'test activity narrative', + 'language' => 'ng', + ], + ], + 'description' => null, + 'activity_status' => null, + 'status' => 'draft', + 'activity_date' => null, + 'contact_info' => null, + 'activity_scope' => null, + 'participating_org' => null, + 'recipient_country' => null, + 'recipient_region' => null, + 'location' => null, + 'sector' => null, + 'country_budget_items' => null, + 'humanitarian_scope' => null, + 'policy_marker' => null, + 'collaboration_type' => null, + 'default_flow_type' => null, + 'default_finance_type' => null, + 'default_aid_type' => null, + 'default_tied_status' => null, + 'budget' => null, + 'planned_disbursement' => null, + 'capital_spend' => null, + 'document_link' => null, + 'related_activity' => null, + 'legacy_data' => null, + 'conditions' => null, + 'org_id' => $orgId, + 'default_field_values' => [ + 'default_currency' => 'AOA', + 'default_language' => 'ng', + 'hierarchy' => '1', + 'budget_not_provided' => '', + 'humanitarian' => '', + 'linked_data_uri' => '', + 'default_collaboration_type' => '', + 'default_flow_type' => '', + 'default_finance_type' => '', + 'default_aid_type' => '', + 'default_tied_status' => '', + ], + 'already_published' => false, + 'linked_to_iati' => false, + 'tag' => null, + 'element_status' => [ + 'iati_identifier' => true, + 'title' => true, + 'description' => false, + 'activity_status' => false, + 'activity_date' => false, + 'activity_scope' => false, + 'recipient_country' => false, + 'recipient_region' => false, + 'collaboration_type' => false, + 'default_flow_type' => false, + 'default_finance_type' => false, + 'default_aid_type' => false, + 'default_tied_status' => false, + 'capital_spend' => false, + 'related_activity' => false, + 'conditions' => false, + 'sector' => false, + 'humanitarian_scope' => false, + 'legacy_data' => false, + 'tag' => false, + 'policy_marker' => false, + 'other_identifier' => false, + 'country_budget_items' => false, + 'budget' => false, + 'participating_org' => false, + 'document_link' => false, + 'contact_info' => false, + 'location' => false, + 'planned_disbursement' => false, + 'transactions' => false, + 'result' => false, + 'reporting_org' => true, + ], + 'created_at' => '2024-12-18T03:45:50.000000Z', + 'updated_at' => '2024-12-18T03:45:50.000000Z', + 'reporting_org' => [ + [ + 'ref' => 'NP-SWC-0987', + 'type' => '15', + 'secondary_reporter' => '1', + 'narrative' => [ + [ + 'narrative' => 'dsadas', + 'language' => 'ab', + ], + ], + ], + ], + 'upload_medium' => 'manual', + 'migrated_from_aidstream' => false, + 'complete_percentage' => 18.75, + 'has_ever_been_published' => false, + 'deprecation_status_map' => [ + 'iati_identifier' => [], + 'other_identifier' => [], + 'title' => [], + 'description' => [], + 'activity_status' => [], + 'activity_date' => [], + 'contact_info' => [], + 'activity_scope' => [], + 'participating_org' => [], + 'recipient_country' => [], + 'recipient_region' => [], + 'location' => [], + 'sector' => [], + 'country_budget_items' => [], + 'humanitarian_scope' => [], + 'policy_marker' => [], + 'collaboration_type' => [], + 'default_flow_type' => [], + 'default_finance_type' => [], + 'default_aid_type' => [], + 'default_tied_status' => [], + 'budget' => [], + 'planned_disbursement' => [], + 'capital_spend' => [], + 'document_link' => [], + 'related_activity' => [], + 'legacy_data' => [], + 'conditions' => [], + 'tag' => [], + 'reporting_org' => [], + ], + ]; + + $emptyTransactionData = []; + $emptyResultData = []; + + $activity = Activity::create($emptyActivityData); + $activity->transactions()->createMany($emptyTransactionData); + $activity->results()->createMany($emptyResultData); + + return $activity; + } + + protected function setTransactionValue(Activity $activity, array $actualData): Activity + { + $transactionSchema = [ + 'activity_id'=>$activity->id, + 'transaction' => [], + 'created_at'=> now(), + 'updated_at'=> now(), + ]; + + foreach ($actualData as $transactionData) { + $transactionSchema['transaction'] = $transactionData; + + Transaction::create($transactionSchema); + } + + return $activity->refresh(); + } + + protected function getEmptyTransactionData() + { + return json_decode('{"reference":null,"humanitarian":null,"transaction_type":[{"transaction_type_code":null}],"transaction_date":[{"date":null}],"value":[{"amount":null,"date":null,"currency":null}],"description":[{"narrative":[{"narrative":null,"language":null}]}],"provider_organization":[{"organization_identifier_code":null,"provider_activity_id":null,"type":null,"narrative":[{"narrative":null,"language":null}]}],"receiver_organization":[{"organization_identifier_code":null,"receiver_activity_id":null,"type":null,"narrative":[{"narrative":null,"language":null}]}],"disbursement_channel":[{"disbursement_channel_code":null}],"sector":[{"sector_vocabulary":null,"text":null,"narrative":[{"narrative":null,"language":null}]}],"recipient_country":[{"country_code":null,"narrative":[{"narrative":null,"language":null}]}],"recipient_region":[{"region_vocabulary":null,"custom_code":null,"narrative":[{"narrative":null,"language":null}]}],"flow_type":[{"flow_type":null}],"finance_type":[{"finance_type":null}],"aid_type":[{"aid_type_vocabulary":null,"aid_type_code":null}],"tied_status":[{"tied_status_code":null}]}', true); + } + + protected function getCompleteTransactionData(bool $withRR = false, bool $withRC = false, bool $withSector = false) + { + if ($withRR) { + return json_decode('{"reference":"Reference","humanitarian":"0","transaction_type":[{"transaction_type_code":"1"}],"transaction_date":[{"date":"2024-12-18"}],"value":[{"amount":"10000000","date":"2024-12-17","currency":"AOA"}],"description":[{"narrative":[{"narrative":"Description data","language":"ng"}]}],"provider_organization":[{"organization_identifier_code":"provide-org-reference","provider_activity_id":"provide-org-activity-id","type":"10","narrative":[{"narrative":"provide-org-narrative","language":"ng"}]}],"receiver_organization":[{"organization_identifier_code":"receiver-org-reference","receiver_activity_id":"receiver-org-activity-id","type":"10","narrative":[{"narrative":"receiver-org-narrative","language":"ng"}]}],"disbursement_channel":[{"disbursement_channel_code":"1"}],"sector":[{"sector_vocabulary":null,"code":null,"narrative":[{"narrative":null,"language":null}]}],"recipient_country":[{"country_code":null,"narrative":[{"narrative":null,"language":null}]}],"recipient_region":[{"region_vocabulary":"1","region_code":"88","narrative":[{"narrative":"RR-narrative","language":"ng"}]}],"flow_type":[{"flow_type":"21"}],"finance_type":[{"finance_type":"1"}],"aid_type":[{"aid_type_vocabulary":"1","aid_type_code":"A01"}],"tied_status":[{"tied_status_code":"3"}]}', true); + } + + if ($withRC) { + return json_decode('{"reference":"Reference","humanitarian":"0","transaction_type":[{"transaction_type_code":"1"}],"transaction_date":[{"date":"2024-12-18"}],"value":[{"amount":"10000000","date":"2024-12-17","currency":"AOA"}],"description":[{"narrative":[{"narrative":"Description data","language":"ng"}]}],"provider_organization":[{"organization_identifier_code":"provide-org-reference","provider_activity_id":"provide-org-activity-id","type":"10","narrative":[{"narrative":"provide-org-narrative","language":"ng"}]}],"receiver_organization":[{"organization_identifier_code":"receiver-org-reference","receiver_activity_id":"receiver-org-activity-id","type":"10","narrative":[{"narrative":"receiver-org-narrative","language":"ng"}]}],"disbursement_channel":[{"disbursement_channel_code":"1"}],"sector":[{"sector_vocabulary":null,"code":null,"narrative":[{"narrative":null,"language":null}]}],"recipient_country":[{"country_code":"NP","narrative":[{"narrative":"RC narr","language":"AF"}]}],"recipient_region":[{"region_vocabulary":null,"region_code":null,"narrative":[{"narrative":null,"language":null}]}],"flow_type":[{"flow_type":"21"}],"finance_type":[{"finance_type":"1"}],"aid_type":[{"aid_type_vocabulary":"1","aid_type_code":"A01"}],"tied_status":[{"tied_status_code":"3"}]}', true); + } + + if ($withSector) { + return json_decode('{"reference":"Reference","humanitarian":"0","transaction_type":[{"transaction_type_code":"1"}],"transaction_date":[{"date":"2024-12-18"}],"value":[{"amount":"10000000","date":"2024-12-17","currency":"AOA"}],"description":[{"narrative":[{"narrative":"Description data","language":"ng"}]}],"provider_organization":[{"organization_identifier_code":"provide-org-reference","provider_activity_id":"provide-org-activity-id","type":"10","narrative":[{"narrative":"provide-org-narrative","language":"ng"}]}],"receiver_organization":[{"organization_identifier_code":"receiver-org-reference","receiver_activity_id":"receiver-org-activity-id","type":"10","narrative":[{"narrative":"receiver-org-narrative","language":"ng"}]}],"disbursement_channel":[{"disbursement_channel_code":"1"}],"sector":[{"sector_vocabulary":"1","code":"11110","narrative":[{"narrative":"sector-narrative","language":"ng"}]}],"recipient_country":[{"country_code":null,"narrative":[{"narrative":null,"language":null}]}],"recipient_region":[{"region_vocabulary":null,"region_code":null,"narrative":[{"narrative":null,"language":null}]}],"flow_type":[{"flow_type":"21"}],"finance_type":[{"finance_type":"1"}],"aid_type":[{"aid_type_vocabulary":"1","aid_type_code":"A01"}],"tied_status":[{"tied_status_code":"3"}]}', true); + } + + return json_decode('{"reference":"Reference","humanitarian":"0","transaction_type":[{"transaction_type_code":"1"}],"transaction_date":[{"date":"2024-12-18"}],"value":[{"amount":"10000000","date":"2024-12-17","currency":"AOA"}],"description":[{"narrative":[{"narrative":"Description data","language":"ng"}]}],"provider_organization":[{"organization_identifier_code":"provide-org-reference","provider_activity_id":"provide-org-activity-id","type":"10","narrative":[{"narrative":"provide-org-narrative","language":"ng"}]}],"receiver_organization":[{"organization_identifier_code":"receiver-org-reference","receiver_activity_id":"receiver-org-activity-id","type":"10","narrative":[{"narrative":"receiver-org-narrative","language":"ng"}]}],"disbursement_channel":[{"disbursement_channel_code":"1"}],"sector":[{"sector_vocabulary":null,"code":null,"narrative":[{"narrative":null,"language":null}]}],"recipient_country":[{"country_code":null,"narrative":[{"narrative":null,"language":null}]}],"recipient_region":[{"region_vocabulary":null,"region_code":null,"narrative":[{"narrative":null,"language":null}]}],"flow_type":[{"flow_type":"21"}],"finance_type":[{"finance_type":"1"}],"aid_type":[{"aid_type_vocabulary":"1","aid_type_code":"A01"}],"tied_status":[{"tied_status_code":"3"}]}', true); + } +}