diff --git a/app/Providers/RepositoryServiceProvider.php b/app/Providers/RepositoryServiceProvider.php index fc8a8c4..e0d69da 100644 --- a/app/Providers/RepositoryServiceProvider.php +++ b/app/Providers/RepositoryServiceProvider.php @@ -50,5 +50,21 @@ public function register() 'App\Classes\Repositories\SupportingMessageRepositoryInterface', 'App\Classes\Repositories\SupportingMessageRepository' ); + + // Legacy Bindings + $this->app->bind( + 'App\Legacy\Classes\Repositories\OrganisationRepositoryInterface', + 'App\Legacy\Classes\Repositories\OrganisationRepository' + ); + + $this->app->bind( + 'App\Legacy\Classes\Repositories\WhatNowRepositoryInterface', + 'App\Legacy\Classes\Repositories\WhatNowRepository' + ); + + $this->app->bind( + 'App\Legacy\Classes\Repositories\WhatNowTranslationRepositoryInterface', + 'App\Legacy\Classes\Repositories\WhatNowTranslationRepository' + ); } } diff --git a/composer.json b/composer.json index b249220..6e3c5a8 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,8 @@ }, "autoload": { "psr-4": { - "App\\": "app/" + "App\\": "app/", + "App\\Legacy\\": "legacy/app/" }, "classmap": [ "database/seeds", diff --git a/config/filesystems.php b/config/filesystems.php index b744c83..e60e92c 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -2,6 +2,8 @@ return [ + 'bucket_name' => env('BUCKET_NAME', 'smdbstorageaccount'), + /* |-------------------------------------------------------------------------- | Default Filesystem Disk diff --git a/database/migrations/2026_02_20_000000_create_legacy_tables.php b/database/migrations/2026_02_20_000000_create_legacy_tables.php new file mode 100644 index 0000000..1250169 --- /dev/null +++ b/database/migrations/2026_02_20_000000_create_legacy_tables.php @@ -0,0 +1,141 @@ +increments('id'); + $table->integer('tenant_id'); + $table->string('tenant_user_id'); + $table->string('name'); + $table->text('description')->nullable(); + $table->string('key')->unique('legacy_applications_key_unique'); + $table->timestamp('created_at')->nullable(); + $table->timestamp('updated_at')->nullable(); + $table->timestamp('deleted_at')->nullable(); + $table->bigInteger('estimated_users_count')->nullable(); + }); + Schema::table('legacy_applications', function ($table) { + $table->index(['tenant_id', 'tenant_user_id'], 'legacy_applications_tenant_id_tenant_user_id_index'); + }); + + Schema::create('legacy_organisations', function ($table) { + $table->increments('id'); + $table->string('country_code', 3); + $table->string('org_name'); + $table->string('oid_code'); + $table->string('attribution_url')->nullable(); + $table->string('attribution_file_name')->nullable(); + }); + Schema::table('legacy_organisations', function ($table) { + $table->index('country_code', 'legacy_organisations_country_code_index'); + }); + + Schema::create('legacy_organisation_details', function ($table) { + $table->increments('id'); + $table->unsignedInteger('org_id'); + $table->string('language_code', 10)->nullable(); + $table->string('org_name'); + $table->text('attribution_message')->nullable(); + $table->tinyInteger('published'); + $table->unique(['org_id', 'language_code'], 'legacy_organisation_details_org_id_language_code_unique'); + $table->foreign('org_id', 'legacy_organisation_details_org_id_foreign') + ->references('id')->on('legacy_organisations') + ->onDelete('cascade'); + }); + + Schema::create('legacy_region_translations', function ($table) { + $table->increments('id'); + $table->unsignedInteger('region_id'); + $table->string('language_code', 10)->nullable(); + $table->string('title'); + $table->text('description')->nullable(); + $table->timestamp('created_at')->nullable(); + $table->timestamp('updated_at')->nullable(); + $table->index('region_id', 'legacy_region_translations_region_id_index'); + }); + + Schema::create('legacy_regions', function ($table) { + $table->increments('id'); + $table->unsignedInteger('organisation_id'); + $table->string('title'); + $table->string('slug'); + $table->timestamp('created_at')->nullable(); + $table->timestamp('updated_at')->nullable(); + $table->index('organisation_id', 'legacy_regions_organisation_id_index'); + $table->index('slug', 'legacy_regions_slug_index'); + }); + + Schema::create('legacy_whatnow_entities', function ($table) { + $table->increments('id'); + $table->unsignedInteger('org_id'); + $table->integer('region_id')->nullable(); + $table->string('event_type'); + $table->timestamp('created_at')->nullable(); + $table->timestamp('updated_at')->nullable(); + $table->unique(['org_id', 'event_type', 'region_id'], 'legacy_whatnow_entities_org_id_event_type_region_id_unique'); + $table->index(['org_id', 'event_type'], 'legacy_whatnow_entities_org_id_event_type_index'); + $table->index('region_id', 'legacy_whatnow_entities_region_id_index'); + }); + + Schema::create('legacy_whatnow_entity_translations', function ($table) { + $table->increments('id'); + $table->unsignedInteger('entity_id'); + $table->string('language_code', 10)->nullable(); + $table->string('title')->nullable(); + $table->text('description')->nullable(); + $table->string('web_url', 512)->nullable(); + $table->timestamp('created_at')->nullable(); + $table->timestamp('published_at')->nullable(); + $table->foreign('entity_id', 'legacy_whatnow_entity_translations_entity_id_foreign') + ->references('id')->on('legacy_whatnow_entities') + ->onDelete('cascade'); + }); + + Schema::create('legacy_whatnow_entity_stages', function ($table) { + $table->increments('id'); + $table->unsignedInteger('translation_id'); + $table->string('language_code', 10)->nullable(); + $table->enum('stage', ['warning', 'watch', 'immediate', 'recover', 'mitigation', 'seasonalForecast']); + $table->json('content')->nullable(); + $table->foreign('translation_id', 'legacy_whatnow_entity_stages_translation_id_foreign') + ->references('id')->on('legacy_whatnow_entity_translations') + ->onDelete('cascade'); + $table->index('translation_id', 'legacy_whatnow_entity_stages_translation_id_index'); + }); + } + + /** + * Reverse the migrations. + * Drop all legacy tables in reverse dependency order to respect foreign key constraints. + * + * @return void + */ + public function down() + { + Schema::disableForeignKeyConstraints(); + + Schema::dropIfExists('legacy_whatnow_entity_stages'); + Schema::dropIfExists('legacy_whatnow_entity_translations'); + Schema::dropIfExists('legacy_whatnow_entities'); + Schema::dropIfExists('legacy_region_translations'); + Schema::dropIfExists('legacy_regions'); + Schema::dropIfExists('legacy_organisation_details'); + Schema::dropIfExists('legacy_organisations'); + Schema::dropIfExists('legacy_applications'); + + Schema::enableForeignKeyConstraints(); + } +} + + diff --git a/legacy/app/Classes/Feeds/JsonFeedInterface.php b/legacy/app/Classes/Feeds/JsonFeedInterface.php new file mode 100644 index 0000000..47d26bb --- /dev/null +++ b/legacy/app/Classes/Feeds/JsonFeedInterface.php @@ -0,0 +1,11 @@ +whatNowRepo = $whatNowRepo; + $this->whatNowTransRepo = $whatNowTransRepo; + $this->responseManager = $responseManager; + $this->transformer = $transformer; + + $this->responseManager->setSerializer(new CustomDataSerializer()); + } + + /** + * @param Organisation $org + * @return $this + */ + public function setOrganisation(Organisation $org) + { + $this->organisation = $org; + + return $this; + } + + /** + * @param string $lang + * @return $this + */ + public function setLanguage($lang = 'en_US') + { + // @todo validate locale + $this->language = $lang; + + return $this; + } + + /** + * @param null $types + * @return $this + */ + public function setEventTypeFilter($types = null) + { + if (is_array($types)) { + $this->filterEventTypes = $types; + } + + if (is_string($types)) { + $this->filterEventTypes = explode(',', $types); + } + + return $this; + } + + public function loadData() + { + $data = $this->whatNowRepo->findItemsForOrgId( + $this->organisation->id, + $this->language, + $this->filterEventTypes + ); + + if ($data instanceof Collection) { + + + $this->collection = $data->reject(function(WhatNowEntity $entity){ + + return ($this->whatNowTransRepo->getLatestPublishedTranslations($entity->id)->count() === 0); + }); + } + } + + public function getCollection() + { + return $this->collection; + } + + public function getResponseData() + { + $resource = new \League\Fractal\Resource\Collection($this->collection, $this->transformer); + $rootScope = $this->responseManager->createData($resource); + return $rootScope->toArray(); + } +} diff --git a/legacy/app/Classes/Repositories/OrganisationRepository.php b/legacy/app/Classes/Repositories/OrganisationRepository.php new file mode 100644 index 0000000..2aaf953 --- /dev/null +++ b/legacy/app/Classes/Repositories/OrganisationRepository.php @@ -0,0 +1,123 @@ +orgModel = $orgModel; + } + + /** + * @param array $attributes + * @return static + */ + public function newInstance(array $attributes = []) + { + return $this->orgModel->newInstance($attributes); + } + + /** + * @param array $columns + * @return \Illuminate\Database\Eloquent\Collection|static[] + */ + public function all($columns = ['*']) + { + return $this->orgModel->all($columns); + } + + /** + * @param array $attributes + * @return static + */ + public function create(array $attributes) + { + return $this->orgModel->create($attributes); + } + + /** + * @param $id + * @param array $columns + * @return mixed + */ + public function find($id, $columns = ['*']) + { + return $this->orgModel->findOrFail($id, $columns); + } + + /** + * @param $id + * @param array $input + * @return mixed + */ + public function updateWithIdAndInput($id, array $input) + { + return $this->orgModel->where('id', $id)->update($input); + } + + /** + * @param Organisation $org + * @param array $input + * @return mixed + */ + public function updateDetailsWithInput(Organisation $org, array $input) + { + Log::error(print_r($input, true)); + + if (array_key_exists('url', $input)) { + $org->update([ + 'attribution_url' => $input['url'], + ]); + } + + if (array_key_exists('translations', $input)) { + if (count($input['translations'])) { + DB::transaction(function () use ($org, $input) { + $org->details()->delete(); + + foreach ($input['translations'] as $lang => $data) { + $org->details()->updateOrCreate([ + 'language_code' => strtolower($lang), + ], [ + 'language_code' => strtolower($lang), + 'org_name' => $data['name'] ?? '', + 'attribution_message' => $data['attributionMessage'] ?? '', + 'published' => $data['published'] ?? false, + ]); + } + }); + } + } + } + + /** + * @param $id + * @return int + */ + public function destroy($id) + { + return $this->orgModel->destroy($id); + } + + /** + * @param $code + * @return mixed + */ + public function findByCountryCode($code) + { + return $this->orgModel->where('country_code', $code)->firstOrFail(); + } +} diff --git a/legacy/app/Classes/Repositories/OrganisationRepositoryInterface.php b/legacy/app/Classes/Repositories/OrganisationRepositoryInterface.php new file mode 100644 index 0000000..4f4f3cd --- /dev/null +++ b/legacy/app/Classes/Repositories/OrganisationRepositoryInterface.php @@ -0,0 +1,21 @@ +whatNowModel = $whatNowModel; + $this->whatNowTransRepo = $whatNowTransRepo; + } + + /** + * @param array $attributes + * @return WhatNowEntity + */ + public function newInstance(array $attributes = []) + { + return $this->whatNowModel->newInstance($attributes); + } + + /** + * @param array $columns + * @return \Illuminate\Database\Eloquent\Collection|static[] + */ + public function all($columns = ['*']) + { + return $this->whatNowModel->all($columns); + } + + /** + * @param array $attributes + * @return WhatNowEntity + */ + public function create(array $attributes) + { + /** @var WhatNowEntity $entity */ + $entity = new $this->whatNowModel([ + 'org_id' => $attributes['org_id'], + 'region_id' => empty($attributes['region_id']) ? null : $attributes['region_id'], + 'country_code' => $attributes['country_code'], + 'event_type' => $attributes['event_type'], + ]); + $entity->save(); + + return $entity; + } + + /** + * @param array $input + * @return WhatNowEntity + */ + public function createFromArray(array $input) + { + $entity = $this->create([ + 'org_id' => $input['orgId'], + 'region_id' => data_get($input, 'region_id', null), + 'country_code' => $input['countryCode'], + 'event_type' => $input['eventType'], + ]); + + if ($input['translations']) { + $this->whatNowTransRepo->addTranslations($entity, $input['translations']); + } + + return $entity; + } + + /** + * @param $id + * @param array $columns + * @return mixed + */ + public function find($id, $columns = ['*']) + { + return $this->whatNowModel->findOrFail($id, $columns); + } + + /** + * @param $id + * @param array $input + * @return mixed + */ + public function updateWithIdAndInput($id, array $input) + { + /** @var WhatNowEntity $entity */ + $entity = $this->whatNowModel->findOrFail($id); + + Log::info('Updating WhatNowEntity', [ + 'id' => $id, + 'input' => $input, + ]); + + $entity->update([ + 'org_id' => $input['orgId'], + 'region_id' => data_get($input, 'region_id', null), + 'country_code' => $input['countryCode'], + 'event_type' => $input['eventType'], + ]); + + if ($input['translations']) { + Log::info('Updating WhatNowEntity translations', [ + 'translations' => $input['translations'], + ]); + + $this->whatNowTransRepo->addTranslations($entity, $input['translations']); + } + + return $entity; + } + + /** + * @param $id + * @return int + */ + public function destroy($id) + { + return $this->whatNowModel->destroy($id); + } + + /** + * @param $orgId + * @param null $lang + * @param array $eventTypes + */ + public function findItemsForOrgId($orgId, $lang = null, array $eventTypes = []) + { + $query = $this->whatNowModel->where('org_id', $orgId); + + if (count($eventTypes)) { + $query->whereIn('event_type', $eventTypes); + } + + return $query->get(); + } + + /** + * @param $orgId + * @param null $lang + * @param array $eventTypes + */ + public function findItemsForRegionByOrgId($orgId, $lang = null, array $eventTypes = [], $regionName = null) + { + $query = $this->whatNowModel->where('org_id', $orgId); + + if (count($eventTypes)) { + $query->whereIn('event_type', $eventTypes); + } + + if (empty($regionName) || strtolower($regionName) == 'national') { + $query->whereNull('region_id'); + } else { + $region = Region::where('organisation_id', '=', $orgId) + ->where('title', '=', $regionName) + ->first(); + + if (! empty($region)) { + $query->where('region_id', $region->id); + } + } + + return $query->get(); + } +} diff --git a/legacy/app/Classes/Repositories/WhatNowRepositoryInterface.php b/legacy/app/Classes/Repositories/WhatNowRepositoryInterface.php new file mode 100644 index 0000000..50f66ee --- /dev/null +++ b/legacy/app/Classes/Repositories/WhatNowRepositoryInterface.php @@ -0,0 +1,27 @@ +whatNowTranslationModel = $whatNowTranslationModel; + } + + /** + * @param array $attributes + * @return WhatNowEntityTranslation + */ + public function newInstance(array $attributes = []) + { + return $this->whatNowTranslationModel->newInstance($attributes); + } + + /** + * @param array $columns + * @return \Illuminate\Database\Eloquent\Collection|static[] + */ + public function all($columns = ['*']) + { + return $this->whatNowTranslationModel->all($columns); + } + + /** + * @param WhatNowEntity $entity + * @param array $translations + */ + public function addTranslations(WhatNowEntity $entity, array $translations) + { + try { + foreach ($translations as $trans) { + Log::info('Adding translation', [ + 'trans' => $trans, + ]); + + $translation = $entity->translations()->create([ + 'web_url' => $trans['webUrl'], + 'language_code' => $trans['lang'], + 'title' => $trans['title'], + 'description' => isset($trans['description']) ? $trans['description'] : null, + ]); + + foreach ($trans['stages'] as $stage => $content) { + if (! in_array($stage, WhatNowRepository::EVENT_STAGES)) { + continue; + } + + $transStage = $translation->stages() + ->where('language_code', '=', $trans['lang']) + ->where('stage', '=', $stage) + ->first(); + + if (empty($transStage)) { + if (! empty($content)) { + try { + $translation->stages()->create([ + 'language_code' => $trans['lang'], + 'stage' => $stage, + 'content' => json_encode($content), + ]); + } catch (\Exception $e) { + Log::error('ERROR', [$e->getMessage()]); + } + } + } else { + $transStage->update([ + 'content' => json_encode($content), + ]); + } + } + } + } catch (\Exception $e) { + Log::error('ERROR', [$e->getMessage()]); + } + } + + /** + * @param $id + * @param array $columns + * @return mixed + */ + public function find($id, $columns = ['*']) + { + return $this->whatNowTranslationModel->findOrFail($id, $columns); + } + + /** + * Returns latest translations for an entity + * + * Query orders translations with this entity id by their created date, and then groups them together + * by the language code, so that only the latest translation for each language is returned. + * + * @param $id + * @return \Illuminate\Database\Eloquent\Collection + */ + public function getLatestTranslations($id) + { + $model = $this->whatNowTranslationModel; + + return $model::fromQuery(DB::raw('SELECT wet1.* +FROM legacy_whatnow_entity_translations wet1 +LEFT JOIN legacy_whatnow_entity_translations wet2 ON wet1.entity_id = wet2.entity_id AND wet1.language_code = wet2.language_code AND wet1.created_at < wet2.created_at +WHERE wet2.created_at IS NULL AND wet1.entity_id = :entityId'), ['entityId' => $id]); + } + + /** + * Returns latest published translations for an entity + * + * Query orders translations with this entity id by their published date, and then groups them together + * by the language code, so that only the latest published translation for each language is returned. + * + * @param $id + * @return \Illuminate\Database\Eloquent\Collection + */ + public function getLatestPublishedTranslations($id) + { + $model = $this->whatNowTranslationModel; + + return $model::fromQuery(DB::raw('SELECT wet1.* +FROM legacy_whatnow_entity_translations wet1 +LEFT JOIN legacy_whatnow_entity_translations wet2 ON wet1.entity_id = wet2.entity_id AND wet1.language_code = wet2.language_code AND wet1.published_at < wet2.published_at +WHERE wet2.published_at IS NULL AND wet1.entity_id = :entityId AND wet1.published_at IS NOT NULL'), ['entityId' => $id]); + } + + /** + * @param array $ids + * @returns void + */ + public function publishTranslationsById(array $ids) + { + WhatNowEntityTranslation::whereIn('id', $ids)->update(['published_at' => new Carbon()]); + } + + /** + * @param int $id + * @return WhatNowEntityTranslation + */ + public function getTranslationById($id) + { + return WhatNowEntityTranslation::findOrFail($id); + } + + /** + * @param $id + * @return int + */ + public function destroy($id) + { + return $this->whatNowTranslationModel->destroy($id); + } + + public function create(array $attributes) + { + // not implemented + } + + public function updateWithIdAndInput($id, array $input) + { + // not implemented + } +} diff --git a/legacy/app/Classes/Repositories/WhatNowTranslationRepositoryInterface.php b/legacy/app/Classes/Repositories/WhatNowTranslationRepositoryInterface.php new file mode 100644 index 0000000..5f6dc49 --- /dev/null +++ b/legacy/app/Classes/Repositories/WhatNowTranslationRepositoryInterface.php @@ -0,0 +1,39 @@ + $data] : $data; + } + + public function item(?string $resourceKey, array $data): array + { + return ($resourceKey && $resourceKey !== 'data') ? [$resourceKey => $data] : $data; + } + + public function null(): ?array + { + return ['data' => []]; + } +} diff --git a/legacy/app/Classes/Transformers/WhatNowEntityTransformer.php b/legacy/app/Classes/Transformers/WhatNowEntityTransformer.php new file mode 100644 index 0000000..3b2b642 --- /dev/null +++ b/legacy/app/Classes/Transformers/WhatNowEntityTransformer.php @@ -0,0 +1,128 @@ +unpublished = $configuration['unpublished']; + } + + if(isset($configuration['castDateToBoolean']) && is_bool($configuration['castDateToBoolean'])) { + $this->castDateToBoolean = $configuration['castDateToBoolean']; + } + + $this->wnTransRepo = $repo; + } + + /** + * Turn this item object into a generic array + * + * @param WhatNowEntity $model + * @return array + */ + public function transform(WhatNowEntity $model) + { + $response = [ + 'id' => (string) $model->id, + 'countryCode' => $model->organisation->country_code, + 'eventType' => $model->event_type, + 'regionName' => $model->region_name, + 'region' => $model->region, + 'attribution' => [ + 'name' => $model->organisation->org_name, + 'countryCode' => $model->organisation->country_code, + 'url' => $model->organisation->attribution_url, + 'imageUrl' => $model->organisation->attribution_file_name ? $model->organisation->getAttributionImageUrl() : null, + 'translations' => null + ] + ]; + + if ($model->organisation->details->count()) { + $response['attribution']['translations'] = []; + + foreach ($model->organisation->details as $detail) { + $response['attribution']['translations'][$detail->language_code] = [ + 'languageCode' => $detail->language_code, + 'name' => $detail->org_name, + 'attributionMessage' => $detail->attribution_message, + ]; + + $response['attribution']['translations'][$detail->language_code]['published'] = (bool) $detail->published; + } + } + + if ($this->unpublished) { + $translations = $this->wnTransRepo->getLatestTranslations($model->id); + } else { + $translations = $this->wnTransRepo->getLatestPublishedTranslations($model->id); + } + + $defaultStages = []; + foreach(WhatNowRepository::EVENT_STAGES as $eventStages) { + $defaultStages[$eventStages] = null; + } + + if ($translations) { + + /** @var WhatNowEntityTranslation $trans */ + foreach ($translations as $trans) { + + $stages = $defaultStages; + if($trans->stages){ + foreach ($trans->stages as $stage) { + $stages[$stage->stage] = json_decode($stage['content']); + } + } + + $response['translations'][$trans->language_code] = [ + 'id' => (string) $trans->id, + 'lang' => $trans->language_code, + 'webUrl' => $trans->web_url, + 'title' => $trans->title, + 'description' => $trans->description, + 'published' => $this->prepareDateField($trans->published_at), + 'createdAt' => $trans->created_at->format('c'), + 'stages' => $stages + ]; + } + } + + return $response; + } + + protected function prepareDateField($date) + { + if($this->castDateToBoolean) + { + return ($date instanceof \DateTimeInterface) ? true : false; + } + + return ($date instanceof \DateTimeInterface) ? $date->format('c') : null; + } +} diff --git a/legacy/app/Http/Controllers/WhatNowController.php b/legacy/app/Http/Controllers/WhatNowController.php new file mode 100644 index 0000000..bbdc09a --- /dev/null +++ b/legacy/app/Http/Controllers/WhatNowController.php @@ -0,0 +1,584 @@ +orgRepo = $orgRepo; + $this->wnRepo = $wnRepo; + $this->wnTransRepo = $wnTransRepo; + $this->request = $request; + $this->manager = $manager; + $this->manager->setSerializer(new CustomDataSerializer()); + } + + /** + * @param $id + * @return \Symfony\Component\HttpFoundation\Response + */ + public function getPublishedById($id) + { + try { + /** @var WhatNowEntity $entity */ + $entity = $this->wnRepo->find($id); + } catch (ModelNotFoundException $e) { + return response()->json([ + 'status' => 404, + 'error_message' => 'Entity not found', + 'errors' => ['Entity not found'], + ], 404); + } + + if ($this->wnTransRepo->getLatestPublishedTranslations($entity->id)->count() === 0) { + return response()->json([ + 'status' => 404, + 'error_message' => 'Entity not found', + 'errors' => ['Entity not found'], + ], 404); + } + + // Load related organisation + $entity->load('organisation'); + $entity->load('organisation.details'); + + // Transform model into required json response structure. Correctly cast data types etc. + $resource = new Item($entity, new WhatNowEntityTransformer($this->wnTransRepo)); + $response = $this->manager->createData($resource); + + return response()->json(['data' => $response->toArray()], 200); + } + + /** + * @param $id + * @return \Symfony\Component\HttpFoundation\Response + */ + public function getLatestById($id) + { + try { + /** @var WhatNowEntity $entity */ + $entity = $this->wnRepo->find($id); + } catch (ModelNotFoundException $e) { + return response()->json([ + 'status' => 404, + 'error_message' => 'Entity not found', + 'errors' => ['Entity not found'], + ], 404); + } + + // Load related organisation + $entity->load('organisation'); + $entity->load('organisation.details'); + + $entity->load('translations'); + + // Transform model into required json response structure. Correctly cast data types etc. + $resource = new Item($entity, new WhatNowEntityTransformer($this->wnTransRepo, [ + 'unpublished' => true, + ])); + $response = $this->manager->createData($resource); + + return response()->json(['data' => $response->toArray()], 200); + } + + /** + * @param $id + * @return \Symfony\Component\HttpFoundation\Response + */ + public function deleteById($id) + { + try { + $entity = $this->wnRepo->find($id); + } catch (ModelNotFoundException $e) { + return response()->json([ + 'status' => 404, + 'error_message' => 'Entity not found', + 'errors' => ['Entity not found'], + ]); + } + + $entity->delete(); + + return response()->json([ + 'status' => 200, + 'message' => 'Entity deleted', + ], 200); + } + + /** + * @param WhatNowFeed $feed + * @param $code + * @return \Laravel\Lumen\Http\ResponseFactory|\Symfony\Component\HttpFoundation\Response + */ + public function getFeed(WhatNowFeed $feed, $code) + { + try { + $org = $this->orgRepo->findByCountryCode(strtoupper($code)); + } catch (\Exception $e) { + Log::error('Organisation not found', ['message' => $e->getMessage()]); + + return response(null, 404); + } + + $feed->setOrganisation($org); + + // @todo lang filter + /*$langParam = $this->request->query('language', null); + $langHeader = $this->request->header('Accept-Language', null); + + if ($langParam) { + $feed->setLanguage($this->request->query('language')); + } elseif ($langHeader) { + $feed->setLanguage(locale_accept_from_http($langHeader)); + }*/ + + $feed->setEventTypeFilter($this->request->query('eventType', null)); + $feed->loadData(); + + return response()->json(['data' => $feed->getResponseData()], 200); + } + + /** + * @param $code + * @return \Laravel\Lumen\Http\ResponseFactory|\Symfony\Component\HttpFoundation\Response + */ + public function getLatestForCountryCode($code) + { + try { + $org = $this->orgRepo->findByCountryCode(strtoupper($code)); + } catch (\Exception $e) { + Log::error('Organisation not found', ['message' => $e->getMessage()]); + + return response(null, 404); + } + + // todo: get language? + + /** @var \Illuminate\Database\Eloquent\Collection $items */ + $items = $this->wnRepo->findItemsForOrgId( + $org->id + ); + + $resource = new Collection($items, new WhatNowEntityTransformer($this->wnTransRepo, [ + 'unpublished' => true, + ])); + $response = $this->manager->createData($resource); + + return response()->json(['data' => $response->toArray()], 200); + } + + /** + * @param $code + * @return \Laravel\Lumen\Http\ResponseFactory|\Symfony\Component\HttpFoundation\Response + */ + public function getLatestForRegion($code, $region) + { + try { + $org = $this->orgRepo->findByCountryCode(strtoupper($code)); + } catch (\Exception $e) { + Log::error('Organisation not found', ['message' => $e->getMessage()]); + + return response(null, 404); + } + + try { + $region = $org->regions()->where('slug', str_slug($region))->firstOrFail(); + } catch (\Exception $e) { + Log::error('Organisation not found', ['message' => $e->getMessage()]); + + return response(null, 404); + } + + /** @var \Illuminate\Database\Eloquent\Collection $items */ + $items = $this->wnRepo->findItemsForRegionByOrgId( + $org->id, + null, + [], + $region->title + ); + + $resource = new Collection($items, new WhatNowEntityTransformer($this->wnTransRepo, [ + 'unpublished' => true, + ])); + $response = $this->manager->createData($resource); + + return response()->json(['data' => $response->toArray()], 200); + } + + /** + * @return \Laravel\Lumen\Http\ResponseFactory|\Symfony\Component\HttpFoundation\Response + */ + public function getAllRevisions() + { + /** @var \Illuminate\Database\Eloquent\Collection $items */ + $items = $this->wnRepo->all(); + + $resource = new Collection($items, new WhatNowEntityTransformer($this->wnTransRepo, [ + 'unpublished' => true, + 'castDateToBoolean' => false, + ])); + + $response = $this->manager->createData($resource); + + return response()->json(['data' => $response->toArray()], 200); + } + + /** + * Creates a new WhatNow Entity + */ + public function post() + { + try { + $this->validate($this->request, [ + 'countryCode' => 'string|size:3', + 'eventType' => 'string|max:50', + 'regionName' => 'nullable|string', + 'translations' => 'array', + 'translations.*.webUrl' => 'nullable|url', + 'translations.*.lang' => 'alpha|size:2', + 'translations.*.title' => 'string', + 'translations.*.description' => 'string', + ]); + } catch (ValidationException $e) { + $errors = collect($e->errors()); + Log::error(print_r($errors, true)); + + return $e->getResponse(); + } + + try { + $org = $this->orgRepo->findByCountryCode($this->request->input('countryCode')); + } catch (\Exception $e) { + Log::error('Organisation not found', ['message' => $e->getMessage()]); + + return response()->json([ + 'status' => 500, + 'error_message' => 'Unable to create item', + 'errors' => ['No matching organisation for country code'], + ], 500); + } + + if (! empty($this->request->input('regionName') && strtolower($this->request->input('regionName')) !== 'national')) { + try { + $region = Region::where('organisation_id', '=', $org->id) + ->where('title', '=', $this->request->input('regionName')) + ->firstOrFail(); + } catch (\Exception $e) { + Log::error('Region not found', ['message' => $e->getMessage()]); + + return response()->json([ + 'status' => 500, + 'error_message' => 'Unable to create item', + 'errors' => ['No matching region for country code'], + ], 500); + } + } + + $eventType = $this->request->get('eventType'); + $regionName = $this->request->get('regionName'); + + /** @var \Illuminate\Database\Eloquent\Collection $exists */ + $exists = $this->wnRepo->findItemsForRegionByOrgId($org->id, null, [$eventType], $regionName); + if ($exists->count() > 0) { + return response()->json([ + 'status' => 409, + 'error_message' => 'Entity already exists', + 'errors' => ['An entity for organisation '.$org->org_name.' and event type '.$eventType.' already exists'], + ], 409); + } + + $attributes = $this->request->all(); + + Log::info($attributes); + + $attributes['orgId'] = $org->id; + empty($region) ?: $attributes['region_id'] = $region->id; + + try { + $entity = $this->wnRepo->createFromArray($attributes); + } catch (QueryException $e) { + Log::error('Error saving Entity', ['message' => $e->getMessage()]); + + return response()->json([ + 'status' => 500, + 'error_message' => 'Error saving Entity', + 'errors' => ['Error saving Entity'], + ], 500); + } + + Log::info($entity); + + // Transform model into required json response structure. Correctly cast data types etc. + $resource = new Item($entity, new WhatNowEntityTransformer($this->wnTransRepo, [ + 'unpublished' => true, + ])); + + $response = $this->manager->createData($resource); + + return response()->json(['data' => $response->toArray()], 201); + } + + public function putById($id) + { + try { + $entity = $this->wnRepo->find($id); + } catch (ModelNotFoundException $e) { + return response()->json([ + 'status' => 404, + 'error_message' => 'Entity not found', + 'errors' => ['Entity not found'], + ]); + } + + // try { + // $this->validate($this->request, [ + // 'countryCode' => 'alpha|size:3', + // 'eventType' => 'string|max:50', + // 'regionName' => 'nullable|string', + // 'translations' => 'array', + // 'translations.*.webUrl' => 'nullable|string', + // 'translations.*.lang' => 'alpha|size:2', + // 'translations.*.title' => 'string', + // 'translations.*.description' => 'string', + // ]); + // } catch (ValidationException $e) { + // Log::info($e->getMessage()); + + // return $e->getResponse(); + // } + + try { + $org = $this->orgRepo->findByCountryCode($this->request->input('countryCode')); + } catch (\Exception $e) { + Log::error('Organisation not found', ['message' => $e->getMessage()]); + + return response()->json([ + 'status' => 500, + 'error_message' => 'Unable to create item', + 'errors' => ['No matching organisation for country code'], + ], 500); + } + + if (! empty($this->request->input('regionName')) && strtolower($this->request->input('regionName')) !== 'national') { + try { + $region = Region::where('organisation_id', '=', $org->id) + ->where('title', '=', $this->request->input('regionName')) + ->firstOrFail(); + } catch (\Exception $e) { + Log::error('Region not found', ['message' => $e->getMessage()]); + + return response()->json([ + 'status' => 500, + 'error_message' => 'Unable to create item', + 'errors' => ['No matching region for country code'], + ], 500); + } + } + + $attributes = $this->request->all(); + $attributes['orgId'] = $org->id; + empty($region) ?: $attributes['region_id'] = $region->id; + + try { + $this->wnRepo->updateWithIdAndInput($entity->id, $attributes); + } catch(\Exception $e) { + Log::error('Error updating item', ['message' => $e->getMessage()]); + + return response()->json([ + 'status' => 500, + 'error_message' => $e->getMessage(), +// 'error_message' => 'Unable to update item', + 'errors' => ['Error updating item'], + ], 500); + } + + // Transform model into required json response structure. Correctly cast data types etc. + $resource = new Item($entity->fresh(), new WhatNowEntityTransformer($this->wnTransRepo, [ + 'unpublished' => true, + ])); + + $response = $this->manager->createData($resource); + + return response()->json(['data' => $response->toArray()], 200); + } + + public function createNewTranslation($id) + { + try { + $entity = $this->wnRepo->find($id); + } catch (ModelNotFoundException $e) { + return response()->json([ + 'status' => 404, + 'error_message' => 'Entity not found', + 'errors' => ['Entity not found'], + ]); + } + + try { + $this->validate($this->request, [ + 'webUrl' => 'url', + 'lang' => 'alpha|size:2', + 'title' => 'string', + 'description' => 'string', + 'stages' => 'array', + ]); + } catch (ValidationException $e) { + return $e->getResponse(); + } + + try { + $this->wnTransRepo->addTranslations($entity, [[ + 'webUrl' => $this->request->get('webUrl'), + 'lang' => $this->request->get('lang'), + 'title' => $this->request->get('title'), + 'description' => $this->request->get('description', null), + 'stages' => $this->request->get('stages'), + ]]); + } catch(\Exception $e) { + return response()->json([ + 'status' => 500, + 'error_message' => 'Unable to update translation', + 'errors' => ['Error updating translation'], + ], 500); + } + + // Transform model into required json response structure. Correctly cast data types etc. + $resource = new Item($entity, new WhatNowEntityTransformer($this->wnTransRepo, [ + 'unpublished' => true, + ])); + + $response = $this->manager->createData($resource); + + return response()->json(['data' => $response->toArray()], 201); + } + + /** + * @param int $id + * @param int $translationId + * @return \Symfony\Component\HttpFoundation\Response + */ + public function patchTranslation($id, $translationId) + { + $this->validate($this->request, [ + 'published' => 'required|bool', + ]); + + try { + /** @var WhatNowEntity $entity */ + $entity = $this->wnRepo->find($id); + } catch (ModelNotFoundException $e) { + return response()->json([ + 'status' => 404, + 'error_message' => 'Entity not found', + 'errors' => ['Entity not found'], + ]); + } + + try { + /** @var WhatNowEntityTranslation $translation */ + $translation = $this->wnTransRepo->getTranslationById($translationId); + } catch (ModelNotFoundException $e) { + return response()->json([ + 'status' => 404, + 'error_message' => 'Translation not found', + 'errors' => ['Translation not found'], + ]); + } + + $publish = $this->request->get('published'); + + if ($publish === true) { + $translation->publish(); + } else { + $translation->revert(); + } + + // Transform model into required json response structure. Correctly cast data types etc. + $resource = new Item($entity, new WhatNowEntityTransformer($this->wnTransRepo, [ + 'unpublished' => true, + ])); + + $response = $this->manager->createData($resource); + + return response()->json(['data' => $response->toArray()], 200); + } + + public function publishTranslationsByIds() + { + $this->validate($this->request, [ + 'translationIds' => 'array', + ]); + + try { + $this->wnTransRepo->publishTranslationsById($this->request->get('translationIds')); + } catch(\Exception $e) { + return response()->json([ + 'status' => 500, + 'error_message' => 'Unable to update translations', + 'errors' => ['Error updating translations'], + ], 500); + } + + return response()->json(['success'], 200); + } +} diff --git a/legacy/app/Models/Organisation.php b/legacy/app/Models/Organisation.php new file mode 100644 index 0000000..e438fbe --- /dev/null +++ b/legacy/app/Models/Organisation.php @@ -0,0 +1,49 @@ +hasMany('App\Models\Alert', 'org_id'); + } + + public function details() + { + return $this->hasMany('App\Legacy\Models\OrganisationDetails', 'org_id'); + } + + public function regions() + { + return $this->hasMany(Region::class); + } + + public function getAttributionImageUrl() + { + return 'https://' . config('filesystems.bucket_name') . '.blob.core.windows.net/whatnow-assets/attribution_images/' . $this->attribution_file_name; + } +} diff --git a/legacy/app/Models/OrganisationDetails.php b/legacy/app/Models/OrganisationDetails.php new file mode 100644 index 0000000..d1c592c --- /dev/null +++ b/legacy/app/Models/OrganisationDetails.php @@ -0,0 +1,45 @@ + 'boolean', + ]; + + public function organisation() + { + return $this->belongsTo('App\Legacy\Models\Organisation', 'org_id', 'id'); + } +} + diff --git a/legacy/app/Models/Region.php b/legacy/app/Models/Region.php new file mode 100644 index 0000000..ac1c325 --- /dev/null +++ b/legacy/app/Models/Region.php @@ -0,0 +1,62 @@ +hasMany(RegionTranslation::class); + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function organisation() + { + return $this->belongsTo(Organisation::class); + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function whatnowEntities() + { + return $this->hasMany(WhatNowEntity::class, 'region_id', 'id'); + } + +} diff --git a/legacy/app/Models/RegionTranslation.php b/legacy/app/Models/RegionTranslation.php new file mode 100644 index 0000000..e1c56af --- /dev/null +++ b/legacy/app/Models/RegionTranslation.php @@ -0,0 +1,44 @@ +belongsTo(Region::class); + } +} + diff --git a/legacy/app/Models/WhatNowEntity.php b/legacy/app/Models/WhatNowEntity.php new file mode 100644 index 0000000..5da872c --- /dev/null +++ b/legacy/app/Models/WhatNowEntity.php @@ -0,0 +1,128 @@ + 'required|numeric', + ]; + + /** + * @param $data + * @return bool + */ + public function validate($data) + { + $v = Validator::make($data, $this->rules); + + if ($v->fails()) { + $this->errors = $v->errors(); + + return false; + } + + return true; + } + + /** + * @return mixed + */ + public function errors() + { + return $this->errors; + } + + /** + * Returns name of related org + * + * @return string + */ + public function getSenderName() + { + return $this->organisation->org_name; + } + + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function organisation() + { + return $this->belongsTo('App\Legacy\Models\Organisation', 'org_id', 'id'); + } + + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function region() + { + return $this->belongsTo('App\Legacy\Models\Region', 'region_id', 'id'); + } + + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function getRegionNameAttribute() + { + if(empty($this->region)){ + return 'National'; + } + + return $this->region->title; + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function translations() + { + return $this->hasMany('App\Legacy\Models\WhatNowEntityTranslation', 'entity_id', 'id'); + } +} diff --git a/legacy/app/Models/WhatNowEntityStage.php b/legacy/app/Models/WhatNowEntityStage.php new file mode 100644 index 0000000..8d7b5a6 --- /dev/null +++ b/legacy/app/Models/WhatNowEntityStage.php @@ -0,0 +1,88 @@ + 'required|string|between:2,10', + 'stage' => 'string|max:10', + ]; + + /** + * @param $data + * @return bool + */ + public function validate($data) + { + $v = Validator::make($data, $this->rules); + + if ($v->fails()) { + $this->errors = $v->errors(); + + return false; + } + + return true; + } + + /** + * @return mixed + */ + public function errors() + { + return $this->errors; + } + + public function translation() + { + return $this->belongsTo('App\Legacy\Models\WhatNowEntityTranslation', 'translation_id', 'id'); + } +} + diff --git a/legacy/app/Models/WhatNowEntityTranslation.php b/legacy/app/Models/WhatNowEntityTranslation.php new file mode 100644 index 0000000..4a52663 --- /dev/null +++ b/legacy/app/Models/WhatNowEntityTranslation.php @@ -0,0 +1,151 @@ + 'required|string|between:2,10', + 'title' => 'string|max:255', + 'description' => 'string', + 'web_url' => 'url', + ]; + + public static function boot() + { + parent::boot(); + + static::creating(function($model) + { + $model->created_at = Carbon::now(); + }); + } + + /** + * @param $data + * @return bool + */ + public function validate($data) + { + $v = Validator::make($data, $this->rules); + + if ($v->fails()) { + $this->errors = $v->errors(); + + return false; + } + + return true; + } + + /** + * @return mixed + */ + public function errors() + { + return $this->errors; + } + +// public function getRegionNameAttribute() +// { +// if(empty($this->entity->region)){ +// return ''; +// } +// +// return $this->entity->region->title; +// } + + /** + * @return \Illuminate\Database\Eloquent\Relations\belongsTo + */ + public function entity() + { + return $this->belongsTo('App\Legacy\Models\WhatNowEntity', 'entity_id', 'id'); + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function stages() + { + return $this->HasMany('App\Legacy\Models\WhatNowEntityStage', 'translation_id', 'id'); + } + + /** + * @param \DateTimeInterface|null $dateTime + * @return WhatNowEntityTranslation + */ + public function publish(\DateTimeInterface $dateTime = null) + { + if(is_null($dateTime)){ + $dateTime = new Carbon(); + } + + $this->published_at = $dateTime; + $this->save(); + + return $this; + } + + /** + * @return WhatNowEntityTranslation + */ + public function revert() + { + $this->published_at = null; + $this->save(); + + return $this; + } +} diff --git a/public/css/app.css b/public/css/app.css new file mode 100644 index 0000000..e69de29 diff --git a/public/js/app.js b/public/js/app.js new file mode 100644 index 0000000..dcd3f17 --- /dev/null +++ b/public/js/app.js @@ -0,0 +1 @@ +!function(n){var t={};function r(e){if(t[e])return t[e].exports;var i=t[e]={i:e,l:!1,exports:{}};return n[e].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=n,r.c=t,r.d=function(n,t,e){r.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:e})},r.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},r.t=function(n,t){if(1&t&&(n=r(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var e=Object.create(null);if(r.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var i in n)r.d(e,i,function(t){return n[t]}.bind(null,i));return e},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,"a",t),t},r.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},r.p="/",r(r.s=9)}([function(n,t,r){"use strict";var e=r(1),i=Object.prototype.toString;function o(n){return"[object Array]"===i.call(n)}function u(n){return void 0===n}function a(n){return null!==n&&"object"==typeof n}function f(n){return"[object Function]"===i.call(n)}function c(n,t){if(null!=n)if("object"!=typeof n&&(n=[n]),o(n))for(var r=0,e=n.length;r=200&&n<300}};f.headers={common:{Accept:"application/json, text/plain, */*"}},e.forEach(["delete","get","head"],(function(n){f.headers[n]={}})),e.forEach(["post","put","patch"],(function(n){f.headers[n]=e.merge(o)})),n.exports=f}).call(this,r(21))},function(n,t,r){"use strict";var e=r(0),i=r(23),o=r(2),u=r(25),a=r(28),f=r(29),c=r(6);n.exports=function(n){return new Promise((function(t,s){var l=n.data,v=n.headers;e.isFormData(l)&&delete v["Content-Type"];var p=new XMLHttpRequest;if(n.auth){var h=n.auth.username||"",d=n.auth.password||"";v.Authorization="Basic "+btoa(h+":"+d)}var _=u(n.baseURL,n.url);if(p.open(n.method.toUpperCase(),o(_,n.params,n.paramsSerializer),!0),p.timeout=n.timeout,p.onreadystatechange=function(){if(p&&4===p.readyState&&(0!==p.status||p.responseURL&&0===p.responseURL.indexOf("file:"))){var r="getAllResponseHeaders"in p?a(p.getAllResponseHeaders()):null,e={data:n.responseType&&"text"!==n.responseType?p.response:p.responseText,status:p.status,statusText:p.statusText,headers:r,config:n,request:p};i(t,s,e),p=null}},p.onabort=function(){p&&(s(c("Request aborted",n,"ECONNABORTED",p)),p=null)},p.onerror=function(){s(c("Network Error",n,null,p)),p=null},p.ontimeout=function(){var t="timeout of "+n.timeout+"ms exceeded";n.timeoutErrorMessage&&(t=n.timeoutErrorMessage),s(c(t,n,"ECONNABORTED",p)),p=null},e.isStandardBrowserEnv()){var g=r(30),y=(n.withCredentials||f(_))&&n.xsrfCookieName?g.read(n.xsrfCookieName):void 0;y&&(v[n.xsrfHeaderName]=y)}if("setRequestHeader"in p&&e.forEach(v,(function(n,t){void 0===l&&"content-type"===t.toLowerCase()?delete v[t]:p.setRequestHeader(t,n)})),e.isUndefined(n.withCredentials)||(p.withCredentials=!!n.withCredentials),n.responseType)try{p.responseType=n.responseType}catch(t){if("json"!==n.responseType)throw t}"function"==typeof n.onDownloadProgress&&p.addEventListener("progress",n.onDownloadProgress),"function"==typeof n.onUploadProgress&&p.upload&&p.upload.addEventListener("progress",n.onUploadProgress),n.cancelToken&&n.cancelToken.promise.then((function(n){p&&(p.abort(),s(n),p=null)})),void 0===l&&(l=null),p.send(l)}))}},function(n,t,r){"use strict";var e=r(24);n.exports=function(n,t,r,i,o){var u=new Error(n);return e(u,t,r,i,o)}},function(n,t,r){"use strict";var e=r(0);n.exports=function(n,t){t=t||{};var r={},i=["url","method","params","data"],o=["headers","auth","proxy"],u=["baseURL","url","transformRequest","transformResponse","paramsSerializer","timeout","withCredentials","adapter","responseType","xsrfCookieName","xsrfHeaderName","onUploadProgress","onDownloadProgress","maxContentLength","validateStatus","maxRedirects","httpAgent","httpsAgent","cancelToken","socketPath"];e.forEach(i,(function(n){void 0!==t[n]&&(r[n]=t[n])})),e.forEach(o,(function(i){e.isObject(t[i])?r[i]=e.deepMerge(n[i],t[i]):void 0!==t[i]?r[i]=t[i]:e.isObject(n[i])?r[i]=e.deepMerge(n[i]):void 0!==n[i]&&(r[i]=n[i])})),e.forEach(u,(function(e){void 0!==t[e]?r[e]=t[e]:void 0!==n[e]&&(r[e]=n[e])}));var a=i.concat(o).concat(u),f=Object.keys(t).filter((function(n){return-1===a.indexOf(n)}));return e.forEach(f,(function(e){void 0!==t[e]?r[e]=t[e]:void 0!==n[e]&&(r[e]=n[e])})),r}},function(n,t,r){"use strict";function e(n){this.message=n}e.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},e.prototype.__CANCEL__=!0,n.exports=e},function(n,t,r){r(10),n.exports=r(33)},function(n,t,r){r(11)},function(n,t,r){window._=r(12),window.axios=r(15),window.axios.defaults.headers.common["X-Requested-With"]="XMLHttpRequest"},function(n,t,r){(function(n,e){var i;(function(){var o="Expected a function",u="__lodash_placeholder__",a=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],f="[object Arguments]",c="[object Array]",s="[object Boolean]",l="[object Date]",v="[object Error]",p="[object Function]",h="[object GeneratorFunction]",d="[object Map]",_="[object Number]",g="[object Object]",y="[object RegExp]",m="[object Set]",w="[object String]",b="[object Symbol]",x="[object WeakMap]",j="[object ArrayBuffer]",A="[object DataView]",E="[object Float32Array]",O="[object Float64Array]",R="[object Int8Array]",S="[object Int16Array]",k="[object Int32Array]",T="[object Uint8Array]",C="[object Uint16Array]",L="[object Uint32Array]",I=/\b__p \+= '';/g,z=/\b(__p \+=) '' \+/g,U=/(__e\(.*?\)|\b__t\)) \+\n'';/g,N=/&(?:amp|lt|gt|quot|#39);/g,B=/[&<>"']/g,P=RegExp(N.source),D=RegExp(B.source),W=/<%-([\s\S]+?)%>/g,q=/<%([\s\S]+?)%>/g,M=/<%=([\s\S]+?)%>/g,F=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,$=/^\w*$/,H=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,V=/[\\^$.*+?()[\]{}|]/g,Z=RegExp(V.source),K=/^\s+/,J=/\s/,X=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,G=/\{\n\/\* \[wrapped with (.+)\] \*/,Y=/,? & /,Q=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,nn=/[()=,{}\[\]\/\s]/,tn=/\\(\\)?/g,rn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,en=/\w*$/,on=/^[-+]0x[0-9a-f]+$/i,un=/^0b[01]+$/i,an=/^\[object .+?Constructor\]$/,fn=/^0o[0-7]+$/i,cn=/^(?:0|[1-9]\d*)$/,sn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,ln=/($^)/,vn=/['\n\r\u2028\u2029\\]/g,pn="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",hn="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",dn="[\\ud800-\\udfff]",_n="["+hn+"]",gn="["+pn+"]",yn="\\d+",mn="[\\u2700-\\u27bf]",wn="[a-z\\xdf-\\xf6\\xf8-\\xff]",bn="[^\\ud800-\\udfff"+hn+yn+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",xn="\\ud83c[\\udffb-\\udfff]",jn="[^\\ud800-\\udfff]",An="(?:\\ud83c[\\udde6-\\uddff]){2}",En="[\\ud800-\\udbff][\\udc00-\\udfff]",On="[A-Z\\xc0-\\xd6\\xd8-\\xde]",Rn="(?:"+wn+"|"+bn+")",Sn="(?:"+On+"|"+bn+")",kn="(?:"+gn+"|"+xn+")"+"?",Tn="[\\ufe0e\\ufe0f]?"+kn+("(?:\\u200d(?:"+[jn,An,En].join("|")+")[\\ufe0e\\ufe0f]?"+kn+")*"),Cn="(?:"+[mn,An,En].join("|")+")"+Tn,Ln="(?:"+[jn+gn+"?",gn,An,En,dn].join("|")+")",In=RegExp("['’]","g"),zn=RegExp(gn,"g"),Un=RegExp(xn+"(?="+xn+")|"+Ln+Tn,"g"),Nn=RegExp([On+"?"+wn+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[_n,On,"$"].join("|")+")",Sn+"+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[_n,On+Rn,"$"].join("|")+")",On+"?"+Rn+"+(?:['’](?:d|ll|m|re|s|t|ve))?",On+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",yn,Cn].join("|"),"g"),Bn=RegExp("[\\u200d\\ud800-\\udfff"+pn+"\\ufe0e\\ufe0f]"),Pn=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Dn=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],Wn=-1,qn={};qn[E]=qn[O]=qn[R]=qn[S]=qn[k]=qn[T]=qn["[object Uint8ClampedArray]"]=qn[C]=qn[L]=!0,qn[f]=qn[c]=qn[j]=qn[s]=qn[A]=qn[l]=qn[v]=qn[p]=qn[d]=qn[_]=qn[g]=qn[y]=qn[m]=qn[w]=qn[x]=!1;var Mn={};Mn[f]=Mn[c]=Mn[j]=Mn[A]=Mn[s]=Mn[l]=Mn[E]=Mn[O]=Mn[R]=Mn[S]=Mn[k]=Mn[d]=Mn[_]=Mn[g]=Mn[y]=Mn[m]=Mn[w]=Mn[b]=Mn[T]=Mn["[object Uint8ClampedArray]"]=Mn[C]=Mn[L]=!0,Mn[v]=Mn[p]=Mn[x]=!1;var Fn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},$n=parseFloat,Hn=parseInt,Vn="object"==typeof n&&n&&n.Object===Object&&n,Zn="object"==typeof self&&self&&self.Object===Object&&self,Kn=Vn||Zn||Function("return this")(),Jn=t&&!t.nodeType&&t,Xn=Jn&&"object"==typeof e&&e&&!e.nodeType&&e,Gn=Xn&&Xn.exports===Jn,Yn=Gn&&Vn.process,Qn=function(){try{var n=Xn&&Xn.require&&Xn.require("util").types;return n||Yn&&Yn.binding&&Yn.binding("util")}catch(n){}}(),nt=Qn&&Qn.isArrayBuffer,tt=Qn&&Qn.isDate,rt=Qn&&Qn.isMap,et=Qn&&Qn.isRegExp,it=Qn&&Qn.isSet,ot=Qn&&Qn.isTypedArray;function ut(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function at(n,t,r,e){for(var i=-1,o=null==n?0:n.length;++i-1}function pt(n,t,r){for(var e=-1,i=null==n?0:n.length;++e-1;);return r}function Nt(n,t){for(var r=n.length;r--&&xt(t,n[r],0)>-1;);return r}function Bt(n,t){for(var r=n.length,e=0;r--;)n[r]===t&&++e;return e}var Pt=Rt({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"}),Dt=Rt({"&":"&","<":"<",">":">",'"':""","'":"'"});function Wt(n){return"\\"+Fn[n]}function qt(n){return Bn.test(n)}function Mt(n){var t=-1,r=Array(n.size);return n.forEach((function(n,e){r[++t]=[e,n]})),r}function Ft(n,t){return function(r){return n(t(r))}}function $t(n,t){for(var r=-1,e=n.length,i=0,o=[];++r",""":'"',"'":"'"});var Gt=function n(t){var r,e=(t=null==t?Kn:Gt.defaults(Kn.Object(),t,Gt.pick(Kn,Dn))).Array,i=t.Date,J=t.Error,pn=t.Function,hn=t.Math,dn=t.Object,_n=t.RegExp,gn=t.String,yn=t.TypeError,mn=e.prototype,wn=pn.prototype,bn=dn.prototype,xn=t["__core-js_shared__"],jn=wn.toString,An=bn.hasOwnProperty,En=0,On=(r=/[^.]+$/.exec(xn&&xn.keys&&xn.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"",Rn=bn.toString,Sn=jn.call(dn),kn=Kn._,Tn=_n("^"+jn.call(An).replace(V,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Cn=Gn?t.Buffer:void 0,Ln=t.Symbol,Un=t.Uint8Array,Bn=Cn?Cn.allocUnsafe:void 0,Fn=Ft(dn.getPrototypeOf,dn),Vn=dn.create,Zn=bn.propertyIsEnumerable,Jn=mn.splice,Xn=Ln?Ln.isConcatSpreadable:void 0,Yn=Ln?Ln.iterator:void 0,Qn=Ln?Ln.toStringTag:void 0,mt=function(){try{var n=no(dn,"defineProperty");return n({},"",{}),n}catch(n){}}(),Rt=t.clearTimeout!==Kn.clearTimeout&&t.clearTimeout,Yt=i&&i.now!==Kn.Date.now&&i.now,Qt=t.setTimeout!==Kn.setTimeout&&t.setTimeout,nr=hn.ceil,tr=hn.floor,rr=dn.getOwnPropertySymbols,er=Cn?Cn.isBuffer:void 0,ir=t.isFinite,or=mn.join,ur=Ft(dn.keys,dn),ar=hn.max,fr=hn.min,cr=i.now,sr=t.parseInt,lr=hn.random,vr=mn.reverse,pr=no(t,"DataView"),hr=no(t,"Map"),dr=no(t,"Promise"),_r=no(t,"Set"),gr=no(t,"WeakMap"),yr=no(dn,"create"),mr=gr&&new gr,wr={},br=So(pr),xr=So(hr),jr=So(dr),Ar=So(_r),Er=So(gr),Or=Ln?Ln.prototype:void 0,Rr=Or?Or.valueOf:void 0,Sr=Or?Or.toString:void 0;function kr(n){if(Hu(n)&&!zu(n)&&!(n instanceof Ir)){if(n instanceof Lr)return n;if(An.call(n,"__wrapped__"))return ko(n)}return new Lr(n)}var Tr=function(){function n(){}return function(t){if(!$u(t))return{};if(Vn)return Vn(t);n.prototype=t;var r=new n;return n.prototype=void 0,r}}();function Cr(){}function Lr(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=void 0}function Ir(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function zr(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t=t?n:t)),n}function Gr(n,t,r,e,i,o){var u,a=1&t,c=2&t,v=4&t;if(r&&(u=i?r(n,e,i,o):r(n)),void 0!==u)return u;if(!$u(n))return n;var x=zu(n);if(x){if(u=function(n){var t=n.length,r=new n.constructor(t);t&&"string"==typeof n[0]&&An.call(n,"index")&&(r.index=n.index,r.input=n.input);return r}(n),!a)return yi(n,u)}else{var I=eo(n),z=I==p||I==h;if(Pu(n))return vi(n,a);if(I==g||I==f||z&&!i){if(u=c||z?{}:oo(n),!a)return c?function(n,t){return mi(n,ro(n),t)}(n,function(n,t){return n&&mi(t,xa(t),n)}(u,n)):function(n,t){return mi(n,to(n),t)}(n,Zr(u,n))}else{if(!Mn[I])return i?n:{};u=function(n,t,r){var e=n.constructor;switch(t){case j:return pi(n);case s:case l:return new e(+n);case A:return function(n,t){var r=t?pi(n.buffer):n.buffer;return new n.constructor(r,n.byteOffset,n.byteLength)}(n,r);case E:case O:case R:case S:case k:case T:case"[object Uint8ClampedArray]":case C:case L:return hi(n,r);case d:return new e;case _:case w:return new e(n);case y:return function(n){var t=new n.constructor(n.source,en.exec(n));return t.lastIndex=n.lastIndex,t}(n);case m:return new e;case b:return i=n,Rr?dn(Rr.call(i)):{}}var i}(n,I,a)}}o||(o=new Pr);var U=o.get(n);if(U)return U;o.set(n,u),Xu(n)?n.forEach((function(e){u.add(Gr(e,t,r,e,n,o))})):Vu(n)&&n.forEach((function(e,i){u.set(i,Gr(e,t,r,i,n,o))}));var N=x?void 0:(v?c?Zi:Vi:c?xa:ba)(n);return ft(N||n,(function(e,i){N&&(e=n[i=e]),$r(u,i,Gr(e,t,r,i,n,o))})),u}function Yr(n,t,r){var e=r.length;if(null==n)return!e;for(n=dn(n);e--;){var i=r[e],o=t[i],u=n[i];if(void 0===u&&!(i in n)||!o(u))return!1}return!0}function Qr(n,t,r){if("function"!=typeof n)throw new yn(o);return bo((function(){n.apply(void 0,r)}),t)}function ne(n,t,r,e){var i=-1,o=vt,u=!0,a=n.length,f=[],c=t.length;if(!a)return f;r&&(t=ht(t,Lt(r))),e?(o=pt,u=!1):t.length>=200&&(o=zt,u=!1,t=new Br(t));n:for(;++i-1},Ur.prototype.set=function(n,t){var r=this.__data__,e=Hr(r,n);return e<0?(++this.size,r.push([n,t])):r[e][1]=t,this},Nr.prototype.clear=function(){this.size=0,this.__data__={hash:new zr,map:new(hr||Ur),string:new zr}},Nr.prototype.delete=function(n){var t=Yi(this,n).delete(n);return this.size-=t?1:0,t},Nr.prototype.get=function(n){return Yi(this,n).get(n)},Nr.prototype.has=function(n){return Yi(this,n).has(n)},Nr.prototype.set=function(n,t){var r=Yi(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},Br.prototype.add=Br.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},Br.prototype.has=function(n){return this.__data__.has(n)},Pr.prototype.clear=function(){this.__data__=new Ur,this.size=0},Pr.prototype.delete=function(n){var t=this.__data__,r=t.delete(n);return this.size=t.size,r},Pr.prototype.get=function(n){return this.__data__.get(n)},Pr.prototype.has=function(n){return this.__data__.has(n)},Pr.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Ur){var e=r.__data__;if(!hr||e.length<199)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Nr(e)}return r.set(n,t),this.size=r.size,this};var te=xi(ce),re=xi(se,!0);function ee(n,t){var r=!0;return te(n,(function(n,e,i){return r=!!t(n,e,i)})),r}function ie(n,t,r){for(var e=-1,i=n.length;++e0&&r(a)?t>1?ue(a,t-1,r,e,i):dt(i,a):e||(i[i.length]=a)}return i}var ae=ji(),fe=ji(!0);function ce(n,t){return n&&ae(n,t,ba)}function se(n,t){return n&&fe(n,t,ba)}function le(n,t){return lt(t,(function(t){return qu(n[t])}))}function ve(n,t){for(var r=0,e=(t=fi(t,n)).length;null!=n&&rt}function _e(n,t){return null!=n&&An.call(n,t)}function ge(n,t){return null!=n&&t in dn(n)}function ye(n,t,r){for(var i=r?pt:vt,o=n[0].length,u=n.length,a=u,f=e(u),c=1/0,s=[];a--;){var l=n[a];a&&t&&(l=ht(l,Lt(t))),c=fr(l.length,c),f[a]=!r&&(t||o>=120&&l.length>=120)?new Br(a&&l):void 0}l=n[0];var v=-1,p=f[0];n:for(;++v=a)return f;var c=r[e];return f*("desc"==c?-1:1)}}return n.index-t.index}(n,t,r)}))}function ze(n,t,r){for(var e=-1,i=t.length,o={};++e-1;)a!==n&&Jn.call(a,f,1),Jn.call(n,f,1);return n}function Ne(n,t){for(var r=n?t.length:0,e=r-1;r--;){var i=t[r];if(r==e||i!==o){var o=i;ao(i)?Jn.call(n,i,1):ni(n,i)}}return n}function Be(n,t){return n+tr(lr()*(t-n+1))}function Pe(n,t){var r="";if(!n||t<1||t>9007199254740991)return r;do{t%2&&(r+=n),(t=tr(t/2))&&(n+=n)}while(t);return r}function De(n,t){return xo(_o(n,t,Za),n+"")}function We(n){return Wr(Ta(n))}function qe(n,t){var r=Ta(n);return Eo(r,Xr(t,0,r.length))}function Me(n,t,r,e){if(!$u(n))return n;for(var i=-1,o=(t=fi(t,n)).length,u=o-1,a=n;null!=a&&++io?0:o+t),(r=r>o?o:r)<0&&(r+=o),o=t>r?0:r-t>>>0,t>>>=0;for(var u=e(o);++i>>1,u=n[o];null!==u&&!Yu(u)&&(r?u<=t:u=200){var c=t?null:Pi(n);if(c)return Ht(c);u=!1,i=zt,f=new Br}else f=t?[]:a;n:for(;++e=e?n:Ve(n,t,r)}var li=Rt||function(n){return Kn.clearTimeout(n)};function vi(n,t){if(t)return n.slice();var r=n.length,e=Bn?Bn(r):new n.constructor(r);return n.copy(e),e}function pi(n){var t=new n.constructor(n.byteLength);return new Un(t).set(new Un(n)),t}function hi(n,t){var r=t?pi(n.buffer):n.buffer;return new n.constructor(r,n.byteOffset,n.length)}function di(n,t){if(n!==t){var r=void 0!==n,e=null===n,i=n==n,o=Yu(n),u=void 0!==t,a=null===t,f=t==t,c=Yu(t);if(!a&&!c&&!o&&n>t||o&&u&&f&&!a&&!c||e&&u&&f||!r&&f||!i)return 1;if(!e&&!o&&!c&&n1?r[i-1]:void 0,u=i>2?r[2]:void 0;for(o=n.length>3&&"function"==typeof o?(i--,o):void 0,u&&fo(r[0],r[1],u)&&(o=i<3?void 0:o,i=1),t=dn(t);++e-1?i[o?t[u]:u]:void 0}}function Si(n){return Hi((function(t){var r=t.length,e=r,i=Lr.prototype.thru;for(n&&t.reverse();e--;){var u=t[e];if("function"!=typeof u)throw new yn(o);if(i&&!a&&"wrapper"==Ji(u))var a=new Lr([],!0)}for(e=a?e:r;++e1&&m.reverse(),l&&ca))return!1;var c=o.get(n),s=o.get(t);if(c&&s)return c==t&&s==n;var l=-1,v=!0,p=2&r?new Br:void 0;for(o.set(n,t),o.set(t,n);++l-1&&n%1==0&&n1?"& ":"")+t[e],t=t.join(r>2?", ":" "),n.replace(X,"{\n/* [wrapped with "+t+"] */\n")}(e,function(n,t){return ft(a,(function(r){var e="_."+r[0];t&r[1]&&!vt(n,e)&&n.push(e)})),n.sort()}(function(n){var t=n.match(G);return t?t[1].split(Y):[]}(e),r)))}function Ao(n){var t=0,r=0;return function(){var e=cr(),i=16-(e-r);if(r=e,i>0){if(++t>=800)return arguments[0]}else t=0;return n.apply(void 0,arguments)}}function Eo(n,t){var r=-1,e=n.length,i=e-1;for(t=void 0===t?e:t;++r1?n[t-1]:void 0;return r="function"==typeof r?(n.pop(),r):void 0,Jo(n,r)}));function ru(n){var t=kr(n);return t.__chain__=!0,t}function eu(n,t){return t(n)}var iu=Hi((function(n){var t=n.length,r=t?n[0]:0,e=this.__wrapped__,i=function(t){return Jr(t,n)};return!(t>1||this.__actions__.length)&&e instanceof Ir&&ao(r)?((e=e.slice(r,+r+(t?1:0))).__actions__.push({func:eu,args:[i],thisArg:void 0}),new Lr(e,this.__chain__).thru((function(n){return t&&!n.length&&n.push(void 0),n}))):this.thru(i)}));var ou=wi((function(n,t,r){An.call(n,r)?++n[r]:Kr(n,r,1)}));var uu=Ri(Io),au=Ri(zo);function fu(n,t){return(zu(n)?ft:te)(n,Gi(t,3))}function cu(n,t){return(zu(n)?ct:re)(n,Gi(t,3))}var su=wi((function(n,t,r){An.call(n,r)?n[r].push(t):Kr(n,r,[t])}));var lu=De((function(n,t,r){var i=-1,o="function"==typeof t,u=Nu(n)?e(n.length):[];return te(n,(function(n){u[++i]=o?ut(t,n,r):me(n,t,r)})),u})),vu=wi((function(n,t,r){Kr(n,r,t)}));function pu(n,t){return(zu(n)?ht:Se)(n,Gi(t,3))}var hu=wi((function(n,t,r){n[r?0:1].push(t)}),(function(){return[[],[]]}));var du=De((function(n,t){if(null==n)return[];var r=t.length;return r>1&&fo(n,t[0],t[1])?t=[]:r>2&&fo(t[0],t[1],t[2])&&(t=[t[0]]),Ie(n,ue(t,1),[])})),_u=Yt||function(){return Kn.Date.now()};function gu(n,t,r){return t=r?void 0:t,Wi(n,128,void 0,void 0,void 0,void 0,t=n&&null==t?n.length:t)}function yu(n,t){var r;if("function"!=typeof t)throw new yn(o);return n=ia(n),function(){return--n>0&&(r=t.apply(this,arguments)),n<=1&&(t=void 0),r}}var mu=De((function(n,t,r){var e=1;if(r.length){var i=$t(r,Xi(mu));e|=32}return Wi(n,e,t,r,i)})),wu=De((function(n,t,r){var e=3;if(r.length){var i=$t(r,Xi(wu));e|=32}return Wi(t,e,n,r,i)}));function bu(n,t,r){var e,i,u,a,f,c,s=0,l=!1,v=!1,p=!0;if("function"!=typeof n)throw new yn(o);function h(t){var r=e,o=i;return e=i=void 0,s=t,a=n.apply(o,r)}function d(n){return s=n,f=bo(g,t),l?h(n):a}function _(n){var r=n-c;return void 0===c||r>=t||r<0||v&&n-s>=u}function g(){var n=_u();if(_(n))return y(n);f=bo(g,function(n){var r=t-(n-c);return v?fr(r,u-(n-s)):r}(n))}function y(n){return f=void 0,p&&e?h(n):(e=i=void 0,a)}function m(){var n=_u(),r=_(n);if(e=arguments,i=this,c=n,r){if(void 0===f)return d(c);if(v)return li(f),f=bo(g,t),h(c)}return void 0===f&&(f=bo(g,t)),a}return t=ua(t)||0,$u(r)&&(l=!!r.leading,u=(v="maxWait"in r)?ar(ua(r.maxWait)||0,t):u,p="trailing"in r?!!r.trailing:p),m.cancel=function(){void 0!==f&&li(f),s=0,e=c=i=f=void 0},m.flush=function(){return void 0===f?a:y(_u())},m}var xu=De((function(n,t){return Qr(n,1,t)})),ju=De((function(n,t,r){return Qr(n,ua(t)||0,r)}));function Au(n,t){if("function"!=typeof n||null!=t&&"function"!=typeof t)throw new yn(o);var r=function(){var e=arguments,i=t?t.apply(this,e):e[0],o=r.cache;if(o.has(i))return o.get(i);var u=n.apply(this,e);return r.cache=o.set(i,u)||o,u};return r.cache=new(Au.Cache||Nr),r}function Eu(n){if("function"!=typeof n)throw new yn(o);return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}Au.Cache=Nr;var Ou=ci((function(n,t){var r=(t=1==t.length&&zu(t[0])?ht(t[0],Lt(Gi())):ht(ue(t,1),Lt(Gi()))).length;return De((function(e){for(var i=-1,o=fr(e.length,r);++i=t})),Iu=we(function(){return arguments}())?we:function(n){return Hu(n)&&An.call(n,"callee")&&!Zn.call(n,"callee")},zu=e.isArray,Uu=nt?Lt(nt):function(n){return Hu(n)&&he(n)==j};function Nu(n){return null!=n&&Fu(n.length)&&!qu(n)}function Bu(n){return Hu(n)&&Nu(n)}var Pu=er||af,Du=tt?Lt(tt):function(n){return Hu(n)&&he(n)==l};function Wu(n){if(!Hu(n))return!1;var t=he(n);return t==v||"[object DOMException]"==t||"string"==typeof n.message&&"string"==typeof n.name&&!Ku(n)}function qu(n){if(!$u(n))return!1;var t=he(n);return t==p||t==h||"[object AsyncFunction]"==t||"[object Proxy]"==t}function Mu(n){return"number"==typeof n&&n==ia(n)}function Fu(n){return"number"==typeof n&&n>-1&&n%1==0&&n<=9007199254740991}function $u(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function Hu(n){return null!=n&&"object"==typeof n}var Vu=rt?Lt(rt):function(n){return Hu(n)&&eo(n)==d};function Zu(n){return"number"==typeof n||Hu(n)&&he(n)==_}function Ku(n){if(!Hu(n)||he(n)!=g)return!1;var t=Fn(n);if(null===t)return!0;var r=An.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&&jn.call(r)==Sn}var Ju=et?Lt(et):function(n){return Hu(n)&&he(n)==y};var Xu=it?Lt(it):function(n){return Hu(n)&&eo(n)==m};function Gu(n){return"string"==typeof n||!zu(n)&&Hu(n)&&he(n)==w}function Yu(n){return"symbol"==typeof n||Hu(n)&&he(n)==b}var Qu=ot?Lt(ot):function(n){return Hu(n)&&Fu(n.length)&&!!qn[he(n)]};var na=Ui(Re),ta=Ui((function(n,t){return n<=t}));function ra(n){if(!n)return[];if(Nu(n))return Gu(n)?Kt(n):yi(n);if(Yn&&n[Yn])return function(n){for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}(n[Yn]());var t=eo(n);return(t==d?Mt:t==m?Ht:Ta)(n)}function ea(n){return n?(n=ua(n))===1/0||n===-1/0?17976931348623157e292*(n<0?-1:1):n==n?n:0:0===n?n:0}function ia(n){var t=ea(n),r=t%1;return t==t?r?t-r:t:0}function oa(n){return n?Xr(ia(n),0,4294967295):0}function ua(n){if("number"==typeof n)return n;if(Yu(n))return NaN;if($u(n)){var t="function"==typeof n.valueOf?n.valueOf():n;n=$u(t)?t+"":t}if("string"!=typeof n)return 0===n?n:+n;n=Ct(n);var r=un.test(n);return r||fn.test(n)?Hn(n.slice(2),r?2:8):on.test(n)?NaN:+n}function aa(n){return mi(n,xa(n))}function fa(n){return null==n?"":Ye(n)}var ca=bi((function(n,t){if(vo(t)||Nu(t))mi(t,ba(t),n);else for(var r in t)An.call(t,r)&&$r(n,r,t[r])})),sa=bi((function(n,t){mi(t,xa(t),n)})),la=bi((function(n,t,r,e){mi(t,xa(t),n,e)})),va=bi((function(n,t,r,e){mi(t,ba(t),n,e)})),pa=Hi(Jr);var ha=De((function(n,t){n=dn(n);var r=-1,e=t.length,i=e>2?t[2]:void 0;for(i&&fo(t[0],t[1],i)&&(e=1);++r1),t})),mi(n,Zi(n),r),e&&(r=Gr(r,7,Fi));for(var i=t.length;i--;)ni(r,t[i]);return r}));var Oa=Hi((function(n,t){return null==n?{}:function(n,t){return ze(n,t,(function(t,r){return ga(n,r)}))}(n,t)}));function Ra(n,t){if(null==n)return{};var r=ht(Zi(n),(function(n){return[n]}));return t=Gi(t),ze(n,r,(function(n,r){return t(n,r[0])}))}var Sa=Di(ba),ka=Di(xa);function Ta(n){return null==n?[]:It(n,ba(n))}var Ca=Ei((function(n,t,r){return t=t.toLowerCase(),n+(r?La(t):t)}));function La(n){return Wa(fa(n).toLowerCase())}function Ia(n){return(n=fa(n))&&n.replace(sn,Pt).replace(zn,"")}var za=Ei((function(n,t,r){return n+(r?"-":"")+t.toLowerCase()})),Ua=Ei((function(n,t,r){return n+(r?" ":"")+t.toLowerCase()})),Na=Ai("toLowerCase");var Ba=Ei((function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}));var Pa=Ei((function(n,t,r){return n+(r?" ":"")+Wa(t)}));var Da=Ei((function(n,t,r){return n+(r?" ":"")+t.toUpperCase()})),Wa=Ai("toUpperCase");function qa(n,t,r){return n=fa(n),void 0===(t=r?void 0:t)?function(n){return Pn.test(n)}(n)?function(n){return n.match(Nn)||[]}(n):function(n){return n.match(Q)||[]}(n):n.match(t)||[]}var Ma=De((function(n,t){try{return ut(n,void 0,t)}catch(n){return Wu(n)?n:new J(n)}})),Fa=Hi((function(n,t){return ft(t,(function(t){t=Ro(t),Kr(n,t,mu(n[t],n))})),n}));function $a(n){return function(){return n}}var Ha=Si(),Va=Si(!0);function Za(n){return n}function Ka(n){return Ae("function"==typeof n?n:Gr(n,1))}var Ja=De((function(n,t){return function(r){return me(r,n,t)}})),Xa=De((function(n,t){return function(r){return me(n,r,t)}}));function Ga(n,t,r){var e=ba(t),i=le(t,e);null!=r||$u(t)&&(i.length||!e.length)||(r=t,t=n,n=this,i=le(t,ba(t)));var o=!($u(r)&&"chain"in r&&!r.chain),u=qu(n);return ft(i,(function(r){var e=t[r];n[r]=e,u&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__),i=r.__actions__=yi(this.__actions__);return i.push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,dt([this.value()],arguments))})})),n}function Ya(){}var Qa=Li(ht),nf=Li(st),tf=Li(yt);function rf(n){return co(n)?Ot(Ro(n)):function(n){return function(t){return ve(t,n)}}(n)}var ef=zi(),of=zi(!0);function uf(){return[]}function af(){return!1}var ff=Ci((function(n,t){return n+t}),0),cf=Bi("ceil"),sf=Ci((function(n,t){return n/t}),1),lf=Bi("floor");var vf,pf=Ci((function(n,t){return n*t}),1),hf=Bi("round"),df=Ci((function(n,t){return n-t}),0);return kr.after=function(n,t){if("function"!=typeof t)throw new yn(o);return n=ia(n),function(){if(--n<1)return t.apply(this,arguments)}},kr.ary=gu,kr.assign=ca,kr.assignIn=sa,kr.assignInWith=la,kr.assignWith=va,kr.at=pa,kr.before=yu,kr.bind=mu,kr.bindAll=Fa,kr.bindKey=wu,kr.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return zu(n)?n:[n]},kr.chain=ru,kr.chunk=function(n,t,r){t=(r?fo(n,t,r):void 0===t)?1:ar(ia(t),0);var i=null==n?0:n.length;if(!i||t<1)return[];for(var o=0,u=0,a=e(nr(i/t));oi?0:i+r),(e=void 0===e||e>i?i:ia(e))<0&&(e+=i),e=r>e?0:oa(e);r>>0)?(n=fa(n))&&("string"==typeof t||null!=t&&!Ju(t))&&!(t=Ye(t))&&qt(n)?si(Kt(n),0,r):n.split(t,r):[]},kr.spread=function(n,t){if("function"!=typeof n)throw new yn(o);return t=null==t?0:ar(ia(t),0),De((function(r){var e=r[t],i=si(r,0,t);return e&&dt(i,e),ut(n,this,i)}))},kr.tail=function(n){var t=null==n?0:n.length;return t?Ve(n,1,t):[]},kr.take=function(n,t,r){return n&&n.length?Ve(n,0,(t=r||void 0===t?1:ia(t))<0?0:t):[]},kr.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?Ve(n,(t=e-(t=r||void 0===t?1:ia(t)))<0?0:t,e):[]},kr.takeRightWhile=function(n,t){return n&&n.length?ri(n,Gi(t,3),!1,!0):[]},kr.takeWhile=function(n,t){return n&&n.length?ri(n,Gi(t,3)):[]},kr.tap=function(n,t){return t(n),n},kr.throttle=function(n,t,r){var e=!0,i=!0;if("function"!=typeof n)throw new yn(o);return $u(r)&&(e="leading"in r?!!r.leading:e,i="trailing"in r?!!r.trailing:i),bu(n,t,{leading:e,maxWait:t,trailing:i})},kr.thru=eu,kr.toArray=ra,kr.toPairs=Sa,kr.toPairsIn=ka,kr.toPath=function(n){return zu(n)?ht(n,Ro):Yu(n)?[n]:yi(Oo(fa(n)))},kr.toPlainObject=aa,kr.transform=function(n,t,r){var e=zu(n),i=e||Pu(n)||Qu(n);if(t=Gi(t,4),null==r){var o=n&&n.constructor;r=i?e?new o:[]:$u(n)&&qu(o)?Tr(Fn(n)):{}}return(i?ft:ce)(n,(function(n,e,i){return t(r,n,e,i)})),r},kr.unary=function(n){return gu(n,1)},kr.union=Ho,kr.unionBy=Vo,kr.unionWith=Zo,kr.uniq=function(n){return n&&n.length?Qe(n):[]},kr.uniqBy=function(n,t){return n&&n.length?Qe(n,Gi(t,2)):[]},kr.uniqWith=function(n,t){return t="function"==typeof t?t:void 0,n&&n.length?Qe(n,void 0,t):[]},kr.unset=function(n,t){return null==n||ni(n,t)},kr.unzip=Ko,kr.unzipWith=Jo,kr.update=function(n,t,r){return null==n?n:ti(n,t,ai(r))},kr.updateWith=function(n,t,r,e){return e="function"==typeof e?e:void 0,null==n?n:ti(n,t,ai(r),e)},kr.values=Ta,kr.valuesIn=function(n){return null==n?[]:It(n,xa(n))},kr.without=Xo,kr.words=qa,kr.wrap=function(n,t){return Ru(ai(t),n)},kr.xor=Go,kr.xorBy=Yo,kr.xorWith=Qo,kr.zip=nu,kr.zipObject=function(n,t){return oi(n||[],t||[],$r)},kr.zipObjectDeep=function(n,t){return oi(n||[],t||[],Me)},kr.zipWith=tu,kr.entries=Sa,kr.entriesIn=ka,kr.extend=sa,kr.extendWith=la,Ga(kr,kr),kr.add=ff,kr.attempt=Ma,kr.camelCase=Ca,kr.capitalize=La,kr.ceil=cf,kr.clamp=function(n,t,r){return void 0===r&&(r=t,t=void 0),void 0!==r&&(r=(r=ua(r))==r?r:0),void 0!==t&&(t=(t=ua(t))==t?t:0),Xr(ua(n),t,r)},kr.clone=function(n){return Gr(n,4)},kr.cloneDeep=function(n){return Gr(n,5)},kr.cloneDeepWith=function(n,t){return Gr(n,5,t="function"==typeof t?t:void 0)},kr.cloneWith=function(n,t){return Gr(n,4,t="function"==typeof t?t:void 0)},kr.conformsTo=function(n,t){return null==t||Yr(n,t,ba(t))},kr.deburr=Ia,kr.defaultTo=function(n,t){return null==n||n!=n?t:n},kr.divide=sf,kr.endsWith=function(n,t,r){n=fa(n),t=Ye(t);var e=n.length,i=r=void 0===r?e:Xr(ia(r),0,e);return(r-=t.length)>=0&&n.slice(r,i)==t},kr.eq=Tu,kr.escape=function(n){return(n=fa(n))&&D.test(n)?n.replace(B,Dt):n},kr.escapeRegExp=function(n){return(n=fa(n))&&Z.test(n)?n.replace(V,"\\$&"):n},kr.every=function(n,t,r){var e=zu(n)?st:ee;return r&&fo(n,t,r)&&(t=void 0),e(n,Gi(t,3))},kr.find=uu,kr.findIndex=Io,kr.findKey=function(n,t){return wt(n,Gi(t,3),ce)},kr.findLast=au,kr.findLastIndex=zo,kr.findLastKey=function(n,t){return wt(n,Gi(t,3),se)},kr.floor=lf,kr.forEach=fu,kr.forEachRight=cu,kr.forIn=function(n,t){return null==n?n:ae(n,Gi(t,3),xa)},kr.forInRight=function(n,t){return null==n?n:fe(n,Gi(t,3),xa)},kr.forOwn=function(n,t){return n&&ce(n,Gi(t,3))},kr.forOwnRight=function(n,t){return n&&se(n,Gi(t,3))},kr.get=_a,kr.gt=Cu,kr.gte=Lu,kr.has=function(n,t){return null!=n&&io(n,t,_e)},kr.hasIn=ga,kr.head=No,kr.identity=Za,kr.includes=function(n,t,r,e){n=Nu(n)?n:Ta(n),r=r&&!e?ia(r):0;var i=n.length;return r<0&&(r=ar(i+r,0)),Gu(n)?r<=i&&n.indexOf(t,r)>-1:!!i&&xt(n,t,r)>-1},kr.indexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var i=null==r?0:ia(r);return i<0&&(i=ar(e+i,0)),xt(n,t,i)},kr.inRange=function(n,t,r){return t=ea(t),void 0===r?(r=t,t=0):r=ea(r),function(n,t,r){return n>=fr(t,r)&&n=-9007199254740991&&n<=9007199254740991},kr.isSet=Xu,kr.isString=Gu,kr.isSymbol=Yu,kr.isTypedArray=Qu,kr.isUndefined=function(n){return void 0===n},kr.isWeakMap=function(n){return Hu(n)&&eo(n)==x},kr.isWeakSet=function(n){return Hu(n)&&"[object WeakSet]"==he(n)},kr.join=function(n,t){return null==n?"":or.call(n,t)},kr.kebabCase=za,kr.last=Wo,kr.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var i=e;return void 0!==r&&(i=(i=ia(r))<0?ar(e+i,0):fr(i,e-1)),t==t?function(n,t,r){for(var e=r+1;e--;)if(n[e]===t)return e;return e}(n,t,i):bt(n,At,i,!0)},kr.lowerCase=Ua,kr.lowerFirst=Na,kr.lt=na,kr.lte=ta,kr.max=function(n){return n&&n.length?ie(n,Za,de):void 0},kr.maxBy=function(n,t){return n&&n.length?ie(n,Gi(t,2),de):void 0},kr.mean=function(n){return Et(n,Za)},kr.meanBy=function(n,t){return Et(n,Gi(t,2))},kr.min=function(n){return n&&n.length?ie(n,Za,Re):void 0},kr.minBy=function(n,t){return n&&n.length?ie(n,Gi(t,2),Re):void 0},kr.stubArray=uf,kr.stubFalse=af,kr.stubObject=function(){return{}},kr.stubString=function(){return""},kr.stubTrue=function(){return!0},kr.multiply=pf,kr.nth=function(n,t){return n&&n.length?Le(n,ia(t)):void 0},kr.noConflict=function(){return Kn._===this&&(Kn._=kn),this},kr.noop=Ya,kr.now=_u,kr.pad=function(n,t,r){n=fa(n);var e=(t=ia(t))?Zt(n):0;if(!t||e>=t)return n;var i=(t-e)/2;return Ii(tr(i),r)+n+Ii(nr(i),r)},kr.padEnd=function(n,t,r){n=fa(n);var e=(t=ia(t))?Zt(n):0;return t&&et){var e=n;n=t,t=e}if(r||n%1||t%1){var i=lr();return fr(n+i*(t-n+$n("1e-"+((i+"").length-1))),t)}return Be(n,t)},kr.reduce=function(n,t,r){var e=zu(n)?_t:St,i=arguments.length<3;return e(n,Gi(t,4),r,i,te)},kr.reduceRight=function(n,t,r){var e=zu(n)?gt:St,i=arguments.length<3;return e(n,Gi(t,4),r,i,re)},kr.repeat=function(n,t,r){return t=(r?fo(n,t,r):void 0===t)?1:ia(t),Pe(fa(n),t)},kr.replace=function(){var n=arguments,t=fa(n[0]);return n.length<3?t:t.replace(n[1],n[2])},kr.result=function(n,t,r){var e=-1,i=(t=fi(t,n)).length;for(i||(i=1,n=void 0);++e9007199254740991)return[];var r=4294967295,e=fr(n,4294967295);n-=4294967295;for(var i=Tt(e,t=Gi(t));++r=o)return n;var a=r-Zt(e);if(a<1)return e;var f=u?si(u,0,a).join(""):n.slice(0,a);if(void 0===i)return f+e;if(u&&(a+=f.length-a),Ju(i)){if(n.slice(a).search(i)){var c,s=f;for(i.global||(i=_n(i.source,fa(en.exec(i))+"g")),i.lastIndex=0;c=i.exec(s);)var l=c.index;f=f.slice(0,void 0===l?a:l)}}else if(n.indexOf(Ye(i),a)!=a){var v=f.lastIndexOf(i);v>-1&&(f=f.slice(0,v))}return f+e},kr.unescape=function(n){return(n=fa(n))&&P.test(n)?n.replace(N,Xt):n},kr.uniqueId=function(n){var t=++En;return fa(n)+t},kr.upperCase=Da,kr.upperFirst=Wa,kr.each=fu,kr.eachRight=cu,kr.first=No,Ga(kr,(vf={},ce(kr,(function(n,t){An.call(kr.prototype,t)||(vf[t]=n)})),vf),{chain:!1}),kr.VERSION="4.17.21",ft(["bind","bindKey","curry","curryRight","partial","partialRight"],(function(n){kr[n].placeholder=kr})),ft(["drop","take"],(function(n,t){Ir.prototype[n]=function(r){r=void 0===r?1:ar(ia(r),0);var e=this.__filtered__&&!t?new Ir(this):this.clone();return e.__filtered__?e.__takeCount__=fr(r,e.__takeCount__):e.__views__.push({size:fr(r,4294967295),type:n+(e.__dir__<0?"Right":"")}),e},Ir.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}})),ft(["filter","map","takeWhile"],(function(n,t){var r=t+1,e=1==r||3==r;Ir.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:Gi(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}})),ft(["head","last"],(function(n,t){var r="take"+(t?"Right":"");Ir.prototype[n]=function(){return this[r](1).value()[0]}})),ft(["initial","tail"],(function(n,t){var r="drop"+(t?"":"Right");Ir.prototype[n]=function(){return this.__filtered__?new Ir(this):this[r](1)}})),Ir.prototype.compact=function(){return this.filter(Za)},Ir.prototype.find=function(n){return this.filter(n).head()},Ir.prototype.findLast=function(n){return this.reverse().find(n)},Ir.prototype.invokeMap=De((function(n,t){return"function"==typeof n?new Ir(this):this.map((function(r){return me(r,n,t)}))})),Ir.prototype.reject=function(n){return this.filter(Eu(Gi(n)))},Ir.prototype.slice=function(n,t){n=ia(n);var r=this;return r.__filtered__&&(n>0||t<0)?new Ir(r):(n<0?r=r.takeRight(-n):n&&(r=r.drop(n)),void 0!==t&&(r=(t=ia(t))<0?r.dropRight(-t):r.take(t-n)),r)},Ir.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Ir.prototype.toArray=function(){return this.take(4294967295)},ce(Ir.prototype,(function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),i=kr[e?"take"+("last"==t?"Right":""):t],o=e||/^find/.test(t);i&&(kr.prototype[t]=function(){var t=this.__wrapped__,u=e?[1]:arguments,a=t instanceof Ir,f=u[0],c=a||zu(t),s=function(n){var t=i.apply(kr,dt([n],u));return e&&l?t[0]:t};c&&r&&"function"==typeof f&&1!=f.length&&(a=c=!1);var l=this.__chain__,v=!!this.__actions__.length,p=o&&!l,h=a&&!v;if(!o&&c){t=h?t:new Ir(this);var d=n.apply(t,u);return d.__actions__.push({func:eu,args:[s],thisArg:void 0}),new Lr(d,l)}return p&&h?n.apply(this,u):(d=this.thru(s),p?e?d.value()[0]:d.value():d)})})),ft(["pop","push","shift","sort","splice","unshift"],(function(n){var t=mn[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);kr.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var i=this.value();return t.apply(zu(i)?i:[],n)}return this[r]((function(r){return t.apply(zu(r)?r:[],n)}))}})),ce(Ir.prototype,(function(n,t){var r=kr[t];if(r){var e=r.name+"";An.call(wr,e)||(wr[e]=[]),wr[e].push({name:t,func:r})}})),wr[ki(void 0,2).name]=[{name:"wrapper",func:void 0}],Ir.prototype.clone=function(){var n=new Ir(this.__wrapped__);return n.__actions__=yi(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=yi(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=yi(this.__views__),n},Ir.prototype.reverse=function(){if(this.__filtered__){var n=new Ir(this);n.__dir__=-1,n.__filtered__=!0}else(n=this.clone()).__dir__*=-1;return n},Ir.prototype.value=function(){var n=this.__wrapped__.value(),t=this.__dir__,r=zu(n),e=t<0,i=r?n.length:0,o=function(n,t,r){var e=-1,i=r.length;for(;++e=this.__values__.length;return{done:n,value:n?void 0:this.__values__[this.__index__++]}},kr.prototype.plant=function(n){for(var t,r=this;r instanceof Cr;){var e=ko(r);e.__index__=0,e.__values__=void 0,t?i.__wrapped__=e:t=e;var i=e;r=r.__wrapped__}return i.__wrapped__=n,t},kr.prototype.reverse=function(){var n=this.__wrapped__;if(n instanceof Ir){var t=n;return this.__actions__.length&&(t=new Ir(this)),(t=t.reverse()).__actions__.push({func:eu,args:[$o],thisArg:void 0}),new Lr(t,this.__chain__)}return this.thru($o)},kr.prototype.toJSON=kr.prototype.valueOf=kr.prototype.value=function(){return ei(this.__wrapped__,this.__actions__)},kr.prototype.first=kr.prototype.head,Yn&&(kr.prototype[Yn]=function(){return this}),kr}();Kn._=Gt,void 0===(i=function(){return Gt}.call(t,r,t,e))||(e.exports=i)}).call(this)}).call(this,r(13),r(14)(n))},function(n,t){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(n){"object"==typeof window&&(r=window)}n.exports=r},function(n,t){n.exports=function(n){return n.webpackPolyfill||(n.deprecate=function(){},n.paths=[],n.children||(n.children=[]),Object.defineProperty(n,"loaded",{enumerable:!0,get:function(){return n.l}}),Object.defineProperty(n,"id",{enumerable:!0,get:function(){return n.i}}),n.webpackPolyfill=1),n}},function(n,t,r){n.exports=r(16)},function(n,t,r){"use strict";var e=r(0),i=r(1),o=r(17),u=r(7);function a(n){var t=new o(n),r=i(o.prototype.request,t);return e.extend(r,o.prototype,t),e.extend(r,t),r}var f=a(r(4));f.Axios=o,f.create=function(n){return a(u(f.defaults,n))},f.Cancel=r(8),f.CancelToken=r(31),f.isCancel=r(3),f.all=function(n){return Promise.all(n)},f.spread=r(32),n.exports=f,n.exports.default=f},function(n,t,r){"use strict";var e=r(0),i=r(2),o=r(18),u=r(19),a=r(7);function f(n){this.defaults=n,this.interceptors={request:new o,response:new o}}f.prototype.request=function(n){"string"==typeof n?(n=arguments[1]||{}).url=arguments[0]:n=n||{},(n=a(this.defaults,n)).method?n.method=n.method.toLowerCase():this.defaults.method?n.method=this.defaults.method.toLowerCase():n.method="get";var t=[u,void 0],r=Promise.resolve(n);for(this.interceptors.request.forEach((function(n){t.unshift(n.fulfilled,n.rejected)})),this.interceptors.response.forEach((function(n){t.push(n.fulfilled,n.rejected)}));t.length;)r=r.then(t.shift(),t.shift());return r},f.prototype.getUri=function(n){return n=a(this.defaults,n),i(n.url,n.params,n.paramsSerializer).replace(/^\?/,"")},e.forEach(["delete","get","head","options"],(function(n){f.prototype[n]=function(t,r){return this.request(e.merge(r||{},{method:n,url:t}))}})),e.forEach(["post","put","patch"],(function(n){f.prototype[n]=function(t,r,i){return this.request(e.merge(i||{},{method:n,url:t,data:r}))}})),n.exports=f},function(n,t,r){"use strict";var e=r(0);function i(){this.handlers=[]}i.prototype.use=function(n,t){return this.handlers.push({fulfilled:n,rejected:t}),this.handlers.length-1},i.prototype.eject=function(n){this.handlers[n]&&(this.handlers[n]=null)},i.prototype.forEach=function(n){e.forEach(this.handlers,(function(t){null!==t&&n(t)}))},n.exports=i},function(n,t,r){"use strict";var e=r(0),i=r(20),o=r(3),u=r(4);function a(n){n.cancelToken&&n.cancelToken.throwIfRequested()}n.exports=function(n){return a(n),n.headers=n.headers||{},n.data=i(n.data,n.headers,n.transformRequest),n.headers=e.merge(n.headers.common||{},n.headers[n.method]||{},n.headers),e.forEach(["delete","get","head","post","put","patch","common"],(function(t){delete n.headers[t]})),(n.adapter||u.adapter)(n).then((function(t){return a(n),t.data=i(t.data,t.headers,n.transformResponse),t}),(function(t){return o(t)||(a(n),t&&t.response&&(t.response.data=i(t.response.data,t.response.headers,n.transformResponse))),Promise.reject(t)}))}},function(n,t,r){"use strict";var e=r(0);n.exports=function(n,t,r){return e.forEach(r,(function(r){n=r(n,t)})),n}},function(n,t){var r,e,i=n.exports={};function o(){throw new Error("setTimeout has not been defined")}function u(){throw new Error("clearTimeout has not been defined")}function a(n){if(r===setTimeout)return setTimeout(n,0);if((r===o||!r)&&setTimeout)return r=setTimeout,setTimeout(n,0);try{return r(n,0)}catch(t){try{return r.call(null,n,0)}catch(t){return r.call(this,n,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:o}catch(n){r=o}try{e="function"==typeof clearTimeout?clearTimeout:u}catch(n){e=u}}();var f,c=[],s=!1,l=-1;function v(){s&&f&&(s=!1,f.length?c=f.concat(c):l=-1,c.length&&p())}function p(){if(!s){var n=a(v);s=!0;for(var t=c.length;t;){for(f=c,c=[];++l1)for(var r=1;r=0)return;u[t]="set-cookie"===t?(u[t]?u[t]:[]).concat([r]):u[t]?u[t]+", "+r:r}})),u):u}},function(n,t,r){"use strict";var e=r(0);n.exports=e.isStandardBrowserEnv()?function(){var n,t=/(msie|trident)/i.test(navigator.userAgent),r=document.createElement("a");function i(n){var e=n;return t&&(r.setAttribute("href",e),e=r.href),r.setAttribute("href",e),{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,""):"",host:r.host,search:r.search?r.search.replace(/^\?/,""):"",hash:r.hash?r.hash.replace(/^#/,""):"",hostname:r.hostname,port:r.port,pathname:"/"===r.pathname.charAt(0)?r.pathname:"/"+r.pathname}}return n=i(window.location.href),function(t){var r=e.isString(t)?i(t):t;return r.protocol===n.protocol&&r.host===n.host}}():function(){return!0}},function(n,t,r){"use strict";var e=r(0);n.exports=e.isStandardBrowserEnv()?{write:function(n,t,r,i,o,u){var a=[];a.push(n+"="+encodeURIComponent(t)),e.isNumber(r)&&a.push("expires="+new Date(r).toGMTString()),e.isString(i)&&a.push("path="+i),e.isString(o)&&a.push("domain="+o),!0===u&&a.push("secure"),document.cookie=a.join("; ")},read:function(n){var t=document.cookie.match(new RegExp("(^|;\\s*)("+n+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(n){this.write(n,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}}},function(n,t,r){"use strict";var e=r(8);function i(n){if("function"!=typeof n)throw new TypeError("executor must be a function.");var t;this.promise=new Promise((function(n){t=n}));var r=this;n((function(n){r.reason||(r.reason=new e(n),t(r.reason))}))}i.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},i.source=function(){var n;return{token:new i((function(t){n=t})),cancel:n}},n.exports=i},function(n,t,r){"use strict";n.exports=function(n){return function(t){return n.apply(null,t)}}},function(n,t){}]); \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index dcda59a..766de6b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -94,10 +94,12 @@ return response()->json(['status' => 'ok']); // Or a more detailed status }); -Route::prefix('v1')->group(function () { +Route::group(['middleware' => 'ApiAuth', 'prefix' => 'v1'], function () { + Route::get('org/{code}/whatnow', '\\App\\Legacy\\Http\\Controllers\\WhatNowController@getFeed'); + Route::any('{any}', function () { return response()->json([ - 'error' => 'API version v1 is no longer supported. Please use /v2/.' + 'error' => 'API version v1 is no longer supported. Please use /v2.' ], 410); })->where('any', '.*'); });