rkljw 3 ngày trước cách đây
mục cha
commit
558bc6fbab
100 tập tin đã thay đổi với 16703 bổ sung23 xóa
  1. 335 0
      app/JsonRpc/NewsService.php
  2. 16 0
      app/JsonRpc/NewsServiceInterface.php
  3. 22 0
      app/Model/Character.php
  4. 22 0
      app/Model/Couplet.php
  5. 22 0
      app/Model/Festival.php
  6. 22 0
      app/Model/HistoryToday.php
  7. 22 0
      app/Model/Idiom.php
  8. 22 0
      app/Model/Riddle.php
  9. 1 0
      composer.json
  10. 445 1
      composer.lock
  11. 19 19
      config/autoload/cache.php
  12. 0 0
      runtime/container/classes.cache
  13. 1 1
      runtime/hyperf.pid
  14. 287 0
      vendor/composer/autoload_classmap.php
  15. 2 0
      vendor/composer/autoload_files.php
  16. 4 0
      vendor/composer/autoload_psr4.php
  17. 318 0
      vendor/composer/autoload_static.php
  18. 465 0
      vendor/composer/installed.json
  19. 71 2
      vendor/composer/installed.php
  20. 126 0
      vendor/illuminate/cache/ApcStore.php
  21. 94 0
      vendor/illuminate/cache/ApcWrapper.php
  22. 106 0
      vendor/illuminate/cache/ArrayLock.php
  23. 219 0
      vendor/illuminate/cache/ArrayStore.php
  24. 85 0
      vendor/illuminate/cache/CacheLock.php
  25. 431 0
      vendor/illuminate/cache/CacheManager.php
  26. 52 0
      vendor/illuminate/cache/CacheServiceProvider.php
  27. 44 0
      vendor/illuminate/cache/Console/CacheTableCommand.php
  28. 147 0
      vendor/illuminate/cache/Console/ClearCommand.php
  29. 59 0
      vendor/illuminate/cache/Console/ForgetCommand.php
  30. 60 0
      vendor/illuminate/cache/Console/PruneStaleTagsCommand.php
  31. 35 0
      vendor/illuminate/cache/Console/stubs/cache.stub
  32. 156 0
      vendor/illuminate/cache/DatabaseLock.php
  33. 419 0
      vendor/illuminate/cache/DatabaseStore.php
  34. 77 0
      vendor/illuminate/cache/DynamoDbLock.php
  35. 546 0
      vendor/illuminate/cache/DynamoDbStore.php
  36. 46 0
      vendor/illuminate/cache/Events/CacheEvent.php
  37. 28 0
      vendor/illuminate/cache/Events/CacheHit.php
  38. 8 0
      vendor/illuminate/cache/Events/CacheMissed.php
  39. 8 0
      vendor/illuminate/cache/Events/KeyForgotten.php
  40. 37 0
      vendor/illuminate/cache/Events/KeyWritten.php
  41. 16 0
      vendor/illuminate/cache/FileLock.php
  42. 405 0
      vendor/illuminate/cache/FileStore.php
  43. 31 0
      vendor/illuminate/cache/HasCacheLock.php
  44. 21 0
      vendor/illuminate/cache/LICENSE.md
  45. 168 0
      vendor/illuminate/cache/Lock.php
  46. 25 0
      vendor/illuminate/cache/LuaScripts.php
  47. 87 0
      vendor/illuminate/cache/MemcachedConnector.php
  48. 75 0
      vendor/illuminate/cache/MemcachedLock.php
  49. 279 0
      vendor/illuminate/cache/MemcachedStore.php
  50. 46 0
      vendor/illuminate/cache/NoLock.php
  51. 126 0
      vendor/illuminate/cache/NullStore.php
  52. 35 0
      vendor/illuminate/cache/PhpRedisLock.php
  53. 238 0
      vendor/illuminate/cache/RateLimiter.php
  54. 18 0
      vendor/illuminate/cache/RateLimiting/GlobalLimit.php
  55. 132 0
      vendor/illuminate/cache/RateLimiting/Limit.php
  56. 16 0
      vendor/illuminate/cache/RateLimiting/Unlimited.php
  57. 83 0
      vendor/illuminate/cache/RedisLock.php
  58. 419 0
      vendor/illuminate/cache/RedisStore.php
  59. 125 0
      vendor/illuminate/cache/RedisTagSet.php
  60. 141 0
      vendor/illuminate/cache/RedisTaggedCache.php
  61. 704 0
      vendor/illuminate/cache/Repository.php
  62. 49 0
      vendor/illuminate/cache/RetrievesMultipleKeys.php
  63. 130 0
      vendor/illuminate/cache/TagSet.php
  64. 19 0
      vendor/illuminate/cache/TaggableStore.php
  65. 125 0
      vendor/illuminate/cache/TaggedCache.php
  66. 49 0
      vendor/illuminate/cache/composer.json
  67. 939 0
      vendor/illuminate/collections/Arr.php
  68. 1821 0
      vendor/illuminate/collections/Collection.php
  69. 1263 0
      vendor/illuminate/collections/Enumerable.php
  70. 63 0
      vendor/illuminate/collections/HigherOrderCollectionProxy.php
  71. 9 0
      vendor/illuminate/collections/ItemNotFoundException.php
  72. 21 0
      vendor/illuminate/collections/LICENSE.md
  73. 1785 0
      vendor/illuminate/collections/LazyCollection.php
  74. 40 0
      vendor/illuminate/collections/MultipleItemsFoundException.php
  75. 1152 0
      vendor/illuminate/collections/Traits/EnumeratesValues.php
  76. 42 0
      vendor/illuminate/collections/composer.json
  77. 226 0
      vendor/illuminate/collections/helpers.php
  78. 109 0
      vendor/illuminate/conditionable/HigherOrderWhenProxy.php
  79. 21 0
      vendor/illuminate/conditionable/LICENSE.md
  80. 73 0
      vendor/illuminate/conditionable/Traits/Conditionable.php
  81. 33 0
      vendor/illuminate/conditionable/composer.json
  82. 15 0
      vendor/illuminate/contracts/Auth/Access/Authorizable.php
  83. 150 0
      vendor/illuminate/contracts/Auth/Access/Gate.php
  84. 49 0
      vendor/illuminate/contracts/Auth/Authenticatable.php
  85. 21 0
      vendor/illuminate/contracts/Auth/CanResetPassword.php
  86. 22 0
      vendor/illuminate/contracts/Auth/Factory.php
  87. 57 0
      vendor/illuminate/contracts/Auth/Guard.php
  88. 8 0
      vendor/illuminate/contracts/Auth/Middleware/AuthenticatesRequests.php
  89. 34 0
      vendor/illuminate/contracts/Auth/MustVerifyEmail.php
  90. 61 0
      vendor/illuminate/contracts/Auth/PasswordBroker.php
  91. 14 0
      vendor/illuminate/contracts/Auth/PasswordBrokerFactory.php
  92. 63 0
      vendor/illuminate/contracts/Auth/StatefulGuard.php
  93. 24 0
      vendor/illuminate/contracts/Auth/SupportsBasicAuth.php
  94. 49 0
      vendor/illuminate/contracts/Auth/UserProvider.php
  95. 35 0
      vendor/illuminate/contracts/Broadcasting/Broadcaster.php
  96. 14 0
      vendor/illuminate/contracts/Broadcasting/Factory.php
  97. 20 0
      vendor/illuminate/contracts/Broadcasting/HasBroadcastChannel.php
  98. 8 0
      vendor/illuminate/contracts/Broadcasting/ShouldBeUnique.php
  99. 13 0
      vendor/illuminate/contracts/Broadcasting/ShouldBroadcast.php
  100. 8 0
      vendor/illuminate/contracts/Broadcasting/ShouldBroadcastNow.php

+ 335 - 0
app/JsonRpc/NewsService.php

@@ -5,6 +5,7 @@ namespace App\JsonRpc;
 use App\Model\Article;
 use App\Model\ArticleData;
 use App\Model\Category;
+use App\Model\HistoryToday;
 use App\Model\WebsiteCategory;
 use App\Model\ArticleSurvey;
 use App\Model\District;
@@ -51,6 +52,13 @@ use App\Model\JobApply;
 use App\Model\JobHunting;
 use App\Model\JobRemuse;
 
+use App\Model\Festival;
+use App\Model\Character;
+use App\Model\Couplet;
+use App\Model\Riddle;
+use App\Model\Idiom;
+use Illuminate\Support\Facades\Cache;
+
 #[RpcService(name: "NewsService", protocol: "jsonrpc-http", server: "jsonrpc-http")]
 class NewsService implements NewsServiceInterface
 {
@@ -5118,4 +5126,331 @@ class NewsService implements NewsServiceInterface
     }
 
     //20250422  书刊音像
+
+    /**
+     * 贴身宝贝
+     * @param array $data
+     * @return array
+     */
+    public function getWebsiteTsbb(array $data): array
+    {
+        $month = $data['month'] ?? date('m');
+        $day = $data['day'] ?? date('d');
+        
+        // 使用缓存键
+        $cacheKey = "tsbb_data_{$month}_{$day}";
+        
+        // 尝试从缓存获取数据
+        $container = \Hyperf\Context\ApplicationContext::getContainer();
+        $cache = $container->get(\Psr\SimpleCache\CacheInterface::class);
+        
+        if ($cachedData = $cache->get($cacheKey)) {
+            return Result::success(unserialize($cachedData));
+        }
+        
+        //查询老黄历
+        try {
+         
+            $date = date('Y-m-d');
+            $almanacUrl = "https://www.36jxs.com/api/Commonweal/almanac?sun=" . $date;
+            // 使用 curl 替代 file_get_contents
+            $ch = curl_init();
+            curl_setopt($ch, CURLOPT_URL, $almanacUrl);
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36');
+            curl_setopt($ch, CURLOPT_HTTPHEADER, [
+                'Accept: application/json',
+                'Content-Type: application/json',
+                'Referer: https://www.36jxs.com/'
+            ]);
+            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+            curl_setopt($ch, CURLOPT_ENCODING, '');
+            
+            $almanacResponse = curl_exec($ch);
+            var_dump("====:",$almanacResponse);
+            
+            if (curl_errno($ch)) {
+                var_dump('Curl error:', curl_error($ch));
+                throw new \Exception('Curl error: ' . curl_error($ch));
+            }
+            
+            // $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+            
+            curl_close($ch);
+            
+            if ($almanacResponse === false) {
+                throw new \Exception('Failed to fetch almanac data');
+            }
+            $almanacData = json_decode($almanacResponse, true);
+            if (json_last_error() !== JSON_ERROR_NONE) {
+                throw new \Exception('Failed to parse almanac data');
+            }
+            $almanacInfo = $almanacData['data'] ?? [];
+        } catch (\Exception $e) {
+            var_dump('Exception:', $e->getMessage());
+            $almanacInfo = [];
+        }
+        
+        // 获取历史上的今天数据
+        $historyTodayList = HistoryToday::whereRaw("DATE_FORMAT(year, '%m') = ?", [$month])
+            ->whereRaw("DATE_FORMAT(year, '%d') = ?", [$day])
+            ->orderBy('year', 'asc')
+            ->select("title", "id", "year", DB::raw('1 as type'))
+            ->limit(16)
+            ->get();
+
+        // 获取节日数据 - 从今天开始获取未来4条
+        $festivalList = Festival::whereRaw("DATE_FORMAT(showtime, '%m-%d') >= ?", [$month . '-' . $day])
+            ->orderBy('showtime', 'asc')
+            ->select("title", "id", "showtime", DB::raw('2 as type'))
+            ->limit(16)
+            ->get();
+        //说文解字
+        $chartacterList = Character::orderBy('updated_at', 'desc')
+            ->select("id", "title", "duyin", "bushou", "bihua",DB::raw('3 as type'))
+            ->limit(6)
+            ->get();
+        //谜语沙龙
+        $riddletList = Riddle::orderBy('updated_at', 'desc')
+            ->select("id", "riddle_title", "riddle_bottom","prompt",DB::raw('4 as type'))
+            ->limit(4)
+            ->get();
+        //成语欣赏
+        $idiomList = Idiom::orderBy('updated_at', 'desc')
+            ->select("id", "title", "duyin",DB::raw('5 as type'))
+            ->limit(32)
+            ->get();
+        //名联赏析
+        $coupletList = Couplet::orderBy('updated_at', 'desc')
+            ->select("id", "first", "second",DB::raw('6 as type'))
+            ->limit(6)
+            ->get();
+        // 获取分类文章数据
+        $categoryIds = [627,628,629,630,631,632,633,634,635,636];
+        
+        // 使用子查询优化
+        $articlesList = DB::table('article')
+            ->select([
+                'article.id',
+                'article.title',
+                'article.imgurl',
+                'article.created_at',
+                'category.name as category_name',
+                'category.id as category_id',
+                DB::raw('100 as type')
+            ])
+            ->join('category', 'article.catid', '=', 'category.id')
+            ->where('article.status', 1)
+            ->whereIn('category.id', $categoryIds)
+            // ->whereRaw('article.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)')
+            ->orderBy('article.created_at', 'desc')
+            ->get()
+            ->groupBy('category_id')
+            ->map(function ($group) {
+                // 确保第一条数据有图片
+                $firstWithImage = $group->first(function ($item) {
+                    return !empty($item->imgurl);
+                });
+                
+                if ($firstWithImage) {
+                    // 如果有带图片的文章,将其放在第一位
+                    $group = $group->filter(function ($item) use ($firstWithImage) {
+                        return $item->id !== $firstWithImage->id;
+                    })->prepend($firstWithImage);
+                }
+                
+                return [
+                    'category_name' => $group->first()->category_name,
+                    'catid' => $group->first()->category_id,
+                    'type'=>100,
+                    'list' => $group->take(6)->map(function ($item) {
+                        return [
+                            'id' => $item->id,
+                            'title' => $item->title,
+                            'imgurl' => $item->imgurl,
+                            'created_at' => $item->created_at
+                        ];
+                    })->values()
+                ];
+            })
+            ->values()
+            ->toArray();
+
+        $result = [
+            // 'almanac' => $almanacInfo,
+            'historyTodayList' => [
+                'category_name' => '历史上的今天',
+                'list' => $historyTodayList,
+                'type' => 1
+            ],
+            'festivalList' => [
+                'category_name' => '节日',
+                'list' => $festivalList,
+                'type' => 2
+            ],
+            'chartacterList' => [
+                'category_name' => '说文解字',
+                'list' => $chartacterList,
+                'type' => 3
+            ],
+            'coupletList' => [
+                'category_name' => '名联赏析',
+                'list' => $coupletList,
+                'type' => 6
+            ],
+            'riddletList' => [
+                'category_name' => '谜语沙龙',
+                'list' => $riddletList,
+                'type' => 4
+            ],
+            'idiomList' => [
+                'category_name' => '成语欣赏',
+                'list' => $idiomList,
+                'type' => 5
+            ],
+            'articlesList' => $articlesList
+        ];
+
+        // 缓存结果,设置1小时过期
+        $cache->set($cacheKey, serialize($result), 3600);
+
+        return Result::success($result);
+    }
+    /**
+     * 获取资讯列表
+     */
+    public function getWebsiteTsbbList(array $data): array
+    {
+        $page = $data['page'] ?? 1;
+        $pageSize = $data['pageSize'] ?? 10;
+        
+        // 如果没有传入月份和日期,则使用今天的日期
+        $month = $data['month'] ?? date('m');
+        $day = $data['day'] ?? date('d');
+        $total = 0;
+        $result = [];
+        $data['type'] = intval($data['type']);
+        var_dump("接收参数:",$data);
+        switch ($data['type']) {
+            case 1:
+                $query = HistoryToday::where(function($q) use ($month, $day) {
+                    // 当前月份之后的数据
+                    $q->whereRaw("DATE_FORMAT(year, '%m') > ?", [$month])
+                    // 或者当前月份且日期大于等于当前日期的数据
+                    ->orWhere(function($q) use ($month, $day) {
+                        $q->whereRaw("DATE_FORMAT(year, '%m') = ?", [$month])
+                          ->whereRaw("DATE_FORMAT(year, '%d') >= ?", [$day]);
+                    });
+                })
+                ->orderByRaw("DATE_FORMAT(year, '%m') ASC, DATE_FORMAT(year, '%d') ASC, year ASC");
+                
+                $total = $query->count();
+                $result = $query->select("title", "id", "year","updated_at", DB::raw('1 as type'))
+                    ->offset(($page - 1) * $pageSize)
+                    ->limit($pageSize)
+                    ->get();
+                break;
+            case 2:
+                $query = Festival::where(function($q) use ($month, $day) {
+                    // 当前月份之后或者当前月份且日期大于等于当前日期的数据
+                    $q->whereRaw("DATE_FORMAT(showtime, '%m') > ?", [$month])
+                    ->orWhere(function($q) use ($month, $day) {
+                        $q->whereRaw("DATE_FORMAT(showtime, '%m') = ?", [$month])
+                          ->whereRaw("DATE_FORMAT(showtime, '%d') >= ?", [$day]);
+                    });
+                })->orderByRaw("DATE_FORMAT(showtime, '%m') ASC, DATE_FORMAT(year, '%d') ASC, year ASC");
+                $total = $query->count();
+                $result = $query->select("title", "id","updated_at", "showtime", DB::raw('2 as type'))
+                    ->offset(($page - 1) * $pageSize)
+                    ->limit($pageSize)
+                    ->get();
+                break;
+            case 3:
+                $query = Character::orderBy("updated_at",  "desc");
+                $total = $query->count();
+                $result = $query->select("title", "id","updated_at", DB::raw('3 as type'))
+                    ->offset(($page - 1) * $pageSize)
+                    ->limit($pageSize)
+                    ->get();
+                break;
+            case 4:
+                $query = Riddle::orderBy("updated_at",  "desc");
+                $total = $query->count();
+                $result = $query->select("riddle_title as title","updated_at", "id", DB::raw('4 as type'))
+                    ->offset(($page - 1) * $pageSize)
+                    ->limit($pageSize)
+                    ->get();
+                break;
+            case 5:
+                $query = Idiom::orderBy("updated_at",  "desc");
+                $total = $query->count();
+                $result = $query->select("title", "id","updated_at", DB::raw('5 as type'))
+                    ->offset(($page - 1) * $pageSize)
+                    ->limit($pageSize)
+                    ->get();
+                break;
+            case 6:
+                $query = Couplet::orderBy("updated_at",  "desc");
+                $total = $query->count();
+                $result = $query->select("first as title","updated_at", "id", DB::raw('6 as type'))
+                    ->offset(($page - 1) * $pageSize)
+                    ->limit($pageSize)
+                    ->get();
+                break;
+            default:
+                $query = Article::where(['catid'=>$data['catid']])->orderBy("updated_at",  "desc");
+                $total = $query->count();
+                $result = $query->select("title", "id","updated_at", DB::raw('100 as type'))
+                    ->offset(($page - 1) * $pageSize)
+                    ->limit($pageSize)
+                    ->get();
+        }
+        return Result::success([
+            'list' => $result,
+            'total' => $total,
+            'page' => (int)$page,
+            'pageSize' => (int)$pageSize,
+            'month' => $month,
+            'day' => $day
+        ]);
+
+    }
+    /**
+     * 1:历史上的今天
+     * 2:节日
+     * 3:文章
+     *
+     * 资讯详情信息
+     */
+    public function getWebsiteTsbbDetail(array $data): array
+    {
+        $data['type'] = intval($data['type']);
+        switch ($data['type']) {
+            case 1:
+                $result = HistoryToday::where("id", $data['id'])->first();
+                break;
+            case 2:
+                $result = Festival::where("id", $data['id'])->first();
+                break;
+            case 3:
+                $result = Character::where("id", $data['id'])->first();
+                break;
+            case 4:
+                $result = Riddle::where("id", $data['id'])->first();
+                break;
+            case 5:
+                $result = Idiom::where("id", $data['id'])->first();
+                break;
+            case 6:
+                $result = Couplet::where("id", $data['id'])->first();
+                break;
+            default:
+                $result = Article::where("id", $data['id'])->select("article.*","article_data.content")->leftJoin("article_data", "article.id", "=", "article_data.article_id")->first();
+                break;
+        }
+        return Result::success($result);
+    }
 }

+ 16 - 0
app/JsonRpc/NewsServiceInterface.php

@@ -379,4 +379,20 @@ interface NewsServiceInterface
      * @return array
      */
     public function getWebsiteJobSelect(array $data):array;
+
+    /**
+     * @param array $data
+     * @return array
+     */
+    public function getWebsiteTsbb(array $data):array;
+    /**
+     *  @param array $data
+     *  @return array
+     */
+    public function getWebsiteTsbbList(array $data):array;
+    /**
+     *      @param array $data
+     *      @return array
+     */
+    public function getWebsiteTsbbDetail(array $data):array;
 }

+ 22 - 0
app/Model/Character.php

@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Model;
+
+use Hyperf\DbConnection\Model\Model;
+
+/**
+ */
+class Character extends Model
+{
+    /**
+     * The table associated with the model.
+     */
+    protected ?string $table = 'character';
+
+    /**
+     * The attributes that should be cast to native types.
+     */
+    protected array $casts = [];
+}

+ 22 - 0
app/Model/Couplet.php

@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Model;
+
+use Hyperf\DbConnection\Model\Model;
+
+/**
+ */
+class Couplet extends Model
+{
+    /**
+     * The table associated with the model.
+     */
+    protected ?string $table = 'couplet';
+
+    /**
+     * The attributes that should be cast to native types.
+     */
+    protected array $casts = [];
+}

+ 22 - 0
app/Model/Festival.php

@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Model;
+
+use Hyperf\DbConnection\Model\Model;
+
+/**
+ */
+class Festival extends Model
+{
+    /**
+     * The table associated with the model.
+     */
+    protected ?string $table = 'festival';
+
+    /**
+     * The attributes that should be cast to native types.
+     */
+    protected array $casts = [];
+}

+ 22 - 0
app/Model/HistoryToday.php

@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Model;
+
+use Hyperf\DbConnection\Model\Model;
+
+/**
+ */
+class HistoryToday extends Model
+{
+    /**
+     * The table associated with the model.
+     */
+    protected ?string $table = 'history_today';
+
+    /**
+     * The attributes that should be cast to native types.
+     */
+    protected array $casts = [];
+}

+ 22 - 0
app/Model/Idiom.php

@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Model;
+
+use Hyperf\DbConnection\Model\Model;
+
+/**
+ */
+class Idiom extends Model
+{
+    /**
+     * The table associated with the model.
+     */
+    protected ?string $table = 'idiom';
+
+    /**
+     * The attributes that should be cast to native types.
+     */
+    protected array $casts = [];
+}

+ 22 - 0
app/Model/Riddle.php

@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Model;
+
+use Hyperf\DbConnection\Model\Model;
+
+/**
+ */
+class Riddle extends Model
+{
+    /**
+     * The table associated with the model.
+     */
+    protected ?string $table = 'riddle';
+
+    /**
+     * The attributes that should be cast to native types.
+     */
+    protected array $casts = [];
+}

+ 1 - 0
composer.json

@@ -40,6 +40,7 @@
         "hyperf/service-governance-nacos": "^3.1",
         "hyperf/snowflake": "^3.1",
         "hyperf/utils": "^3.1",
+        "illuminate/cache": "^10.48",
         "ramsey/uuid": "^4.7"
     },
     "require-dev": {

+ 445 - 1
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "1f3e4f9eb6cb2b59a5b4e2acc6bc716e",
+    "content-hash": "a149cd206ffadfdf51d80918d612c3fa",
     "packages": [
         {
             "name": "brick/math",
@@ -4462,6 +4462,370 @@
             ],
             "time": "2023-11-24T03:10:53+00:00"
         },
+        {
+            "name": "illuminate/cache",
+            "version": "v10.48.28",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/cache.git",
+                "reference": "20f36c3209107ee5c8c646f88a0562a2c1b05a6c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/cache/zipball/20f36c3209107ee5c8c646f88a0562a2c1b05a6c",
+                "reference": "20f36c3209107ee5c8c646f88a0562a2c1b05a6c",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "illuminate/collections": "^10.0",
+                "illuminate/contracts": "^10.0",
+                "illuminate/macroable": "^10.0",
+                "illuminate/support": "^10.0",
+                "php": "^8.1"
+            },
+            "provide": {
+                "psr/simple-cache-implementation": "1.0|2.0|3.0"
+            },
+            "suggest": {
+                "ext-apcu": "Required to use the APC cache driver.",
+                "ext-filter": "Required to use the DynamoDb cache driver.",
+                "ext-memcached": "Required to use the memcache cache driver.",
+                "illuminate/database": "Required to use the database cache driver (^10.0).",
+                "illuminate/filesystem": "Required to use the file cache driver (^10.0).",
+                "illuminate/redis": "Required to use the redis cache driver (^10.0).",
+                "symfony/cache": "Required to use PSR-6 cache bridge (^6.2)."
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Cache\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Cache package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "time": "2024-11-21T14:02:44+00:00"
+        },
+        {
+            "name": "illuminate/collections",
+            "version": "v10.48.28",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/collections.git",
+                "reference": "48de3d6bc6aa779112ddcb608a3a96fc975d89d8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/collections/zipball/48de3d6bc6aa779112ddcb608a3a96fc975d89d8",
+                "reference": "48de3d6bc6aa779112ddcb608a3a96fc975d89d8",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "illuminate/conditionable": "^10.0",
+                "illuminate/contracts": "^10.0",
+                "illuminate/macroable": "^10.0",
+                "php": "^8.1"
+            },
+            "suggest": {
+                "symfony/var-dumper": "Required to use the dump method (^6.2)."
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "helpers.php"
+                ],
+                "psr-4": {
+                    "Illuminate\\Support\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Collections package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "time": "2024-11-21T14:02:44+00:00"
+        },
+        {
+            "name": "illuminate/conditionable",
+            "version": "v10.48.28",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/conditionable.git",
+                "reference": "3ee34ac306fafc2a6f19cd7cd68c9af389e432a5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/conditionable/zipball/3ee34ac306fafc2a6f19cd7cd68c9af389e432a5",
+                "reference": "3ee34ac306fafc2a6f19cd7cd68c9af389e432a5",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^8.0.2"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Support\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Conditionable package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "time": "2024-11-21T14:02:44+00:00"
+        },
+        {
+            "name": "illuminate/contracts",
+            "version": "v10.48.28",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/contracts.git",
+                "reference": "f90663a69f926105a70b78060a31f3c64e2d1c74"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/contracts/zipball/f90663a69f926105a70b78060a31f3c64e2d1c74",
+                "reference": "f90663a69f926105a70b78060a31f3c64e2d1c74",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^8.1",
+                "psr/container": "^1.1.1|^2.0.1",
+                "psr/simple-cache": "^1.0|^2.0|^3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Contracts\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Contracts package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "time": "2024-11-21T14:02:44+00:00"
+        },
+        {
+            "name": "illuminate/macroable",
+            "version": "v10.48.28",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/macroable.git",
+                "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/macroable/zipball/dff667a46ac37b634dcf68909d9d41e94dc97c27",
+                "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^8.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Support\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Macroable package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "time": "2023-06-05T12:46:42+00:00"
+        },
+        {
+            "name": "illuminate/support",
+            "version": "v10.48.28",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/support.git",
+                "reference": "6d09b480d34846245d9288f4dcefb17a73ce6e6a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/support/zipball/6d09b480d34846245d9288f4dcefb17a73ce6e6a",
+                "reference": "6d09b480d34846245d9288f4dcefb17a73ce6e6a",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "doctrine/inflector": "^2.0",
+                "ext-ctype": "*",
+                "ext-filter": "*",
+                "ext-mbstring": "*",
+                "illuminate/collections": "^10.0",
+                "illuminate/conditionable": "^10.0",
+                "illuminate/contracts": "^10.0",
+                "illuminate/macroable": "^10.0",
+                "nesbot/carbon": "^2.67",
+                "php": "^8.1",
+                "voku/portable-ascii": "^2.0"
+            },
+            "conflict": {
+                "tightenco/collect": "<5.5.33"
+            },
+            "suggest": {
+                "illuminate/filesystem": "Required to use the composer class (^10.0).",
+                "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.6).",
+                "ramsey/uuid": "Required to use Str::uuid() (^4.7).",
+                "symfony/process": "Required to use the composer class (^6.2).",
+                "symfony/uid": "Required to use Str::ulid() (^6.2).",
+                "symfony/var-dumper": "Required to use the dd function (^6.2).",
+                "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)."
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "helpers.php"
+                ],
+                "psr-4": {
+                    "Illuminate\\Support\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Support package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "time": "2024-12-10T14:47:55+00:00"
+        },
         {
             "name": "jetbrains/phpstorm-attributes",
             "version": "1.1",
@@ -7014,6 +7378,86 @@
                 }
             ],
             "time": "2023-11-12T22:43:29+00:00"
+        },
+        {
+            "name": "voku/portable-ascii",
+            "version": "2.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/voku/portable-ascii.git",
+                "reference": "16c17671a804bb92602822113dd91fbc8a35d2af"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/voku/portable-ascii/zipball/16c17671a804bb92602822113dd91fbc8a35d2af",
+                "reference": "16c17671a804bb92602822113dd91fbc8a35d2af",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.0.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
+            },
+            "suggest": {
+                "ext-intl": "Use Intl for transliterator_transliterate() support"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "voku\\": "src/voku/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Lars Moelleken",
+                    "homepage": "https://www.moelleken.org/"
+                }
+            ],
+            "description": "Portable ASCII library - performance optimized (ascii) string functions for php.",
+            "homepage": "https://github.com/voku/portable-ascii",
+            "keywords": [
+                "ascii",
+                "clean",
+                "php"
+            ],
+            "support": {
+                "issues": "https://github.com/voku/portable-ascii/issues",
+                "source": "https://github.com/voku/portable-ascii/tree/2.0.2"
+            },
+            "funding": [
+                {
+                    "url": "https://www.paypal.me/moelleken",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/voku",
+                    "type": "github"
+                },
+                {
+                    "url": "https://opencollective.com/portable-ascii",
+                    "type": "open_collective"
+                },
+                {
+                    "url": "https://www.patreon.com/voku",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-11-21T00:49:12+00:00"
         }
     ],
     "packages-dev": [

+ 19 - 19
config/autoload/cache.php

@@ -1,19 +1,19 @@
-<?php
-
-declare(strict_types=1);
-/**
- * This file is part of Hyperf.
- *
- * @link     https://www.hyperf.io
- * @document https://hyperf.wiki
- * @contact  group@hyperf.io
- * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
- */
-return [
-    'default' => [
-        'driver' => Hyperf\Cache\Driver\RedisDriver::class,
-        'packer' => Hyperf\Codec\Packer\PhpSerializerPacker::class,
-        'prefix' => 'c:',
-        'skip_cache_results' => [],
-    ],
-];
+<?php
+
+declare(strict_types=1);
+/**
+ * This file is part of Hyperf.
+ *
+ * @link     https://www.hyperf.io
+ * @document https://hyperf.wiki
+ * @contact  group@hyperf.io
+ * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
+ */
+return [
+    'default' => [
+        'driver' => \Hyperf\Cache\Driver\FileSystemDriver::class,
+        'packer' => Hyperf\Codec\Packer\PhpSerializerPacker::class,
+        'prefix' => 'c:',
+        'skip_cache_results' => [],
+    ],
+];

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
runtime/container/classes.cache


+ 1 - 1
runtime/hyperf.pid

@@ -1 +1 @@
-83871
+27172

+ 287 - 0
vendor/composer/autoload_classmap.php

@@ -20,11 +20,16 @@ return array(
     'App\\Model\\ArticleSurvey' => $baseDir . '/app/Model/ArticleSurvey.php',
     'App\\Model\\Book' => $baseDir . '/app/Model/Book.php',
     'App\\Model\\Category' => $baseDir . '/app/Model/Category.php',
+    'App\\Model\\Character' => $baseDir . '/app/Model/Character.php',
     'App\\Model\\ChatGroups' => $baseDir . '/app/Model/ChatGroups.php',
     'App\\Model\\ChatGroupsMember' => $baseDir . '/app/Model/ChatGroupsMember.php',
     'App\\Model\\ChatRecords' => $baseDir . '/app/Model/ChatRecords.php',
+    'App\\Model\\Couplet' => $baseDir . '/app/Model/Couplet.php',
     'App\\Model\\District' => $baseDir . '/app/Model/District.php',
+    'App\\Model\\Festival' => $baseDir . '/app/Model/Festival.php',
     'App\\Model\\Good' => $baseDir . '/app/Model/Good.php',
+    'App\\Model\\HistoryToday' => $baseDir . '/app/Model/HistoryToday.php',
+    'App\\Model\\Idiom' => $baseDir . '/app/Model/Idiom.php',
     'App\\Model\\JobApply' => $baseDir . '/app/Model/JobApply.php',
     'App\\Model\\JobCompany' => $baseDir . '/app/Model/JobCompany.php',
     'App\\Model\\JobEnum' => $baseDir . '/app/Model/JobEnum.php',
@@ -37,6 +42,7 @@ return array(
     'App\\Model\\Link' => $baseDir . '/app/Model/Link.php',
     'App\\Model\\Model' => $baseDir . '/app/Model/Model.php',
     'App\\Model\\Notice' => $baseDir . '/app/Model/Notice.php',
+    'App\\Model\\Riddle' => $baseDir . '/app/Model/Riddle.php',
     'App\\Model\\User' => $baseDir . '/app/Model/User.php',
     'App\\Model\\UserInfo' => $baseDir . '/app/Model/UserInfo.php',
     'App\\Model\\Web' => $baseDir . '/app/Model/Web.php',
@@ -1572,6 +1578,286 @@ return array(
     'Hyperf\\Watcher\\Option' => $vendorDir . '/hyperf/watcher/src/Option.php',
     'Hyperf\\Watcher\\Process' => $vendorDir . '/hyperf/watcher/src/Process.php',
     'Hyperf\\Watcher\\Watcher' => $vendorDir . '/hyperf/watcher/src/Watcher.php',
+    'Illuminate\\Cache\\ApcStore' => $vendorDir . '/illuminate/cache/ApcStore.php',
+    'Illuminate\\Cache\\ApcWrapper' => $vendorDir . '/illuminate/cache/ApcWrapper.php',
+    'Illuminate\\Cache\\ArrayLock' => $vendorDir . '/illuminate/cache/ArrayLock.php',
+    'Illuminate\\Cache\\ArrayStore' => $vendorDir . '/illuminate/cache/ArrayStore.php',
+    'Illuminate\\Cache\\CacheLock' => $vendorDir . '/illuminate/cache/CacheLock.php',
+    'Illuminate\\Cache\\CacheManager' => $vendorDir . '/illuminate/cache/CacheManager.php',
+    'Illuminate\\Cache\\CacheServiceProvider' => $vendorDir . '/illuminate/cache/CacheServiceProvider.php',
+    'Illuminate\\Cache\\Console\\CacheTableCommand' => $vendorDir . '/illuminate/cache/Console/CacheTableCommand.php',
+    'Illuminate\\Cache\\Console\\ClearCommand' => $vendorDir . '/illuminate/cache/Console/ClearCommand.php',
+    'Illuminate\\Cache\\Console\\ForgetCommand' => $vendorDir . '/illuminate/cache/Console/ForgetCommand.php',
+    'Illuminate\\Cache\\Console\\PruneStaleTagsCommand' => $vendorDir . '/illuminate/cache/Console/PruneStaleTagsCommand.php',
+    'Illuminate\\Cache\\DatabaseLock' => $vendorDir . '/illuminate/cache/DatabaseLock.php',
+    'Illuminate\\Cache\\DatabaseStore' => $vendorDir . '/illuminate/cache/DatabaseStore.php',
+    'Illuminate\\Cache\\DynamoDbLock' => $vendorDir . '/illuminate/cache/DynamoDbLock.php',
+    'Illuminate\\Cache\\DynamoDbStore' => $vendorDir . '/illuminate/cache/DynamoDbStore.php',
+    'Illuminate\\Cache\\Events\\CacheEvent' => $vendorDir . '/illuminate/cache/Events/CacheEvent.php',
+    'Illuminate\\Cache\\Events\\CacheHit' => $vendorDir . '/illuminate/cache/Events/CacheHit.php',
+    'Illuminate\\Cache\\Events\\CacheMissed' => $vendorDir . '/illuminate/cache/Events/CacheMissed.php',
+    'Illuminate\\Cache\\Events\\KeyForgotten' => $vendorDir . '/illuminate/cache/Events/KeyForgotten.php',
+    'Illuminate\\Cache\\Events\\KeyWritten' => $vendorDir . '/illuminate/cache/Events/KeyWritten.php',
+    'Illuminate\\Cache\\FileLock' => $vendorDir . '/illuminate/cache/FileLock.php',
+    'Illuminate\\Cache\\FileStore' => $vendorDir . '/illuminate/cache/FileStore.php',
+    'Illuminate\\Cache\\HasCacheLock' => $vendorDir . '/illuminate/cache/HasCacheLock.php',
+    'Illuminate\\Cache\\Lock' => $vendorDir . '/illuminate/cache/Lock.php',
+    'Illuminate\\Cache\\LuaScripts' => $vendorDir . '/illuminate/cache/LuaScripts.php',
+    'Illuminate\\Cache\\MemcachedConnector' => $vendorDir . '/illuminate/cache/MemcachedConnector.php',
+    'Illuminate\\Cache\\MemcachedLock' => $vendorDir . '/illuminate/cache/MemcachedLock.php',
+    'Illuminate\\Cache\\MemcachedStore' => $vendorDir . '/illuminate/cache/MemcachedStore.php',
+    'Illuminate\\Cache\\NoLock' => $vendorDir . '/illuminate/cache/NoLock.php',
+    'Illuminate\\Cache\\NullStore' => $vendorDir . '/illuminate/cache/NullStore.php',
+    'Illuminate\\Cache\\PhpRedisLock' => $vendorDir . '/illuminate/cache/PhpRedisLock.php',
+    'Illuminate\\Cache\\RateLimiter' => $vendorDir . '/illuminate/cache/RateLimiter.php',
+    'Illuminate\\Cache\\RateLimiting\\GlobalLimit' => $vendorDir . '/illuminate/cache/RateLimiting/GlobalLimit.php',
+    'Illuminate\\Cache\\RateLimiting\\Limit' => $vendorDir . '/illuminate/cache/RateLimiting/Limit.php',
+    'Illuminate\\Cache\\RateLimiting\\Unlimited' => $vendorDir . '/illuminate/cache/RateLimiting/Unlimited.php',
+    'Illuminate\\Cache\\RedisLock' => $vendorDir . '/illuminate/cache/RedisLock.php',
+    'Illuminate\\Cache\\RedisStore' => $vendorDir . '/illuminate/cache/RedisStore.php',
+    'Illuminate\\Cache\\RedisTagSet' => $vendorDir . '/illuminate/cache/RedisTagSet.php',
+    'Illuminate\\Cache\\RedisTaggedCache' => $vendorDir . '/illuminate/cache/RedisTaggedCache.php',
+    'Illuminate\\Cache\\Repository' => $vendorDir . '/illuminate/cache/Repository.php',
+    'Illuminate\\Cache\\RetrievesMultipleKeys' => $vendorDir . '/illuminate/cache/RetrievesMultipleKeys.php',
+    'Illuminate\\Cache\\TagSet' => $vendorDir . '/illuminate/cache/TagSet.php',
+    'Illuminate\\Cache\\TaggableStore' => $vendorDir . '/illuminate/cache/TaggableStore.php',
+    'Illuminate\\Cache\\TaggedCache' => $vendorDir . '/illuminate/cache/TaggedCache.php',
+    'Illuminate\\Contracts\\Auth\\Access\\Authorizable' => $vendorDir . '/illuminate/contracts/Auth/Access/Authorizable.php',
+    'Illuminate\\Contracts\\Auth\\Access\\Gate' => $vendorDir . '/illuminate/contracts/Auth/Access/Gate.php',
+    'Illuminate\\Contracts\\Auth\\Authenticatable' => $vendorDir . '/illuminate/contracts/Auth/Authenticatable.php',
+    'Illuminate\\Contracts\\Auth\\CanResetPassword' => $vendorDir . '/illuminate/contracts/Auth/CanResetPassword.php',
+    'Illuminate\\Contracts\\Auth\\Factory' => $vendorDir . '/illuminate/contracts/Auth/Factory.php',
+    'Illuminate\\Contracts\\Auth\\Guard' => $vendorDir . '/illuminate/contracts/Auth/Guard.php',
+    'Illuminate\\Contracts\\Auth\\Middleware\\AuthenticatesRequests' => $vendorDir . '/illuminate/contracts/Auth/Middleware/AuthenticatesRequests.php',
+    'Illuminate\\Contracts\\Auth\\MustVerifyEmail' => $vendorDir . '/illuminate/contracts/Auth/MustVerifyEmail.php',
+    'Illuminate\\Contracts\\Auth\\PasswordBroker' => $vendorDir . '/illuminate/contracts/Auth/PasswordBroker.php',
+    'Illuminate\\Contracts\\Auth\\PasswordBrokerFactory' => $vendorDir . '/illuminate/contracts/Auth/PasswordBrokerFactory.php',
+    'Illuminate\\Contracts\\Auth\\StatefulGuard' => $vendorDir . '/illuminate/contracts/Auth/StatefulGuard.php',
+    'Illuminate\\Contracts\\Auth\\SupportsBasicAuth' => $vendorDir . '/illuminate/contracts/Auth/SupportsBasicAuth.php',
+    'Illuminate\\Contracts\\Auth\\UserProvider' => $vendorDir . '/illuminate/contracts/Auth/UserProvider.php',
+    'Illuminate\\Contracts\\Broadcasting\\Broadcaster' => $vendorDir . '/illuminate/contracts/Broadcasting/Broadcaster.php',
+    'Illuminate\\Contracts\\Broadcasting\\Factory' => $vendorDir . '/illuminate/contracts/Broadcasting/Factory.php',
+    'Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel' => $vendorDir . '/illuminate/contracts/Broadcasting/HasBroadcastChannel.php',
+    'Illuminate\\Contracts\\Broadcasting\\ShouldBeUnique' => $vendorDir . '/illuminate/contracts/Broadcasting/ShouldBeUnique.php',
+    'Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast' => $vendorDir . '/illuminate/contracts/Broadcasting/ShouldBroadcast.php',
+    'Illuminate\\Contracts\\Broadcasting\\ShouldBroadcastNow' => $vendorDir . '/illuminate/contracts/Broadcasting/ShouldBroadcastNow.php',
+    'Illuminate\\Contracts\\Bus\\Dispatcher' => $vendorDir . '/illuminate/contracts/Bus/Dispatcher.php',
+    'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => $vendorDir . '/illuminate/contracts/Bus/QueueingDispatcher.php',
+    'Illuminate\\Contracts\\Cache\\Factory' => $vendorDir . '/illuminate/contracts/Cache/Factory.php',
+    'Illuminate\\Contracts\\Cache\\Lock' => $vendorDir . '/illuminate/contracts/Cache/Lock.php',
+    'Illuminate\\Contracts\\Cache\\LockProvider' => $vendorDir . '/illuminate/contracts/Cache/LockProvider.php',
+    'Illuminate\\Contracts\\Cache\\LockTimeoutException' => $vendorDir . '/illuminate/contracts/Cache/LockTimeoutException.php',
+    'Illuminate\\Contracts\\Cache\\Repository' => $vendorDir . '/illuminate/contracts/Cache/Repository.php',
+    'Illuminate\\Contracts\\Cache\\Store' => $vendorDir . '/illuminate/contracts/Cache/Store.php',
+    'Illuminate\\Contracts\\Config\\Repository' => $vendorDir . '/illuminate/contracts/Config/Repository.php',
+    'Illuminate\\Contracts\\Console\\Application' => $vendorDir . '/illuminate/contracts/Console/Application.php',
+    'Illuminate\\Contracts\\Console\\Isolatable' => $vendorDir . '/illuminate/contracts/Console/Isolatable.php',
+    'Illuminate\\Contracts\\Console\\Kernel' => $vendorDir . '/illuminate/contracts/Console/Kernel.php',
+    'Illuminate\\Contracts\\Console\\PromptsForMissingInput' => $vendorDir . '/illuminate/contracts/Console/PromptsForMissingInput.php',
+    'Illuminate\\Contracts\\Container\\BindingResolutionException' => $vendorDir . '/illuminate/contracts/Container/BindingResolutionException.php',
+    'Illuminate\\Contracts\\Container\\CircularDependencyException' => $vendorDir . '/illuminate/contracts/Container/CircularDependencyException.php',
+    'Illuminate\\Contracts\\Container\\Container' => $vendorDir . '/illuminate/contracts/Container/Container.php',
+    'Illuminate\\Contracts\\Container\\ContextualBindingBuilder' => $vendorDir . '/illuminate/contracts/Container/ContextualBindingBuilder.php',
+    'Illuminate\\Contracts\\Cookie\\Factory' => $vendorDir . '/illuminate/contracts/Cookie/Factory.php',
+    'Illuminate\\Contracts\\Cookie\\QueueingFactory' => $vendorDir . '/illuminate/contracts/Cookie/QueueingFactory.php',
+    'Illuminate\\Contracts\\Database\\Eloquent\\Builder' => $vendorDir . '/illuminate/contracts/Database/Eloquent/Builder.php',
+    'Illuminate\\Contracts\\Database\\Eloquent\\Castable' => $vendorDir . '/illuminate/contracts/Database/Eloquent/Castable.php',
+    'Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes' => $vendorDir . '/illuminate/contracts/Database/Eloquent/CastsAttributes.php',
+    'Illuminate\\Contracts\\Database\\Eloquent\\CastsInboundAttributes' => $vendorDir . '/illuminate/contracts/Database/Eloquent/CastsInboundAttributes.php',
+    'Illuminate\\Contracts\\Database\\Eloquent\\DeviatesCastableAttributes' => $vendorDir . '/illuminate/contracts/Database/Eloquent/DeviatesCastableAttributes.php',
+    'Illuminate\\Contracts\\Database\\Eloquent\\SerializesCastableAttributes' => $vendorDir . '/illuminate/contracts/Database/Eloquent/SerializesCastableAttributes.php',
+    'Illuminate\\Contracts\\Database\\Eloquent\\SupportsPartialRelations' => $vendorDir . '/illuminate/contracts/Database/Eloquent/SupportsPartialRelations.php',
+    'Illuminate\\Contracts\\Database\\Events\\MigrationEvent' => $vendorDir . '/illuminate/contracts/Database/Events/MigrationEvent.php',
+    'Illuminate\\Contracts\\Database\\ModelIdentifier' => $vendorDir . '/illuminate/contracts/Database/ModelIdentifier.php',
+    'Illuminate\\Contracts\\Database\\Query\\Builder' => $vendorDir . '/illuminate/contracts/Database/Query/Builder.php',
+    'Illuminate\\Contracts\\Database\\Query\\ConditionExpression' => $vendorDir . '/illuminate/contracts/Database/Query/ConditionExpression.php',
+    'Illuminate\\Contracts\\Database\\Query\\Expression' => $vendorDir . '/illuminate/contracts/Database/Query/Expression.php',
+    'Illuminate\\Contracts\\Debug\\ExceptionHandler' => $vendorDir . '/illuminate/contracts/Debug/ExceptionHandler.php',
+    'Illuminate\\Contracts\\Encryption\\DecryptException' => $vendorDir . '/illuminate/contracts/Encryption/DecryptException.php',
+    'Illuminate\\Contracts\\Encryption\\EncryptException' => $vendorDir . '/illuminate/contracts/Encryption/EncryptException.php',
+    'Illuminate\\Contracts\\Encryption\\Encrypter' => $vendorDir . '/illuminate/contracts/Encryption/Encrypter.php',
+    'Illuminate\\Contracts\\Encryption\\StringEncrypter' => $vendorDir . '/illuminate/contracts/Encryption/StringEncrypter.php',
+    'Illuminate\\Contracts\\Events\\Dispatcher' => $vendorDir . '/illuminate/contracts/Events/Dispatcher.php',
+    'Illuminate\\Contracts\\Events\\ShouldDispatchAfterCommit' => $vendorDir . '/illuminate/contracts/Events/ShouldDispatchAfterCommit.php',
+    'Illuminate\\Contracts\\Events\\ShouldHandleEventsAfterCommit' => $vendorDir . '/illuminate/contracts/Events/ShouldHandleEventsAfterCommit.php',
+    'Illuminate\\Contracts\\Filesystem\\Cloud' => $vendorDir . '/illuminate/contracts/Filesystem/Cloud.php',
+    'Illuminate\\Contracts\\Filesystem\\Factory' => $vendorDir . '/illuminate/contracts/Filesystem/Factory.php',
+    'Illuminate\\Contracts\\Filesystem\\FileNotFoundException' => $vendorDir . '/illuminate/contracts/Filesystem/FileNotFoundException.php',
+    'Illuminate\\Contracts\\Filesystem\\Filesystem' => $vendorDir . '/illuminate/contracts/Filesystem/Filesystem.php',
+    'Illuminate\\Contracts\\Filesystem\\LockTimeoutException' => $vendorDir . '/illuminate/contracts/Filesystem/LockTimeoutException.php',
+    'Illuminate\\Contracts\\Foundation\\Application' => $vendorDir . '/illuminate/contracts/Foundation/Application.php',
+    'Illuminate\\Contracts\\Foundation\\CachesConfiguration' => $vendorDir . '/illuminate/contracts/Foundation/CachesConfiguration.php',
+    'Illuminate\\Contracts\\Foundation\\CachesRoutes' => $vendorDir . '/illuminate/contracts/Foundation/CachesRoutes.php',
+    'Illuminate\\Contracts\\Foundation\\ExceptionRenderer' => $vendorDir . '/illuminate/contracts/Foundation/ExceptionRenderer.php',
+    'Illuminate\\Contracts\\Foundation\\MaintenanceMode' => $vendorDir . '/illuminate/contracts/Foundation/MaintenanceMode.php',
+    'Illuminate\\Contracts\\Hashing\\Hasher' => $vendorDir . '/illuminate/contracts/Hashing/Hasher.php',
+    'Illuminate\\Contracts\\Http\\Kernel' => $vendorDir . '/illuminate/contracts/Http/Kernel.php',
+    'Illuminate\\Contracts\\Mail\\Attachable' => $vendorDir . '/illuminate/contracts/Mail/Attachable.php',
+    'Illuminate\\Contracts\\Mail\\Factory' => $vendorDir . '/illuminate/contracts/Mail/Factory.php',
+    'Illuminate\\Contracts\\Mail\\MailQueue' => $vendorDir . '/illuminate/contracts/Mail/MailQueue.php',
+    'Illuminate\\Contracts\\Mail\\Mailable' => $vendorDir . '/illuminate/contracts/Mail/Mailable.php',
+    'Illuminate\\Contracts\\Mail\\Mailer' => $vendorDir . '/illuminate/contracts/Mail/Mailer.php',
+    'Illuminate\\Contracts\\Notifications\\Dispatcher' => $vendorDir . '/illuminate/contracts/Notifications/Dispatcher.php',
+    'Illuminate\\Contracts\\Notifications\\Factory' => $vendorDir . '/illuminate/contracts/Notifications/Factory.php',
+    'Illuminate\\Contracts\\Pagination\\CursorPaginator' => $vendorDir . '/illuminate/contracts/Pagination/CursorPaginator.php',
+    'Illuminate\\Contracts\\Pagination\\LengthAwarePaginator' => $vendorDir . '/illuminate/contracts/Pagination/LengthAwarePaginator.php',
+    'Illuminate\\Contracts\\Pagination\\Paginator' => $vendorDir . '/illuminate/contracts/Pagination/Paginator.php',
+    'Illuminate\\Contracts\\Pipeline\\Hub' => $vendorDir . '/illuminate/contracts/Pipeline/Hub.php',
+    'Illuminate\\Contracts\\Pipeline\\Pipeline' => $vendorDir . '/illuminate/contracts/Pipeline/Pipeline.php',
+    'Illuminate\\Contracts\\Process\\InvokedProcess' => $vendorDir . '/illuminate/contracts/Process/InvokedProcess.php',
+    'Illuminate\\Contracts\\Process\\ProcessResult' => $vendorDir . '/illuminate/contracts/Process/ProcessResult.php',
+    'Illuminate\\Contracts\\Queue\\ClearableQueue' => $vendorDir . '/illuminate/contracts/Queue/ClearableQueue.php',
+    'Illuminate\\Contracts\\Queue\\EntityNotFoundException' => $vendorDir . '/illuminate/contracts/Queue/EntityNotFoundException.php',
+    'Illuminate\\Contracts\\Queue\\EntityResolver' => $vendorDir . '/illuminate/contracts/Queue/EntityResolver.php',
+    'Illuminate\\Contracts\\Queue\\Factory' => $vendorDir . '/illuminate/contracts/Queue/Factory.php',
+    'Illuminate\\Contracts\\Queue\\Job' => $vendorDir . '/illuminate/contracts/Queue/Job.php',
+    'Illuminate\\Contracts\\Queue\\Monitor' => $vendorDir . '/illuminate/contracts/Queue/Monitor.php',
+    'Illuminate\\Contracts\\Queue\\Queue' => $vendorDir . '/illuminate/contracts/Queue/Queue.php',
+    'Illuminate\\Contracts\\Queue\\QueueableCollection' => $vendorDir . '/illuminate/contracts/Queue/QueueableCollection.php',
+    'Illuminate\\Contracts\\Queue\\QueueableEntity' => $vendorDir . '/illuminate/contracts/Queue/QueueableEntity.php',
+    'Illuminate\\Contracts\\Queue\\ShouldBeEncrypted' => $vendorDir . '/illuminate/contracts/Queue/ShouldBeEncrypted.php',
+    'Illuminate\\Contracts\\Queue\\ShouldBeUnique' => $vendorDir . '/illuminate/contracts/Queue/ShouldBeUnique.php',
+    'Illuminate\\Contracts\\Queue\\ShouldBeUniqueUntilProcessing' => $vendorDir . '/illuminate/contracts/Queue/ShouldBeUniqueUntilProcessing.php',
+    'Illuminate\\Contracts\\Queue\\ShouldQueue' => $vendorDir . '/illuminate/contracts/Queue/ShouldQueue.php',
+    'Illuminate\\Contracts\\Queue\\ShouldQueueAfterCommit' => $vendorDir . '/illuminate/contracts/Queue/ShouldQueueAfterCommit.php',
+    'Illuminate\\Contracts\\Redis\\Connection' => $vendorDir . '/illuminate/contracts/Redis/Connection.php',
+    'Illuminate\\Contracts\\Redis\\Connector' => $vendorDir . '/illuminate/contracts/Redis/Connector.php',
+    'Illuminate\\Contracts\\Redis\\Factory' => $vendorDir . '/illuminate/contracts/Redis/Factory.php',
+    'Illuminate\\Contracts\\Redis\\LimiterTimeoutException' => $vendorDir . '/illuminate/contracts/Redis/LimiterTimeoutException.php',
+    'Illuminate\\Contracts\\Routing\\BindingRegistrar' => $vendorDir . '/illuminate/contracts/Routing/BindingRegistrar.php',
+    'Illuminate\\Contracts\\Routing\\Registrar' => $vendorDir . '/illuminate/contracts/Routing/Registrar.php',
+    'Illuminate\\Contracts\\Routing\\ResponseFactory' => $vendorDir . '/illuminate/contracts/Routing/ResponseFactory.php',
+    'Illuminate\\Contracts\\Routing\\UrlGenerator' => $vendorDir . '/illuminate/contracts/Routing/UrlGenerator.php',
+    'Illuminate\\Contracts\\Routing\\UrlRoutable' => $vendorDir . '/illuminate/contracts/Routing/UrlRoutable.php',
+    'Illuminate\\Contracts\\Session\\Middleware\\AuthenticatesSessions' => $vendorDir . '/illuminate/contracts/Session/Middleware/AuthenticatesSessions.php',
+    'Illuminate\\Contracts\\Session\\Session' => $vendorDir . '/illuminate/contracts/Session/Session.php',
+    'Illuminate\\Contracts\\Support\\Arrayable' => $vendorDir . '/illuminate/contracts/Support/Arrayable.php',
+    'Illuminate\\Contracts\\Support\\CanBeEscapedWhenCastToString' => $vendorDir . '/illuminate/contracts/Support/CanBeEscapedWhenCastToString.php',
+    'Illuminate\\Contracts\\Support\\DeferrableProvider' => $vendorDir . '/illuminate/contracts/Support/DeferrableProvider.php',
+    'Illuminate\\Contracts\\Support\\DeferringDisplayableValue' => $vendorDir . '/illuminate/contracts/Support/DeferringDisplayableValue.php',
+    'Illuminate\\Contracts\\Support\\Htmlable' => $vendorDir . '/illuminate/contracts/Support/Htmlable.php',
+    'Illuminate\\Contracts\\Support\\Jsonable' => $vendorDir . '/illuminate/contracts/Support/Jsonable.php',
+    'Illuminate\\Contracts\\Support\\MessageBag' => $vendorDir . '/illuminate/contracts/Support/MessageBag.php',
+    'Illuminate\\Contracts\\Support\\MessageProvider' => $vendorDir . '/illuminate/contracts/Support/MessageProvider.php',
+    'Illuminate\\Contracts\\Support\\Renderable' => $vendorDir . '/illuminate/contracts/Support/Renderable.php',
+    'Illuminate\\Contracts\\Support\\Responsable' => $vendorDir . '/illuminate/contracts/Support/Responsable.php',
+    'Illuminate\\Contracts\\Support\\ValidatedData' => $vendorDir . '/illuminate/contracts/Support/ValidatedData.php',
+    'Illuminate\\Contracts\\Translation\\HasLocalePreference' => $vendorDir . '/illuminate/contracts/Translation/HasLocalePreference.php',
+    'Illuminate\\Contracts\\Translation\\Loader' => $vendorDir . '/illuminate/contracts/Translation/Loader.php',
+    'Illuminate\\Contracts\\Translation\\Translator' => $vendorDir . '/illuminate/contracts/Translation/Translator.php',
+    'Illuminate\\Contracts\\Validation\\DataAwareRule' => $vendorDir . '/illuminate/contracts/Validation/DataAwareRule.php',
+    'Illuminate\\Contracts\\Validation\\Factory' => $vendorDir . '/illuminate/contracts/Validation/Factory.php',
+    'Illuminate\\Contracts\\Validation\\ImplicitRule' => $vendorDir . '/illuminate/contracts/Validation/ImplicitRule.php',
+    'Illuminate\\Contracts\\Validation\\InvokableRule' => $vendorDir . '/illuminate/contracts/Validation/InvokableRule.php',
+    'Illuminate\\Contracts\\Validation\\Rule' => $vendorDir . '/illuminate/contracts/Validation/Rule.php',
+    'Illuminate\\Contracts\\Validation\\UncompromisedVerifier' => $vendorDir . '/illuminate/contracts/Validation/UncompromisedVerifier.php',
+    'Illuminate\\Contracts\\Validation\\ValidatesWhenResolved' => $vendorDir . '/illuminate/contracts/Validation/ValidatesWhenResolved.php',
+    'Illuminate\\Contracts\\Validation\\ValidationRule' => $vendorDir . '/illuminate/contracts/Validation/ValidationRule.php',
+    'Illuminate\\Contracts\\Validation\\Validator' => $vendorDir . '/illuminate/contracts/Validation/Validator.php',
+    'Illuminate\\Contracts\\Validation\\ValidatorAwareRule' => $vendorDir . '/illuminate/contracts/Validation/ValidatorAwareRule.php',
+    'Illuminate\\Contracts\\View\\Engine' => $vendorDir . '/illuminate/contracts/View/Engine.php',
+    'Illuminate\\Contracts\\View\\Factory' => $vendorDir . '/illuminate/contracts/View/Factory.php',
+    'Illuminate\\Contracts\\View\\View' => $vendorDir . '/illuminate/contracts/View/View.php',
+    'Illuminate\\Contracts\\View\\ViewCompilationException' => $vendorDir . '/illuminate/contracts/View/ViewCompilationException.php',
+    'Illuminate\\Support\\AggregateServiceProvider' => $vendorDir . '/illuminate/support/AggregateServiceProvider.php',
+    'Illuminate\\Support\\Arr' => $vendorDir . '/illuminate/collections/Arr.php',
+    'Illuminate\\Support\\Benchmark' => $vendorDir . '/illuminate/support/Benchmark.php',
+    'Illuminate\\Support\\Carbon' => $vendorDir . '/illuminate/support/Carbon.php',
+    'Illuminate\\Support\\Collection' => $vendorDir . '/illuminate/collections/Collection.php',
+    'Illuminate\\Support\\Composer' => $vendorDir . '/illuminate/support/Composer.php',
+    'Illuminate\\Support\\ConfigurationUrlParser' => $vendorDir . '/illuminate/support/ConfigurationUrlParser.php',
+    'Illuminate\\Support\\DateFactory' => $vendorDir . '/illuminate/support/DateFactory.php',
+    'Illuminate\\Support\\DefaultProviders' => $vendorDir . '/illuminate/support/DefaultProviders.php',
+    'Illuminate\\Support\\Enumerable' => $vendorDir . '/illuminate/collections/Enumerable.php',
+    'Illuminate\\Support\\Env' => $vendorDir . '/illuminate/support/Env.php',
+    'Illuminate\\Support\\Exceptions\\MathException' => $vendorDir . '/illuminate/support/Exceptions/MathException.php',
+    'Illuminate\\Support\\Facades\\App' => $vendorDir . '/illuminate/support/Facades/App.php',
+    'Illuminate\\Support\\Facades\\Artisan' => $vendorDir . '/illuminate/support/Facades/Artisan.php',
+    'Illuminate\\Support\\Facades\\Auth' => $vendorDir . '/illuminate/support/Facades/Auth.php',
+    'Illuminate\\Support\\Facades\\Blade' => $vendorDir . '/illuminate/support/Facades/Blade.php',
+    'Illuminate\\Support\\Facades\\Broadcast' => $vendorDir . '/illuminate/support/Facades/Broadcast.php',
+    'Illuminate\\Support\\Facades\\Bus' => $vendorDir . '/illuminate/support/Facades/Bus.php',
+    'Illuminate\\Support\\Facades\\Cache' => $vendorDir . '/illuminate/support/Facades/Cache.php',
+    'Illuminate\\Support\\Facades\\Config' => $vendorDir . '/illuminate/support/Facades/Config.php',
+    'Illuminate\\Support\\Facades\\Cookie' => $vendorDir . '/illuminate/support/Facades/Cookie.php',
+    'Illuminate\\Support\\Facades\\Crypt' => $vendorDir . '/illuminate/support/Facades/Crypt.php',
+    'Illuminate\\Support\\Facades\\DB' => $vendorDir . '/illuminate/support/Facades/DB.php',
+    'Illuminate\\Support\\Facades\\Date' => $vendorDir . '/illuminate/support/Facades/Date.php',
+    'Illuminate\\Support\\Facades\\Event' => $vendorDir . '/illuminate/support/Facades/Event.php',
+    'Illuminate\\Support\\Facades\\Facade' => $vendorDir . '/illuminate/support/Facades/Facade.php',
+    'Illuminate\\Support\\Facades\\File' => $vendorDir . '/illuminate/support/Facades/File.php',
+    'Illuminate\\Support\\Facades\\Gate' => $vendorDir . '/illuminate/support/Facades/Gate.php',
+    'Illuminate\\Support\\Facades\\Hash' => $vendorDir . '/illuminate/support/Facades/Hash.php',
+    'Illuminate\\Support\\Facades\\Http' => $vendorDir . '/illuminate/support/Facades/Http.php',
+    'Illuminate\\Support\\Facades\\Lang' => $vendorDir . '/illuminate/support/Facades/Lang.php',
+    'Illuminate\\Support\\Facades\\Log' => $vendorDir . '/illuminate/support/Facades/Log.php',
+    'Illuminate\\Support\\Facades\\Mail' => $vendorDir . '/illuminate/support/Facades/Mail.php',
+    'Illuminate\\Support\\Facades\\Notification' => $vendorDir . '/illuminate/support/Facades/Notification.php',
+    'Illuminate\\Support\\Facades\\ParallelTesting' => $vendorDir . '/illuminate/support/Facades/ParallelTesting.php',
+    'Illuminate\\Support\\Facades\\Password' => $vendorDir . '/illuminate/support/Facades/Password.php',
+    'Illuminate\\Support\\Facades\\Pipeline' => $vendorDir . '/illuminate/support/Facades/Pipeline.php',
+    'Illuminate\\Support\\Facades\\Process' => $vendorDir . '/illuminate/support/Facades/Process.php',
+    'Illuminate\\Support\\Facades\\Queue' => $vendorDir . '/illuminate/support/Facades/Queue.php',
+    'Illuminate\\Support\\Facades\\RateLimiter' => $vendorDir . '/illuminate/support/Facades/RateLimiter.php',
+    'Illuminate\\Support\\Facades\\Redirect' => $vendorDir . '/illuminate/support/Facades/Redirect.php',
+    'Illuminate\\Support\\Facades\\Redis' => $vendorDir . '/illuminate/support/Facades/Redis.php',
+    'Illuminate\\Support\\Facades\\Request' => $vendorDir . '/illuminate/support/Facades/Request.php',
+    'Illuminate\\Support\\Facades\\Response' => $vendorDir . '/illuminate/support/Facades/Response.php',
+    'Illuminate\\Support\\Facades\\Route' => $vendorDir . '/illuminate/support/Facades/Route.php',
+    'Illuminate\\Support\\Facades\\Schema' => $vendorDir . '/illuminate/support/Facades/Schema.php',
+    'Illuminate\\Support\\Facades\\Session' => $vendorDir . '/illuminate/support/Facades/Session.php',
+    'Illuminate\\Support\\Facades\\Storage' => $vendorDir . '/illuminate/support/Facades/Storage.php',
+    'Illuminate\\Support\\Facades\\URL' => $vendorDir . '/illuminate/support/Facades/URL.php',
+    'Illuminate\\Support\\Facades\\Validator' => $vendorDir . '/illuminate/support/Facades/Validator.php',
+    'Illuminate\\Support\\Facades\\View' => $vendorDir . '/illuminate/support/Facades/View.php',
+    'Illuminate\\Support\\Facades\\Vite' => $vendorDir . '/illuminate/support/Facades/Vite.php',
+    'Illuminate\\Support\\Fluent' => $vendorDir . '/illuminate/support/Fluent.php',
+    'Illuminate\\Support\\HigherOrderCollectionProxy' => $vendorDir . '/illuminate/collections/HigherOrderCollectionProxy.php',
+    'Illuminate\\Support\\HigherOrderTapProxy' => $vendorDir . '/illuminate/support/HigherOrderTapProxy.php',
+    'Illuminate\\Support\\HigherOrderWhenProxy' => $vendorDir . '/illuminate/conditionable/HigherOrderWhenProxy.php',
+    'Illuminate\\Support\\HtmlString' => $vendorDir . '/illuminate/support/HtmlString.php',
+    'Illuminate\\Support\\InteractsWithTime' => $vendorDir . '/illuminate/support/InteractsWithTime.php',
+    'Illuminate\\Support\\ItemNotFoundException' => $vendorDir . '/illuminate/collections/ItemNotFoundException.php',
+    'Illuminate\\Support\\Js' => $vendorDir . '/illuminate/support/Js.php',
+    'Illuminate\\Support\\LazyCollection' => $vendorDir . '/illuminate/collections/LazyCollection.php',
+    'Illuminate\\Support\\Lottery' => $vendorDir . '/illuminate/support/Lottery.php',
+    'Illuminate\\Support\\Manager' => $vendorDir . '/illuminate/support/Manager.php',
+    'Illuminate\\Support\\MessageBag' => $vendorDir . '/illuminate/support/MessageBag.php',
+    'Illuminate\\Support\\MultipleInstanceManager' => $vendorDir . '/illuminate/support/MultipleInstanceManager.php',
+    'Illuminate\\Support\\MultipleItemsFoundException' => $vendorDir . '/illuminate/collections/MultipleItemsFoundException.php',
+    'Illuminate\\Support\\NamespacedItemResolver' => $vendorDir . '/illuminate/support/NamespacedItemResolver.php',
+    'Illuminate\\Support\\Number' => $vendorDir . '/illuminate/support/Number.php',
+    'Illuminate\\Support\\Optional' => $vendorDir . '/illuminate/support/Optional.php',
+    'Illuminate\\Support\\Pluralizer' => $vendorDir . '/illuminate/support/Pluralizer.php',
+    'Illuminate\\Support\\ProcessUtils' => $vendorDir . '/illuminate/support/ProcessUtils.php',
+    'Illuminate\\Support\\Reflector' => $vendorDir . '/illuminate/support/Reflector.php',
+    'Illuminate\\Support\\ServiceProvider' => $vendorDir . '/illuminate/support/ServiceProvider.php',
+    'Illuminate\\Support\\Sleep' => $vendorDir . '/illuminate/support/Sleep.php',
+    'Illuminate\\Support\\Str' => $vendorDir . '/illuminate/support/Str.php',
+    'Illuminate\\Support\\Stringable' => $vendorDir . '/illuminate/support/Stringable.php',
+    'Illuminate\\Support\\Testing\\Fakes\\BatchFake' => $vendorDir . '/illuminate/support/Testing/Fakes/BatchFake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\BatchRepositoryFake' => $vendorDir . '/illuminate/support/Testing/Fakes/BatchRepositoryFake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\BusFake' => $vendorDir . '/illuminate/support/Testing/Fakes/BusFake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\ChainedBatchTruthTest' => $vendorDir . '/illuminate/support/Testing/Fakes/ChainedBatchTruthTest.php',
+    'Illuminate\\Support\\Testing\\Fakes\\EventFake' => $vendorDir . '/illuminate/support/Testing/Fakes/EventFake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\Fake' => $vendorDir . '/illuminate/support/Testing/Fakes/Fake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\MailFake' => $vendorDir . '/illuminate/support/Testing/Fakes/MailFake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\NotificationFake' => $vendorDir . '/illuminate/support/Testing/Fakes/NotificationFake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\PendingBatchFake' => $vendorDir . '/illuminate/support/Testing/Fakes/PendingBatchFake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\PendingChainFake' => $vendorDir . '/illuminate/support/Testing/Fakes/PendingChainFake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\PendingMailFake' => $vendorDir . '/illuminate/support/Testing/Fakes/PendingMailFake.php',
+    'Illuminate\\Support\\Testing\\Fakes\\QueueFake' => $vendorDir . '/illuminate/support/Testing/Fakes/QueueFake.php',
+    'Illuminate\\Support\\Timebox' => $vendorDir . '/illuminate/support/Timebox.php',
+    'Illuminate\\Support\\Traits\\CapsuleManagerTrait' => $vendorDir . '/illuminate/support/Traits/CapsuleManagerTrait.php',
+    'Illuminate\\Support\\Traits\\Conditionable' => $vendorDir . '/illuminate/conditionable/Traits/Conditionable.php',
+    'Illuminate\\Support\\Traits\\EnumeratesValues' => $vendorDir . '/illuminate/collections/Traits/EnumeratesValues.php',
+    'Illuminate\\Support\\Traits\\ForwardsCalls' => $vendorDir . '/illuminate/support/Traits/ForwardsCalls.php',
+    'Illuminate\\Support\\Traits\\Localizable' => $vendorDir . '/illuminate/support/Traits/Localizable.php',
+    'Illuminate\\Support\\Traits\\Macroable' => $vendorDir . '/illuminate/macroable/Traits/Macroable.php',
+    'Illuminate\\Support\\Traits\\ReflectsClosures' => $vendorDir . '/illuminate/support/Traits/ReflectsClosures.php',
+    'Illuminate\\Support\\Traits\\Tappable' => $vendorDir . '/illuminate/support/Traits/Tappable.php',
+    'Illuminate\\Support\\ValidatedInput' => $vendorDir . '/illuminate/support/ValidatedInput.php',
+    'Illuminate\\Support\\ViewErrorBag' => $vendorDir . '/illuminate/support/ViewErrorBag.php',
     'JetBrains\\PhpStorm\\ArrayShape' => $vendorDir . '/jetbrains/phpstorm-attributes/src/ArrayShape.php',
     'JetBrains\\PhpStorm\\Deprecated' => $vendorDir . '/jetbrains/phpstorm-attributes/src/Deprecated.php',
     'JetBrains\\PhpStorm\\ExpectedValues' => $vendorDir . '/jetbrains/phpstorm-attributes/src/ExpectedValues.php',
@@ -4711,4 +4997,5 @@ return array(
     'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php',
     'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
     'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
+    'voku\\helper\\ASCII' => $vendorDir . '/voku/portable-ascii/src/voku/helper/ASCII.php',
 );

+ 2 - 0
vendor/composer/autoload_files.php

@@ -24,9 +24,11 @@ return array(
     'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
     '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
     'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
+    '60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php',
     '253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
     '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
     '662a729f963d39afe703c9d9b7ab4a8c' => $vendorDir . '/symfony/polyfill-php83/bootstrap.php',
+    '72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php',
     'ec07570ca5a812141189b1fa81503674' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert/Functions.php',
     '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
     '6ca3f08a814c4fd9d5830fc6808a9488' => $vendorDir . '/fukuball/jieba-php/src/vendor/multi-array/MultiArray.php',

+ 4 - 0
vendor/composer/autoload_psr4.php

@@ -6,6 +6,7 @@ $vendorDir = dirname(__DIR__);
 $baseDir = dirname($vendorDir);
 
 return array(
+    'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'),
     'Symfony\\Polyfill\\Php83\\' => array($vendorDir . '/symfony/polyfill-php83'),
     'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'),
     'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
@@ -55,6 +56,9 @@ return array(
     'Laminas\\Stdlib\\' => array($vendorDir . '/laminas/laminas-stdlib/src'),
     'Laminas\\Mime\\' => array($vendorDir . '/laminas/laminas-mime/src'),
     'JetBrains\\PhpStorm\\' => array($vendorDir . '/jetbrains/phpstorm-attributes/src'),
+    'Illuminate\\Support\\' => array($vendorDir . '/illuminate/support', $vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/conditionable', $vendorDir . '/illuminate/macroable'),
+    'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'),
+    'Illuminate\\Cache\\' => array($vendorDir . '/illuminate/cache'),
     'Hyperf\\Watcher\\' => array($vendorDir . '/hyperf/watcher/src'),
     'Hyperf\\Testing\\' => array($vendorDir . '/hyperf/testing/src'),
     'Hyperf\\Tappable\\' => array($vendorDir . '/hyperf/tappable/src'),

+ 318 - 0
vendor/composer/autoload_static.php

@@ -25,9 +25,11 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
         '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
         'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
+        '60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php',
         '253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
         '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
         '662a729f963d39afe703c9d9b7ab4a8c' => __DIR__ . '/..' . '/symfony/polyfill-php83/bootstrap.php',
+        '72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php',
         'ec07570ca5a812141189b1fa81503674' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert/Functions.php',
         '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
         '6ca3f08a814c4fd9d5830fc6808a9488' => __DIR__ . '/..' . '/fukuball/jieba-php/src/vendor/multi-array/MultiArray.php',
@@ -41,6 +43,10 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
     );
 
     public static $prefixLengthsPsr4 = array (
+        'v' => 
+        array (
+            'voku\\' => 5,
+        ),
         'S' => 
         array (
             'Symfony\\Polyfill\\Php83\\' => 23,
@@ -108,6 +114,12 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         array (
             'JetBrains\\PhpStorm\\' => 19,
         ),
+        'I' => 
+        array (
+            'Illuminate\\Support\\' => 19,
+            'Illuminate\\Contracts\\' => 21,
+            'Illuminate\\Cache\\' => 17,
+        ),
         'H' => 
         array (
             'Hyperf\\Watcher\\' => 15,
@@ -213,6 +225,10 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
     );
 
     public static $prefixDirsPsr4 = array (
+        'voku\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/voku/portable-ascii/src/voku',
+        ),
         'Symfony\\Polyfill\\Php83\\' => 
         array (
             0 => __DIR__ . '/..' . '/symfony/polyfill-php83',
@@ -411,6 +427,21 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         array (
             0 => __DIR__ . '/..' . '/jetbrains/phpstorm-attributes/src',
         ),
+        'Illuminate\\Support\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/illuminate/support',
+            1 => __DIR__ . '/..' . '/illuminate/collections',
+            2 => __DIR__ . '/..' . '/illuminate/conditionable',
+            3 => __DIR__ . '/..' . '/illuminate/macroable',
+        ),
+        'Illuminate\\Contracts\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/illuminate/contracts',
+        ),
+        'Illuminate\\Cache\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/illuminate/cache',
+        ),
         'Hyperf\\Watcher\\' => 
         array (
             0 => __DIR__ . '/..' . '/hyperf/watcher/src',
@@ -740,11 +771,16 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'App\\Model\\ArticleSurvey' => __DIR__ . '/../..' . '/app/Model/ArticleSurvey.php',
         'App\\Model\\Book' => __DIR__ . '/../..' . '/app/Model/Book.php',
         'App\\Model\\Category' => __DIR__ . '/../..' . '/app/Model/Category.php',
+        'App\\Model\\Character' => __DIR__ . '/../..' . '/app/Model/Character.php',
         'App\\Model\\ChatGroups' => __DIR__ . '/../..' . '/app/Model/ChatGroups.php',
         'App\\Model\\ChatGroupsMember' => __DIR__ . '/../..' . '/app/Model/ChatGroupsMember.php',
         'App\\Model\\ChatRecords' => __DIR__ . '/../..' . '/app/Model/ChatRecords.php',
+        'App\\Model\\Couplet' => __DIR__ . '/../..' . '/app/Model/Couplet.php',
         'App\\Model\\District' => __DIR__ . '/../..' . '/app/Model/District.php',
+        'App\\Model\\Festival' => __DIR__ . '/../..' . '/app/Model/Festival.php',
         'App\\Model\\Good' => __DIR__ . '/../..' . '/app/Model/Good.php',
+        'App\\Model\\HistoryToday' => __DIR__ . '/../..' . '/app/Model/HistoryToday.php',
+        'App\\Model\\Idiom' => __DIR__ . '/../..' . '/app/Model/Idiom.php',
         'App\\Model\\JobApply' => __DIR__ . '/../..' . '/app/Model/JobApply.php',
         'App\\Model\\JobCompany' => __DIR__ . '/../..' . '/app/Model/JobCompany.php',
         'App\\Model\\JobEnum' => __DIR__ . '/../..' . '/app/Model/JobEnum.php',
@@ -757,6 +793,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'App\\Model\\Link' => __DIR__ . '/../..' . '/app/Model/Link.php',
         'App\\Model\\Model' => __DIR__ . '/../..' . '/app/Model/Model.php',
         'App\\Model\\Notice' => __DIR__ . '/../..' . '/app/Model/Notice.php',
+        'App\\Model\\Riddle' => __DIR__ . '/../..' . '/app/Model/Riddle.php',
         'App\\Model\\User' => __DIR__ . '/../..' . '/app/Model/User.php',
         'App\\Model\\UserInfo' => __DIR__ . '/../..' . '/app/Model/UserInfo.php',
         'App\\Model\\Web' => __DIR__ . '/../..' . '/app/Model/Web.php',
@@ -2292,6 +2329,286 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'Hyperf\\Watcher\\Option' => __DIR__ . '/..' . '/hyperf/watcher/src/Option.php',
         'Hyperf\\Watcher\\Process' => __DIR__ . '/..' . '/hyperf/watcher/src/Process.php',
         'Hyperf\\Watcher\\Watcher' => __DIR__ . '/..' . '/hyperf/watcher/src/Watcher.php',
+        'Illuminate\\Cache\\ApcStore' => __DIR__ . '/..' . '/illuminate/cache/ApcStore.php',
+        'Illuminate\\Cache\\ApcWrapper' => __DIR__ . '/..' . '/illuminate/cache/ApcWrapper.php',
+        'Illuminate\\Cache\\ArrayLock' => __DIR__ . '/..' . '/illuminate/cache/ArrayLock.php',
+        'Illuminate\\Cache\\ArrayStore' => __DIR__ . '/..' . '/illuminate/cache/ArrayStore.php',
+        'Illuminate\\Cache\\CacheLock' => __DIR__ . '/..' . '/illuminate/cache/CacheLock.php',
+        'Illuminate\\Cache\\CacheManager' => __DIR__ . '/..' . '/illuminate/cache/CacheManager.php',
+        'Illuminate\\Cache\\CacheServiceProvider' => __DIR__ . '/..' . '/illuminate/cache/CacheServiceProvider.php',
+        'Illuminate\\Cache\\Console\\CacheTableCommand' => __DIR__ . '/..' . '/illuminate/cache/Console/CacheTableCommand.php',
+        'Illuminate\\Cache\\Console\\ClearCommand' => __DIR__ . '/..' . '/illuminate/cache/Console/ClearCommand.php',
+        'Illuminate\\Cache\\Console\\ForgetCommand' => __DIR__ . '/..' . '/illuminate/cache/Console/ForgetCommand.php',
+        'Illuminate\\Cache\\Console\\PruneStaleTagsCommand' => __DIR__ . '/..' . '/illuminate/cache/Console/PruneStaleTagsCommand.php',
+        'Illuminate\\Cache\\DatabaseLock' => __DIR__ . '/..' . '/illuminate/cache/DatabaseLock.php',
+        'Illuminate\\Cache\\DatabaseStore' => __DIR__ . '/..' . '/illuminate/cache/DatabaseStore.php',
+        'Illuminate\\Cache\\DynamoDbLock' => __DIR__ . '/..' . '/illuminate/cache/DynamoDbLock.php',
+        'Illuminate\\Cache\\DynamoDbStore' => __DIR__ . '/..' . '/illuminate/cache/DynamoDbStore.php',
+        'Illuminate\\Cache\\Events\\CacheEvent' => __DIR__ . '/..' . '/illuminate/cache/Events/CacheEvent.php',
+        'Illuminate\\Cache\\Events\\CacheHit' => __DIR__ . '/..' . '/illuminate/cache/Events/CacheHit.php',
+        'Illuminate\\Cache\\Events\\CacheMissed' => __DIR__ . '/..' . '/illuminate/cache/Events/CacheMissed.php',
+        'Illuminate\\Cache\\Events\\KeyForgotten' => __DIR__ . '/..' . '/illuminate/cache/Events/KeyForgotten.php',
+        'Illuminate\\Cache\\Events\\KeyWritten' => __DIR__ . '/..' . '/illuminate/cache/Events/KeyWritten.php',
+        'Illuminate\\Cache\\FileLock' => __DIR__ . '/..' . '/illuminate/cache/FileLock.php',
+        'Illuminate\\Cache\\FileStore' => __DIR__ . '/..' . '/illuminate/cache/FileStore.php',
+        'Illuminate\\Cache\\HasCacheLock' => __DIR__ . '/..' . '/illuminate/cache/HasCacheLock.php',
+        'Illuminate\\Cache\\Lock' => __DIR__ . '/..' . '/illuminate/cache/Lock.php',
+        'Illuminate\\Cache\\LuaScripts' => __DIR__ . '/..' . '/illuminate/cache/LuaScripts.php',
+        'Illuminate\\Cache\\MemcachedConnector' => __DIR__ . '/..' . '/illuminate/cache/MemcachedConnector.php',
+        'Illuminate\\Cache\\MemcachedLock' => __DIR__ . '/..' . '/illuminate/cache/MemcachedLock.php',
+        'Illuminate\\Cache\\MemcachedStore' => __DIR__ . '/..' . '/illuminate/cache/MemcachedStore.php',
+        'Illuminate\\Cache\\NoLock' => __DIR__ . '/..' . '/illuminate/cache/NoLock.php',
+        'Illuminate\\Cache\\NullStore' => __DIR__ . '/..' . '/illuminate/cache/NullStore.php',
+        'Illuminate\\Cache\\PhpRedisLock' => __DIR__ . '/..' . '/illuminate/cache/PhpRedisLock.php',
+        'Illuminate\\Cache\\RateLimiter' => __DIR__ . '/..' . '/illuminate/cache/RateLimiter.php',
+        'Illuminate\\Cache\\RateLimiting\\GlobalLimit' => __DIR__ . '/..' . '/illuminate/cache/RateLimiting/GlobalLimit.php',
+        'Illuminate\\Cache\\RateLimiting\\Limit' => __DIR__ . '/..' . '/illuminate/cache/RateLimiting/Limit.php',
+        'Illuminate\\Cache\\RateLimiting\\Unlimited' => __DIR__ . '/..' . '/illuminate/cache/RateLimiting/Unlimited.php',
+        'Illuminate\\Cache\\RedisLock' => __DIR__ . '/..' . '/illuminate/cache/RedisLock.php',
+        'Illuminate\\Cache\\RedisStore' => __DIR__ . '/..' . '/illuminate/cache/RedisStore.php',
+        'Illuminate\\Cache\\RedisTagSet' => __DIR__ . '/..' . '/illuminate/cache/RedisTagSet.php',
+        'Illuminate\\Cache\\RedisTaggedCache' => __DIR__ . '/..' . '/illuminate/cache/RedisTaggedCache.php',
+        'Illuminate\\Cache\\Repository' => __DIR__ . '/..' . '/illuminate/cache/Repository.php',
+        'Illuminate\\Cache\\RetrievesMultipleKeys' => __DIR__ . '/..' . '/illuminate/cache/RetrievesMultipleKeys.php',
+        'Illuminate\\Cache\\TagSet' => __DIR__ . '/..' . '/illuminate/cache/TagSet.php',
+        'Illuminate\\Cache\\TaggableStore' => __DIR__ . '/..' . '/illuminate/cache/TaggableStore.php',
+        'Illuminate\\Cache\\TaggedCache' => __DIR__ . '/..' . '/illuminate/cache/TaggedCache.php',
+        'Illuminate\\Contracts\\Auth\\Access\\Authorizable' => __DIR__ . '/..' . '/illuminate/contracts/Auth/Access/Authorizable.php',
+        'Illuminate\\Contracts\\Auth\\Access\\Gate' => __DIR__ . '/..' . '/illuminate/contracts/Auth/Access/Gate.php',
+        'Illuminate\\Contracts\\Auth\\Authenticatable' => __DIR__ . '/..' . '/illuminate/contracts/Auth/Authenticatable.php',
+        'Illuminate\\Contracts\\Auth\\CanResetPassword' => __DIR__ . '/..' . '/illuminate/contracts/Auth/CanResetPassword.php',
+        'Illuminate\\Contracts\\Auth\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Auth/Factory.php',
+        'Illuminate\\Contracts\\Auth\\Guard' => __DIR__ . '/..' . '/illuminate/contracts/Auth/Guard.php',
+        'Illuminate\\Contracts\\Auth\\Middleware\\AuthenticatesRequests' => __DIR__ . '/..' . '/illuminate/contracts/Auth/Middleware/AuthenticatesRequests.php',
+        'Illuminate\\Contracts\\Auth\\MustVerifyEmail' => __DIR__ . '/..' . '/illuminate/contracts/Auth/MustVerifyEmail.php',
+        'Illuminate\\Contracts\\Auth\\PasswordBroker' => __DIR__ . '/..' . '/illuminate/contracts/Auth/PasswordBroker.php',
+        'Illuminate\\Contracts\\Auth\\PasswordBrokerFactory' => __DIR__ . '/..' . '/illuminate/contracts/Auth/PasswordBrokerFactory.php',
+        'Illuminate\\Contracts\\Auth\\StatefulGuard' => __DIR__ . '/..' . '/illuminate/contracts/Auth/StatefulGuard.php',
+        'Illuminate\\Contracts\\Auth\\SupportsBasicAuth' => __DIR__ . '/..' . '/illuminate/contracts/Auth/SupportsBasicAuth.php',
+        'Illuminate\\Contracts\\Auth\\UserProvider' => __DIR__ . '/..' . '/illuminate/contracts/Auth/UserProvider.php',
+        'Illuminate\\Contracts\\Broadcasting\\Broadcaster' => __DIR__ . '/..' . '/illuminate/contracts/Broadcasting/Broadcaster.php',
+        'Illuminate\\Contracts\\Broadcasting\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Broadcasting/Factory.php',
+        'Illuminate\\Contracts\\Broadcasting\\HasBroadcastChannel' => __DIR__ . '/..' . '/illuminate/contracts/Broadcasting/HasBroadcastChannel.php',
+        'Illuminate\\Contracts\\Broadcasting\\ShouldBeUnique' => __DIR__ . '/..' . '/illuminate/contracts/Broadcasting/ShouldBeUnique.php',
+        'Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast' => __DIR__ . '/..' . '/illuminate/contracts/Broadcasting/ShouldBroadcast.php',
+        'Illuminate\\Contracts\\Broadcasting\\ShouldBroadcastNow' => __DIR__ . '/..' . '/illuminate/contracts/Broadcasting/ShouldBroadcastNow.php',
+        'Illuminate\\Contracts\\Bus\\Dispatcher' => __DIR__ . '/..' . '/illuminate/contracts/Bus/Dispatcher.php',
+        'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => __DIR__ . '/..' . '/illuminate/contracts/Bus/QueueingDispatcher.php',
+        'Illuminate\\Contracts\\Cache\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Cache/Factory.php',
+        'Illuminate\\Contracts\\Cache\\Lock' => __DIR__ . '/..' . '/illuminate/contracts/Cache/Lock.php',
+        'Illuminate\\Contracts\\Cache\\LockProvider' => __DIR__ . '/..' . '/illuminate/contracts/Cache/LockProvider.php',
+        'Illuminate\\Contracts\\Cache\\LockTimeoutException' => __DIR__ . '/..' . '/illuminate/contracts/Cache/LockTimeoutException.php',
+        'Illuminate\\Contracts\\Cache\\Repository' => __DIR__ . '/..' . '/illuminate/contracts/Cache/Repository.php',
+        'Illuminate\\Contracts\\Cache\\Store' => __DIR__ . '/..' . '/illuminate/contracts/Cache/Store.php',
+        'Illuminate\\Contracts\\Config\\Repository' => __DIR__ . '/..' . '/illuminate/contracts/Config/Repository.php',
+        'Illuminate\\Contracts\\Console\\Application' => __DIR__ . '/..' . '/illuminate/contracts/Console/Application.php',
+        'Illuminate\\Contracts\\Console\\Isolatable' => __DIR__ . '/..' . '/illuminate/contracts/Console/Isolatable.php',
+        'Illuminate\\Contracts\\Console\\Kernel' => __DIR__ . '/..' . '/illuminate/contracts/Console/Kernel.php',
+        'Illuminate\\Contracts\\Console\\PromptsForMissingInput' => __DIR__ . '/..' . '/illuminate/contracts/Console/PromptsForMissingInput.php',
+        'Illuminate\\Contracts\\Container\\BindingResolutionException' => __DIR__ . '/..' . '/illuminate/contracts/Container/BindingResolutionException.php',
+        'Illuminate\\Contracts\\Container\\CircularDependencyException' => __DIR__ . '/..' . '/illuminate/contracts/Container/CircularDependencyException.php',
+        'Illuminate\\Contracts\\Container\\Container' => __DIR__ . '/..' . '/illuminate/contracts/Container/Container.php',
+        'Illuminate\\Contracts\\Container\\ContextualBindingBuilder' => __DIR__ . '/..' . '/illuminate/contracts/Container/ContextualBindingBuilder.php',
+        'Illuminate\\Contracts\\Cookie\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Cookie/Factory.php',
+        'Illuminate\\Contracts\\Cookie\\QueueingFactory' => __DIR__ . '/..' . '/illuminate/contracts/Cookie/QueueingFactory.php',
+        'Illuminate\\Contracts\\Database\\Eloquent\\Builder' => __DIR__ . '/..' . '/illuminate/contracts/Database/Eloquent/Builder.php',
+        'Illuminate\\Contracts\\Database\\Eloquent\\Castable' => __DIR__ . '/..' . '/illuminate/contracts/Database/Eloquent/Castable.php',
+        'Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes' => __DIR__ . '/..' . '/illuminate/contracts/Database/Eloquent/CastsAttributes.php',
+        'Illuminate\\Contracts\\Database\\Eloquent\\CastsInboundAttributes' => __DIR__ . '/..' . '/illuminate/contracts/Database/Eloquent/CastsInboundAttributes.php',
+        'Illuminate\\Contracts\\Database\\Eloquent\\DeviatesCastableAttributes' => __DIR__ . '/..' . '/illuminate/contracts/Database/Eloquent/DeviatesCastableAttributes.php',
+        'Illuminate\\Contracts\\Database\\Eloquent\\SerializesCastableAttributes' => __DIR__ . '/..' . '/illuminate/contracts/Database/Eloquent/SerializesCastableAttributes.php',
+        'Illuminate\\Contracts\\Database\\Eloquent\\SupportsPartialRelations' => __DIR__ . '/..' . '/illuminate/contracts/Database/Eloquent/SupportsPartialRelations.php',
+        'Illuminate\\Contracts\\Database\\Events\\MigrationEvent' => __DIR__ . '/..' . '/illuminate/contracts/Database/Events/MigrationEvent.php',
+        'Illuminate\\Contracts\\Database\\ModelIdentifier' => __DIR__ . '/..' . '/illuminate/contracts/Database/ModelIdentifier.php',
+        'Illuminate\\Contracts\\Database\\Query\\Builder' => __DIR__ . '/..' . '/illuminate/contracts/Database/Query/Builder.php',
+        'Illuminate\\Contracts\\Database\\Query\\ConditionExpression' => __DIR__ . '/..' . '/illuminate/contracts/Database/Query/ConditionExpression.php',
+        'Illuminate\\Contracts\\Database\\Query\\Expression' => __DIR__ . '/..' . '/illuminate/contracts/Database/Query/Expression.php',
+        'Illuminate\\Contracts\\Debug\\ExceptionHandler' => __DIR__ . '/..' . '/illuminate/contracts/Debug/ExceptionHandler.php',
+        'Illuminate\\Contracts\\Encryption\\DecryptException' => __DIR__ . '/..' . '/illuminate/contracts/Encryption/DecryptException.php',
+        'Illuminate\\Contracts\\Encryption\\EncryptException' => __DIR__ . '/..' . '/illuminate/contracts/Encryption/EncryptException.php',
+        'Illuminate\\Contracts\\Encryption\\Encrypter' => __DIR__ . '/..' . '/illuminate/contracts/Encryption/Encrypter.php',
+        'Illuminate\\Contracts\\Encryption\\StringEncrypter' => __DIR__ . '/..' . '/illuminate/contracts/Encryption/StringEncrypter.php',
+        'Illuminate\\Contracts\\Events\\Dispatcher' => __DIR__ . '/..' . '/illuminate/contracts/Events/Dispatcher.php',
+        'Illuminate\\Contracts\\Events\\ShouldDispatchAfterCommit' => __DIR__ . '/..' . '/illuminate/contracts/Events/ShouldDispatchAfterCommit.php',
+        'Illuminate\\Contracts\\Events\\ShouldHandleEventsAfterCommit' => __DIR__ . '/..' . '/illuminate/contracts/Events/ShouldHandleEventsAfterCommit.php',
+        'Illuminate\\Contracts\\Filesystem\\Cloud' => __DIR__ . '/..' . '/illuminate/contracts/Filesystem/Cloud.php',
+        'Illuminate\\Contracts\\Filesystem\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Filesystem/Factory.php',
+        'Illuminate\\Contracts\\Filesystem\\FileNotFoundException' => __DIR__ . '/..' . '/illuminate/contracts/Filesystem/FileNotFoundException.php',
+        'Illuminate\\Contracts\\Filesystem\\Filesystem' => __DIR__ . '/..' . '/illuminate/contracts/Filesystem/Filesystem.php',
+        'Illuminate\\Contracts\\Filesystem\\LockTimeoutException' => __DIR__ . '/..' . '/illuminate/contracts/Filesystem/LockTimeoutException.php',
+        'Illuminate\\Contracts\\Foundation\\Application' => __DIR__ . '/..' . '/illuminate/contracts/Foundation/Application.php',
+        'Illuminate\\Contracts\\Foundation\\CachesConfiguration' => __DIR__ . '/..' . '/illuminate/contracts/Foundation/CachesConfiguration.php',
+        'Illuminate\\Contracts\\Foundation\\CachesRoutes' => __DIR__ . '/..' . '/illuminate/contracts/Foundation/CachesRoutes.php',
+        'Illuminate\\Contracts\\Foundation\\ExceptionRenderer' => __DIR__ . '/..' . '/illuminate/contracts/Foundation/ExceptionRenderer.php',
+        'Illuminate\\Contracts\\Foundation\\MaintenanceMode' => __DIR__ . '/..' . '/illuminate/contracts/Foundation/MaintenanceMode.php',
+        'Illuminate\\Contracts\\Hashing\\Hasher' => __DIR__ . '/..' . '/illuminate/contracts/Hashing/Hasher.php',
+        'Illuminate\\Contracts\\Http\\Kernel' => __DIR__ . '/..' . '/illuminate/contracts/Http/Kernel.php',
+        'Illuminate\\Contracts\\Mail\\Attachable' => __DIR__ . '/..' . '/illuminate/contracts/Mail/Attachable.php',
+        'Illuminate\\Contracts\\Mail\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Mail/Factory.php',
+        'Illuminate\\Contracts\\Mail\\MailQueue' => __DIR__ . '/..' . '/illuminate/contracts/Mail/MailQueue.php',
+        'Illuminate\\Contracts\\Mail\\Mailable' => __DIR__ . '/..' . '/illuminate/contracts/Mail/Mailable.php',
+        'Illuminate\\Contracts\\Mail\\Mailer' => __DIR__ . '/..' . '/illuminate/contracts/Mail/Mailer.php',
+        'Illuminate\\Contracts\\Notifications\\Dispatcher' => __DIR__ . '/..' . '/illuminate/contracts/Notifications/Dispatcher.php',
+        'Illuminate\\Contracts\\Notifications\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Notifications/Factory.php',
+        'Illuminate\\Contracts\\Pagination\\CursorPaginator' => __DIR__ . '/..' . '/illuminate/contracts/Pagination/CursorPaginator.php',
+        'Illuminate\\Contracts\\Pagination\\LengthAwarePaginator' => __DIR__ . '/..' . '/illuminate/contracts/Pagination/LengthAwarePaginator.php',
+        'Illuminate\\Contracts\\Pagination\\Paginator' => __DIR__ . '/..' . '/illuminate/contracts/Pagination/Paginator.php',
+        'Illuminate\\Contracts\\Pipeline\\Hub' => __DIR__ . '/..' . '/illuminate/contracts/Pipeline/Hub.php',
+        'Illuminate\\Contracts\\Pipeline\\Pipeline' => __DIR__ . '/..' . '/illuminate/contracts/Pipeline/Pipeline.php',
+        'Illuminate\\Contracts\\Process\\InvokedProcess' => __DIR__ . '/..' . '/illuminate/contracts/Process/InvokedProcess.php',
+        'Illuminate\\Contracts\\Process\\ProcessResult' => __DIR__ . '/..' . '/illuminate/contracts/Process/ProcessResult.php',
+        'Illuminate\\Contracts\\Queue\\ClearableQueue' => __DIR__ . '/..' . '/illuminate/contracts/Queue/ClearableQueue.php',
+        'Illuminate\\Contracts\\Queue\\EntityNotFoundException' => __DIR__ . '/..' . '/illuminate/contracts/Queue/EntityNotFoundException.php',
+        'Illuminate\\Contracts\\Queue\\EntityResolver' => __DIR__ . '/..' . '/illuminate/contracts/Queue/EntityResolver.php',
+        'Illuminate\\Contracts\\Queue\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Queue/Factory.php',
+        'Illuminate\\Contracts\\Queue\\Job' => __DIR__ . '/..' . '/illuminate/contracts/Queue/Job.php',
+        'Illuminate\\Contracts\\Queue\\Monitor' => __DIR__ . '/..' . '/illuminate/contracts/Queue/Monitor.php',
+        'Illuminate\\Contracts\\Queue\\Queue' => __DIR__ . '/..' . '/illuminate/contracts/Queue/Queue.php',
+        'Illuminate\\Contracts\\Queue\\QueueableCollection' => __DIR__ . '/..' . '/illuminate/contracts/Queue/QueueableCollection.php',
+        'Illuminate\\Contracts\\Queue\\QueueableEntity' => __DIR__ . '/..' . '/illuminate/contracts/Queue/QueueableEntity.php',
+        'Illuminate\\Contracts\\Queue\\ShouldBeEncrypted' => __DIR__ . '/..' . '/illuminate/contracts/Queue/ShouldBeEncrypted.php',
+        'Illuminate\\Contracts\\Queue\\ShouldBeUnique' => __DIR__ . '/..' . '/illuminate/contracts/Queue/ShouldBeUnique.php',
+        'Illuminate\\Contracts\\Queue\\ShouldBeUniqueUntilProcessing' => __DIR__ . '/..' . '/illuminate/contracts/Queue/ShouldBeUniqueUntilProcessing.php',
+        'Illuminate\\Contracts\\Queue\\ShouldQueue' => __DIR__ . '/..' . '/illuminate/contracts/Queue/ShouldQueue.php',
+        'Illuminate\\Contracts\\Queue\\ShouldQueueAfterCommit' => __DIR__ . '/..' . '/illuminate/contracts/Queue/ShouldQueueAfterCommit.php',
+        'Illuminate\\Contracts\\Redis\\Connection' => __DIR__ . '/..' . '/illuminate/contracts/Redis/Connection.php',
+        'Illuminate\\Contracts\\Redis\\Connector' => __DIR__ . '/..' . '/illuminate/contracts/Redis/Connector.php',
+        'Illuminate\\Contracts\\Redis\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Redis/Factory.php',
+        'Illuminate\\Contracts\\Redis\\LimiterTimeoutException' => __DIR__ . '/..' . '/illuminate/contracts/Redis/LimiterTimeoutException.php',
+        'Illuminate\\Contracts\\Routing\\BindingRegistrar' => __DIR__ . '/..' . '/illuminate/contracts/Routing/BindingRegistrar.php',
+        'Illuminate\\Contracts\\Routing\\Registrar' => __DIR__ . '/..' . '/illuminate/contracts/Routing/Registrar.php',
+        'Illuminate\\Contracts\\Routing\\ResponseFactory' => __DIR__ . '/..' . '/illuminate/contracts/Routing/ResponseFactory.php',
+        'Illuminate\\Contracts\\Routing\\UrlGenerator' => __DIR__ . '/..' . '/illuminate/contracts/Routing/UrlGenerator.php',
+        'Illuminate\\Contracts\\Routing\\UrlRoutable' => __DIR__ . '/..' . '/illuminate/contracts/Routing/UrlRoutable.php',
+        'Illuminate\\Contracts\\Session\\Middleware\\AuthenticatesSessions' => __DIR__ . '/..' . '/illuminate/contracts/Session/Middleware/AuthenticatesSessions.php',
+        'Illuminate\\Contracts\\Session\\Session' => __DIR__ . '/..' . '/illuminate/contracts/Session/Session.php',
+        'Illuminate\\Contracts\\Support\\Arrayable' => __DIR__ . '/..' . '/illuminate/contracts/Support/Arrayable.php',
+        'Illuminate\\Contracts\\Support\\CanBeEscapedWhenCastToString' => __DIR__ . '/..' . '/illuminate/contracts/Support/CanBeEscapedWhenCastToString.php',
+        'Illuminate\\Contracts\\Support\\DeferrableProvider' => __DIR__ . '/..' . '/illuminate/contracts/Support/DeferrableProvider.php',
+        'Illuminate\\Contracts\\Support\\DeferringDisplayableValue' => __DIR__ . '/..' . '/illuminate/contracts/Support/DeferringDisplayableValue.php',
+        'Illuminate\\Contracts\\Support\\Htmlable' => __DIR__ . '/..' . '/illuminate/contracts/Support/Htmlable.php',
+        'Illuminate\\Contracts\\Support\\Jsonable' => __DIR__ . '/..' . '/illuminate/contracts/Support/Jsonable.php',
+        'Illuminate\\Contracts\\Support\\MessageBag' => __DIR__ . '/..' . '/illuminate/contracts/Support/MessageBag.php',
+        'Illuminate\\Contracts\\Support\\MessageProvider' => __DIR__ . '/..' . '/illuminate/contracts/Support/MessageProvider.php',
+        'Illuminate\\Contracts\\Support\\Renderable' => __DIR__ . '/..' . '/illuminate/contracts/Support/Renderable.php',
+        'Illuminate\\Contracts\\Support\\Responsable' => __DIR__ . '/..' . '/illuminate/contracts/Support/Responsable.php',
+        'Illuminate\\Contracts\\Support\\ValidatedData' => __DIR__ . '/..' . '/illuminate/contracts/Support/ValidatedData.php',
+        'Illuminate\\Contracts\\Translation\\HasLocalePreference' => __DIR__ . '/..' . '/illuminate/contracts/Translation/HasLocalePreference.php',
+        'Illuminate\\Contracts\\Translation\\Loader' => __DIR__ . '/..' . '/illuminate/contracts/Translation/Loader.php',
+        'Illuminate\\Contracts\\Translation\\Translator' => __DIR__ . '/..' . '/illuminate/contracts/Translation/Translator.php',
+        'Illuminate\\Contracts\\Validation\\DataAwareRule' => __DIR__ . '/..' . '/illuminate/contracts/Validation/DataAwareRule.php',
+        'Illuminate\\Contracts\\Validation\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/Validation/Factory.php',
+        'Illuminate\\Contracts\\Validation\\ImplicitRule' => __DIR__ . '/..' . '/illuminate/contracts/Validation/ImplicitRule.php',
+        'Illuminate\\Contracts\\Validation\\InvokableRule' => __DIR__ . '/..' . '/illuminate/contracts/Validation/InvokableRule.php',
+        'Illuminate\\Contracts\\Validation\\Rule' => __DIR__ . '/..' . '/illuminate/contracts/Validation/Rule.php',
+        'Illuminate\\Contracts\\Validation\\UncompromisedVerifier' => __DIR__ . '/..' . '/illuminate/contracts/Validation/UncompromisedVerifier.php',
+        'Illuminate\\Contracts\\Validation\\ValidatesWhenResolved' => __DIR__ . '/..' . '/illuminate/contracts/Validation/ValidatesWhenResolved.php',
+        'Illuminate\\Contracts\\Validation\\ValidationRule' => __DIR__ . '/..' . '/illuminate/contracts/Validation/ValidationRule.php',
+        'Illuminate\\Contracts\\Validation\\Validator' => __DIR__ . '/..' . '/illuminate/contracts/Validation/Validator.php',
+        'Illuminate\\Contracts\\Validation\\ValidatorAwareRule' => __DIR__ . '/..' . '/illuminate/contracts/Validation/ValidatorAwareRule.php',
+        'Illuminate\\Contracts\\View\\Engine' => __DIR__ . '/..' . '/illuminate/contracts/View/Engine.php',
+        'Illuminate\\Contracts\\View\\Factory' => __DIR__ . '/..' . '/illuminate/contracts/View/Factory.php',
+        'Illuminate\\Contracts\\View\\View' => __DIR__ . '/..' . '/illuminate/contracts/View/View.php',
+        'Illuminate\\Contracts\\View\\ViewCompilationException' => __DIR__ . '/..' . '/illuminate/contracts/View/ViewCompilationException.php',
+        'Illuminate\\Support\\AggregateServiceProvider' => __DIR__ . '/..' . '/illuminate/support/AggregateServiceProvider.php',
+        'Illuminate\\Support\\Arr' => __DIR__ . '/..' . '/illuminate/collections/Arr.php',
+        'Illuminate\\Support\\Benchmark' => __DIR__ . '/..' . '/illuminate/support/Benchmark.php',
+        'Illuminate\\Support\\Carbon' => __DIR__ . '/..' . '/illuminate/support/Carbon.php',
+        'Illuminate\\Support\\Collection' => __DIR__ . '/..' . '/illuminate/collections/Collection.php',
+        'Illuminate\\Support\\Composer' => __DIR__ . '/..' . '/illuminate/support/Composer.php',
+        'Illuminate\\Support\\ConfigurationUrlParser' => __DIR__ . '/..' . '/illuminate/support/ConfigurationUrlParser.php',
+        'Illuminate\\Support\\DateFactory' => __DIR__ . '/..' . '/illuminate/support/DateFactory.php',
+        'Illuminate\\Support\\DefaultProviders' => __DIR__ . '/..' . '/illuminate/support/DefaultProviders.php',
+        'Illuminate\\Support\\Enumerable' => __DIR__ . '/..' . '/illuminate/collections/Enumerable.php',
+        'Illuminate\\Support\\Env' => __DIR__ . '/..' . '/illuminate/support/Env.php',
+        'Illuminate\\Support\\Exceptions\\MathException' => __DIR__ . '/..' . '/illuminate/support/Exceptions/MathException.php',
+        'Illuminate\\Support\\Facades\\App' => __DIR__ . '/..' . '/illuminate/support/Facades/App.php',
+        'Illuminate\\Support\\Facades\\Artisan' => __DIR__ . '/..' . '/illuminate/support/Facades/Artisan.php',
+        'Illuminate\\Support\\Facades\\Auth' => __DIR__ . '/..' . '/illuminate/support/Facades/Auth.php',
+        'Illuminate\\Support\\Facades\\Blade' => __DIR__ . '/..' . '/illuminate/support/Facades/Blade.php',
+        'Illuminate\\Support\\Facades\\Broadcast' => __DIR__ . '/..' . '/illuminate/support/Facades/Broadcast.php',
+        'Illuminate\\Support\\Facades\\Bus' => __DIR__ . '/..' . '/illuminate/support/Facades/Bus.php',
+        'Illuminate\\Support\\Facades\\Cache' => __DIR__ . '/..' . '/illuminate/support/Facades/Cache.php',
+        'Illuminate\\Support\\Facades\\Config' => __DIR__ . '/..' . '/illuminate/support/Facades/Config.php',
+        'Illuminate\\Support\\Facades\\Cookie' => __DIR__ . '/..' . '/illuminate/support/Facades/Cookie.php',
+        'Illuminate\\Support\\Facades\\Crypt' => __DIR__ . '/..' . '/illuminate/support/Facades/Crypt.php',
+        'Illuminate\\Support\\Facades\\DB' => __DIR__ . '/..' . '/illuminate/support/Facades/DB.php',
+        'Illuminate\\Support\\Facades\\Date' => __DIR__ . '/..' . '/illuminate/support/Facades/Date.php',
+        'Illuminate\\Support\\Facades\\Event' => __DIR__ . '/..' . '/illuminate/support/Facades/Event.php',
+        'Illuminate\\Support\\Facades\\Facade' => __DIR__ . '/..' . '/illuminate/support/Facades/Facade.php',
+        'Illuminate\\Support\\Facades\\File' => __DIR__ . '/..' . '/illuminate/support/Facades/File.php',
+        'Illuminate\\Support\\Facades\\Gate' => __DIR__ . '/..' . '/illuminate/support/Facades/Gate.php',
+        'Illuminate\\Support\\Facades\\Hash' => __DIR__ . '/..' . '/illuminate/support/Facades/Hash.php',
+        'Illuminate\\Support\\Facades\\Http' => __DIR__ . '/..' . '/illuminate/support/Facades/Http.php',
+        'Illuminate\\Support\\Facades\\Lang' => __DIR__ . '/..' . '/illuminate/support/Facades/Lang.php',
+        'Illuminate\\Support\\Facades\\Log' => __DIR__ . '/..' . '/illuminate/support/Facades/Log.php',
+        'Illuminate\\Support\\Facades\\Mail' => __DIR__ . '/..' . '/illuminate/support/Facades/Mail.php',
+        'Illuminate\\Support\\Facades\\Notification' => __DIR__ . '/..' . '/illuminate/support/Facades/Notification.php',
+        'Illuminate\\Support\\Facades\\ParallelTesting' => __DIR__ . '/..' . '/illuminate/support/Facades/ParallelTesting.php',
+        'Illuminate\\Support\\Facades\\Password' => __DIR__ . '/..' . '/illuminate/support/Facades/Password.php',
+        'Illuminate\\Support\\Facades\\Pipeline' => __DIR__ . '/..' . '/illuminate/support/Facades/Pipeline.php',
+        'Illuminate\\Support\\Facades\\Process' => __DIR__ . '/..' . '/illuminate/support/Facades/Process.php',
+        'Illuminate\\Support\\Facades\\Queue' => __DIR__ . '/..' . '/illuminate/support/Facades/Queue.php',
+        'Illuminate\\Support\\Facades\\RateLimiter' => __DIR__ . '/..' . '/illuminate/support/Facades/RateLimiter.php',
+        'Illuminate\\Support\\Facades\\Redirect' => __DIR__ . '/..' . '/illuminate/support/Facades/Redirect.php',
+        'Illuminate\\Support\\Facades\\Redis' => __DIR__ . '/..' . '/illuminate/support/Facades/Redis.php',
+        'Illuminate\\Support\\Facades\\Request' => __DIR__ . '/..' . '/illuminate/support/Facades/Request.php',
+        'Illuminate\\Support\\Facades\\Response' => __DIR__ . '/..' . '/illuminate/support/Facades/Response.php',
+        'Illuminate\\Support\\Facades\\Route' => __DIR__ . '/..' . '/illuminate/support/Facades/Route.php',
+        'Illuminate\\Support\\Facades\\Schema' => __DIR__ . '/..' . '/illuminate/support/Facades/Schema.php',
+        'Illuminate\\Support\\Facades\\Session' => __DIR__ . '/..' . '/illuminate/support/Facades/Session.php',
+        'Illuminate\\Support\\Facades\\Storage' => __DIR__ . '/..' . '/illuminate/support/Facades/Storage.php',
+        'Illuminate\\Support\\Facades\\URL' => __DIR__ . '/..' . '/illuminate/support/Facades/URL.php',
+        'Illuminate\\Support\\Facades\\Validator' => __DIR__ . '/..' . '/illuminate/support/Facades/Validator.php',
+        'Illuminate\\Support\\Facades\\View' => __DIR__ . '/..' . '/illuminate/support/Facades/View.php',
+        'Illuminate\\Support\\Facades\\Vite' => __DIR__ . '/..' . '/illuminate/support/Facades/Vite.php',
+        'Illuminate\\Support\\Fluent' => __DIR__ . '/..' . '/illuminate/support/Fluent.php',
+        'Illuminate\\Support\\HigherOrderCollectionProxy' => __DIR__ . '/..' . '/illuminate/collections/HigherOrderCollectionProxy.php',
+        'Illuminate\\Support\\HigherOrderTapProxy' => __DIR__ . '/..' . '/illuminate/support/HigherOrderTapProxy.php',
+        'Illuminate\\Support\\HigherOrderWhenProxy' => __DIR__ . '/..' . '/illuminate/conditionable/HigherOrderWhenProxy.php',
+        'Illuminate\\Support\\HtmlString' => __DIR__ . '/..' . '/illuminate/support/HtmlString.php',
+        'Illuminate\\Support\\InteractsWithTime' => __DIR__ . '/..' . '/illuminate/support/InteractsWithTime.php',
+        'Illuminate\\Support\\ItemNotFoundException' => __DIR__ . '/..' . '/illuminate/collections/ItemNotFoundException.php',
+        'Illuminate\\Support\\Js' => __DIR__ . '/..' . '/illuminate/support/Js.php',
+        'Illuminate\\Support\\LazyCollection' => __DIR__ . '/..' . '/illuminate/collections/LazyCollection.php',
+        'Illuminate\\Support\\Lottery' => __DIR__ . '/..' . '/illuminate/support/Lottery.php',
+        'Illuminate\\Support\\Manager' => __DIR__ . '/..' . '/illuminate/support/Manager.php',
+        'Illuminate\\Support\\MessageBag' => __DIR__ . '/..' . '/illuminate/support/MessageBag.php',
+        'Illuminate\\Support\\MultipleInstanceManager' => __DIR__ . '/..' . '/illuminate/support/MultipleInstanceManager.php',
+        'Illuminate\\Support\\MultipleItemsFoundException' => __DIR__ . '/..' . '/illuminate/collections/MultipleItemsFoundException.php',
+        'Illuminate\\Support\\NamespacedItemResolver' => __DIR__ . '/..' . '/illuminate/support/NamespacedItemResolver.php',
+        'Illuminate\\Support\\Number' => __DIR__ . '/..' . '/illuminate/support/Number.php',
+        'Illuminate\\Support\\Optional' => __DIR__ . '/..' . '/illuminate/support/Optional.php',
+        'Illuminate\\Support\\Pluralizer' => __DIR__ . '/..' . '/illuminate/support/Pluralizer.php',
+        'Illuminate\\Support\\ProcessUtils' => __DIR__ . '/..' . '/illuminate/support/ProcessUtils.php',
+        'Illuminate\\Support\\Reflector' => __DIR__ . '/..' . '/illuminate/support/Reflector.php',
+        'Illuminate\\Support\\ServiceProvider' => __DIR__ . '/..' . '/illuminate/support/ServiceProvider.php',
+        'Illuminate\\Support\\Sleep' => __DIR__ . '/..' . '/illuminate/support/Sleep.php',
+        'Illuminate\\Support\\Str' => __DIR__ . '/..' . '/illuminate/support/Str.php',
+        'Illuminate\\Support\\Stringable' => __DIR__ . '/..' . '/illuminate/support/Stringable.php',
+        'Illuminate\\Support\\Testing\\Fakes\\BatchFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/BatchFake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\BatchRepositoryFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/BatchRepositoryFake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\BusFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/BusFake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\ChainedBatchTruthTest' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/ChainedBatchTruthTest.php',
+        'Illuminate\\Support\\Testing\\Fakes\\EventFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/EventFake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\Fake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/Fake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\MailFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/MailFake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\NotificationFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/NotificationFake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\PendingBatchFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/PendingBatchFake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\PendingChainFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/PendingChainFake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\PendingMailFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/PendingMailFake.php',
+        'Illuminate\\Support\\Testing\\Fakes\\QueueFake' => __DIR__ . '/..' . '/illuminate/support/Testing/Fakes/QueueFake.php',
+        'Illuminate\\Support\\Timebox' => __DIR__ . '/..' . '/illuminate/support/Timebox.php',
+        'Illuminate\\Support\\Traits\\CapsuleManagerTrait' => __DIR__ . '/..' . '/illuminate/support/Traits/CapsuleManagerTrait.php',
+        'Illuminate\\Support\\Traits\\Conditionable' => __DIR__ . '/..' . '/illuminate/conditionable/Traits/Conditionable.php',
+        'Illuminate\\Support\\Traits\\EnumeratesValues' => __DIR__ . '/..' . '/illuminate/collections/Traits/EnumeratesValues.php',
+        'Illuminate\\Support\\Traits\\ForwardsCalls' => __DIR__ . '/..' . '/illuminate/support/Traits/ForwardsCalls.php',
+        'Illuminate\\Support\\Traits\\Localizable' => __DIR__ . '/..' . '/illuminate/support/Traits/Localizable.php',
+        'Illuminate\\Support\\Traits\\Macroable' => __DIR__ . '/..' . '/illuminate/macroable/Traits/Macroable.php',
+        'Illuminate\\Support\\Traits\\ReflectsClosures' => __DIR__ . '/..' . '/illuminate/support/Traits/ReflectsClosures.php',
+        'Illuminate\\Support\\Traits\\Tappable' => __DIR__ . '/..' . '/illuminate/support/Traits/Tappable.php',
+        'Illuminate\\Support\\ValidatedInput' => __DIR__ . '/..' . '/illuminate/support/ValidatedInput.php',
+        'Illuminate\\Support\\ViewErrorBag' => __DIR__ . '/..' . '/illuminate/support/ViewErrorBag.php',
         'JetBrains\\PhpStorm\\ArrayShape' => __DIR__ . '/..' . '/jetbrains/phpstorm-attributes/src/ArrayShape.php',
         'JetBrains\\PhpStorm\\Deprecated' => __DIR__ . '/..' . '/jetbrains/phpstorm-attributes/src/Deprecated.php',
         'JetBrains\\PhpStorm\\ExpectedValues' => __DIR__ . '/..' . '/jetbrains/phpstorm-attributes/src/ExpectedValues.php',
@@ -5431,6 +5748,7 @@ class ComposerStaticInit88f2a4d4a4e81dc7d415bcdf39930654
         'TheSeer\\Tokenizer\\XMLSerializer' => __DIR__ . '/..' . '/theseer/tokenizer/src/XMLSerializer.php',
         'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
         'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
+        'voku\\helper\\ASCII' => __DIR__ . '/..' . '/voku/portable-ascii/src/voku/helper/ASCII.php',
     );
 
     public static function getInitializer(ClassLoader $loader)

+ 465 - 0
vendor/composer/installed.json

@@ -5427,6 +5427,388 @@
             ],
             "install-path": "../hyperf/watcher"
         },
+        {
+            "name": "illuminate/cache",
+            "version": "v10.48.28",
+            "version_normalized": "10.48.28.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/cache.git",
+                "reference": "20f36c3209107ee5c8c646f88a0562a2c1b05a6c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/cache/zipball/20f36c3209107ee5c8c646f88a0562a2c1b05a6c",
+                "reference": "20f36c3209107ee5c8c646f88a0562a2c1b05a6c",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "illuminate/collections": "^10.0",
+                "illuminate/contracts": "^10.0",
+                "illuminate/macroable": "^10.0",
+                "illuminate/support": "^10.0",
+                "php": "^8.1"
+            },
+            "provide": {
+                "psr/simple-cache-implementation": "1.0|2.0|3.0"
+            },
+            "suggest": {
+                "ext-apcu": "Required to use the APC cache driver.",
+                "ext-filter": "Required to use the DynamoDb cache driver.",
+                "ext-memcached": "Required to use the memcache cache driver.",
+                "illuminate/database": "Required to use the database cache driver (^10.0).",
+                "illuminate/filesystem": "Required to use the file cache driver (^10.0).",
+                "illuminate/redis": "Required to use the redis cache driver (^10.0).",
+                "symfony/cache": "Required to use PSR-6 cache bridge (^6.2)."
+            },
+            "time": "2024-11-21T14:02:44+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Cache\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Cache package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "install-path": "../illuminate/cache"
+        },
+        {
+            "name": "illuminate/collections",
+            "version": "v10.48.28",
+            "version_normalized": "10.48.28.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/collections.git",
+                "reference": "48de3d6bc6aa779112ddcb608a3a96fc975d89d8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/collections/zipball/48de3d6bc6aa779112ddcb608a3a96fc975d89d8",
+                "reference": "48de3d6bc6aa779112ddcb608a3a96fc975d89d8",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "illuminate/conditionable": "^10.0",
+                "illuminate/contracts": "^10.0",
+                "illuminate/macroable": "^10.0",
+                "php": "^8.1"
+            },
+            "suggest": {
+                "symfony/var-dumper": "Required to use the dump method (^6.2)."
+            },
+            "time": "2024-11-21T14:02:44+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "helpers.php"
+                ],
+                "psr-4": {
+                    "Illuminate\\Support\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Collections package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "install-path": "../illuminate/collections"
+        },
+        {
+            "name": "illuminate/conditionable",
+            "version": "v10.48.28",
+            "version_normalized": "10.48.28.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/conditionable.git",
+                "reference": "3ee34ac306fafc2a6f19cd7cd68c9af389e432a5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/conditionable/zipball/3ee34ac306fafc2a6f19cd7cd68c9af389e432a5",
+                "reference": "3ee34ac306fafc2a6f19cd7cd68c9af389e432a5",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^8.0.2"
+            },
+            "time": "2024-11-21T14:02:44+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Support\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Conditionable package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "install-path": "../illuminate/conditionable"
+        },
+        {
+            "name": "illuminate/contracts",
+            "version": "v10.48.28",
+            "version_normalized": "10.48.28.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/contracts.git",
+                "reference": "f90663a69f926105a70b78060a31f3c64e2d1c74"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/contracts/zipball/f90663a69f926105a70b78060a31f3c64e2d1c74",
+                "reference": "f90663a69f926105a70b78060a31f3c64e2d1c74",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^8.1",
+                "psr/container": "^1.1.1|^2.0.1",
+                "psr/simple-cache": "^1.0|^2.0|^3.0"
+            },
+            "time": "2024-11-21T14:02:44+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Contracts\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Contracts package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "install-path": "../illuminate/contracts"
+        },
+        {
+            "name": "illuminate/macroable",
+            "version": "v10.48.28",
+            "version_normalized": "10.48.28.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/macroable.git",
+                "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/macroable/zipball/dff667a46ac37b634dcf68909d9d41e94dc97c27",
+                "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^8.1"
+            },
+            "time": "2023-06-05T12:46:42+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Illuminate\\Support\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Macroable package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "install-path": "../illuminate/macroable"
+        },
+        {
+            "name": "illuminate/support",
+            "version": "v10.48.28",
+            "version_normalized": "10.48.28.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/illuminate/support.git",
+                "reference": "6d09b480d34846245d9288f4dcefb17a73ce6e6a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/illuminate/support/zipball/6d09b480d34846245d9288f4dcefb17a73ce6e6a",
+                "reference": "6d09b480d34846245d9288f4dcefb17a73ce6e6a",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "doctrine/inflector": "^2.0",
+                "ext-ctype": "*",
+                "ext-filter": "*",
+                "ext-mbstring": "*",
+                "illuminate/collections": "^10.0",
+                "illuminate/conditionable": "^10.0",
+                "illuminate/contracts": "^10.0",
+                "illuminate/macroable": "^10.0",
+                "nesbot/carbon": "^2.67",
+                "php": "^8.1",
+                "voku/portable-ascii": "^2.0"
+            },
+            "conflict": {
+                "tightenco/collect": "<5.5.33"
+            },
+            "suggest": {
+                "illuminate/filesystem": "Required to use the composer class (^10.0).",
+                "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.6).",
+                "ramsey/uuid": "Required to use Str::uuid() (^4.7).",
+                "symfony/process": "Required to use the composer class (^6.2).",
+                "symfony/uid": "Required to use Str::ulid() (^6.2).",
+                "symfony/var-dumper": "Required to use the dd function (^6.2).",
+                "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)."
+            },
+            "time": "2024-12-10T14:47:55+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "10.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "helpers.php"
+                ],
+                "psr-4": {
+                    "Illuminate\\Support\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "The Illuminate Support package.",
+            "homepage": "https://laravel.com",
+            "support": {
+                "issues": "https://github.com/laravel/framework/issues",
+                "source": "https://github.com/laravel/framework"
+            },
+            "install-path": "../illuminate/support"
+        },
         {
             "name": "jetbrains/phpstorm-attributes",
             "version": "1.1",
@@ -11135,6 +11517,89 @@
                 }
             ],
             "install-path": "../vlucas/phpdotenv"
+        },
+        {
+            "name": "voku/portable-ascii",
+            "version": "2.0.2",
+            "version_normalized": "2.0.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/voku/portable-ascii.git",
+                "reference": "16c17671a804bb92602822113dd91fbc8a35d2af"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/voku/portable-ascii/zipball/16c17671a804bb92602822113dd91fbc8a35d2af",
+                "reference": "16c17671a804bb92602822113dd91fbc8a35d2af",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.0.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
+            },
+            "suggest": {
+                "ext-intl": "Use Intl for transliterator_transliterate() support"
+            },
+            "time": "2024-11-21T00:49:12+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "voku\\": "src/voku/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Lars Moelleken",
+                    "homepage": "https://www.moelleken.org/"
+                }
+            ],
+            "description": "Portable ASCII library - performance optimized (ascii) string functions for php.",
+            "homepage": "https://github.com/voku/portable-ascii",
+            "keywords": [
+                "ascii",
+                "clean",
+                "php"
+            ],
+            "support": {
+                "issues": "https://github.com/voku/portable-ascii/issues",
+                "source": "https://github.com/voku/portable-ascii/tree/2.0.2"
+            },
+            "funding": [
+                {
+                    "url": "https://www.paypal.me/moelleken",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/voku",
+                    "type": "github"
+                },
+                {
+                    "url": "https://opencollective.com/portable-ascii",
+                    "type": "open_collective"
+                },
+                {
+                    "url": "https://www.patreon.com/voku",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../voku/portable-ascii"
         }
     ],
     "dev": true,

+ 71 - 2
vendor/composer/installed.php

@@ -3,7 +3,7 @@
         'name' => 'hyperf/hyperf-skeleton',
         'pretty_version' => 'dev-master',
         'version' => 'dev-master',
-        'reference' => '1131810f1743bbec66466a1e449a323135033a21',
+        'reference' => '235a559b5e0bffacf5f9cb4a8e35e38e159daeb9',
         'type' => 'project',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
@@ -457,7 +457,7 @@
         'hyperf/hyperf-skeleton' => array(
             'pretty_version' => 'dev-master',
             'version' => 'dev-master',
-            'reference' => '1131810f1743bbec66466a1e449a323135033a21',
+            'reference' => '235a559b5e0bffacf5f9cb4a8e35e38e159daeb9',
             'type' => 'project',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),
@@ -706,6 +706,60 @@
             'aliases' => array(),
             'dev_requirement' => true,
         ),
+        'illuminate/cache' => array(
+            'pretty_version' => 'v10.48.28',
+            'version' => '10.48.28.0',
+            'reference' => '20f36c3209107ee5c8c646f88a0562a2c1b05a6c',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../illuminate/cache',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'illuminate/collections' => array(
+            'pretty_version' => 'v10.48.28',
+            'version' => '10.48.28.0',
+            'reference' => '48de3d6bc6aa779112ddcb608a3a96fc975d89d8',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../illuminate/collections',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'illuminate/conditionable' => array(
+            'pretty_version' => 'v10.48.28',
+            'version' => '10.48.28.0',
+            'reference' => '3ee34ac306fafc2a6f19cd7cd68c9af389e432a5',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../illuminate/conditionable',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'illuminate/contracts' => array(
+            'pretty_version' => 'v10.48.28',
+            'version' => '10.48.28.0',
+            'reference' => 'f90663a69f926105a70b78060a31f3c64e2d1c74',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../illuminate/contracts',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'illuminate/macroable' => array(
+            'pretty_version' => 'v10.48.28',
+            'version' => '10.48.28.0',
+            'reference' => 'dff667a46ac37b634dcf68909d9d41e94dc97c27',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../illuminate/macroable',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'illuminate/support' => array(
+            'pretty_version' => 'v10.48.28',
+            'version' => '10.48.28.0',
+            'reference' => '6d09b480d34846245d9288f4dcefb17a73ce6e6a',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../illuminate/support',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
         'jetbrains/phpstorm-attributes' => array(
             'pretty_version' => '1.1',
             'version' => '1.1.0.0',
@@ -1037,6 +1091,12 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
+        'psr/simple-cache-implementation' => array(
+            'dev_requirement' => false,
+            'provided' => array(
+                0 => '1.0|2.0|3.0',
+            ),
+        ),
         'ralouphie/getallheaders' => array(
             'pretty_version' => '3.0.3',
             'version' => '3.0.3.0',
@@ -1505,5 +1565,14 @@
             'aliases' => array(),
             'dev_requirement' => false,
         ),
+        'voku/portable-ascii' => array(
+            'pretty_version' => '2.0.2',
+            'version' => '2.0.2.0',
+            'reference' => '16c17671a804bb92602822113dd91fbc8a35d2af',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../voku/portable-ascii',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
     ),
 );

+ 126 - 0
vendor/illuminate/cache/ApcStore.php

@@ -0,0 +1,126 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class ApcStore extends TaggableStore
+{
+    use RetrievesMultipleKeys;
+
+    /**
+     * The APC wrapper instance.
+     *
+     * @var \Illuminate\Cache\ApcWrapper
+     */
+    protected $apc;
+
+    /**
+     * A string that should be prepended to keys.
+     *
+     * @var string
+     */
+    protected $prefix;
+
+    /**
+     * Create a new APC store.
+     *
+     * @param  \Illuminate\Cache\ApcWrapper  $apc
+     * @param  string  $prefix
+     * @return void
+     */
+    public function __construct(ApcWrapper $apc, $prefix = '')
+    {
+        $this->apc = $apc;
+        $this->prefix = $prefix;
+    }
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @param  string|array  $key
+     * @return mixed
+     */
+    public function get($key)
+    {
+        return $this->apc->get($this->prefix.$key);
+    }
+
+    /**
+     * Store an item in the cache for a given number of seconds.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function put($key, $value, $seconds)
+    {
+        return $this->apc->put($this->prefix.$key, $value, $seconds);
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function increment($key, $value = 1)
+    {
+        return $this->apc->increment($this->prefix.$key, $value);
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function decrement($key, $value = 1)
+    {
+        return $this->apc->decrement($this->prefix.$key, $value);
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        return $this->put($key, $value, 0);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forget($key)
+    {
+        return $this->apc->delete($this->prefix.$key);
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        return $this->apc->flush();
+    }
+
+    /**
+     * Get the cache key prefix.
+     *
+     * @return string
+     */
+    public function getPrefix()
+    {
+        return $this->prefix;
+    }
+}

+ 94 - 0
vendor/illuminate/cache/ApcWrapper.php

@@ -0,0 +1,94 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class ApcWrapper
+{
+    /**
+     * Indicates if APCu is supported.
+     *
+     * @var bool
+     */
+    protected $apcu = false;
+
+    /**
+     * Create a new APC wrapper instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        $this->apcu = function_exists('apcu_fetch');
+    }
+
+    /**
+     * Get an item from the cache.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function get($key)
+    {
+        $fetchedValue = $this->apcu ? apcu_fetch($key, $success) : apc_fetch($key, $success);
+
+        return $success ? $fetchedValue : null;
+    }
+
+    /**
+     * Store an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return array|bool
+     */
+    public function put($key, $value, $seconds)
+    {
+        return $this->apcu ? apcu_store($key, $value, $seconds) : apc_store($key, $value, $seconds);
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function increment($key, $value)
+    {
+        return $this->apcu ? apcu_inc($key, $value) : apc_inc($key, $value);
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function decrement($key, $value)
+    {
+        return $this->apcu ? apcu_dec($key, $value) : apc_dec($key, $value);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function delete($key)
+    {
+        return $this->apcu ? apcu_delete($key) : apc_delete($key);
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        return $this->apcu ? apcu_clear_cache() : apc_clear_cache('user');
+    }
+}

+ 106 - 0
vendor/illuminate/cache/ArrayLock.php

@@ -0,0 +1,106 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Support\Carbon;
+
+class ArrayLock extends Lock
+{
+    /**
+     * The parent array cache store.
+     *
+     * @var \Illuminate\Cache\ArrayStore
+     */
+    protected $store;
+
+    /**
+     * Create a new lock instance.
+     *
+     * @param  \Illuminate\Cache\ArrayStore  $store
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return void
+     */
+    public function __construct($store, $name, $seconds, $owner = null)
+    {
+        parent::__construct($name, $seconds, $owner);
+
+        $this->store = $store;
+    }
+
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @return bool
+     */
+    public function acquire()
+    {
+        $expiration = $this->store->locks[$this->name]['expiresAt'] ?? Carbon::now()->addSecond();
+
+        if ($this->exists() && $expiration->isFuture()) {
+            return false;
+        }
+
+        $this->store->locks[$this->name] = [
+            'owner' => $this->owner,
+            'expiresAt' => $this->seconds === 0 ? null : Carbon::now()->addSeconds($this->seconds),
+        ];
+
+        return true;
+    }
+
+    /**
+     * Determine if the current lock exists.
+     *
+     * @return bool
+     */
+    protected function exists()
+    {
+        return isset($this->store->locks[$this->name]);
+    }
+
+    /**
+     * Release the lock.
+     *
+     * @return bool
+     */
+    public function release()
+    {
+        if (! $this->exists()) {
+            return false;
+        }
+
+        if (! $this->isOwnedByCurrentProcess()) {
+            return false;
+        }
+
+        $this->forceRelease();
+
+        return true;
+    }
+
+    /**
+     * Returns the owner value written into the driver for this lock.
+     *
+     * @return string
+     */
+    protected function getCurrentOwner()
+    {
+        if (! $this->exists()) {
+            return null;
+        }
+
+        return $this->store->locks[$this->name]['owner'];
+    }
+
+    /**
+     * Releases this lock in disregard of ownership.
+     *
+     * @return void
+     */
+    public function forceRelease()
+    {
+        unset($this->store->locks[$this->name]);
+    }
+}

+ 219 - 0
vendor/illuminate/cache/ArrayStore.php

@@ -0,0 +1,219 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Contracts\Cache\LockProvider;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\InteractsWithTime;
+
+class ArrayStore extends TaggableStore implements LockProvider
+{
+    use InteractsWithTime, RetrievesMultipleKeys;
+
+    /**
+     * The array of stored values.
+     *
+     * @var array
+     */
+    protected $storage = [];
+
+    /**
+     * The array of locks.
+     *
+     * @var array
+     */
+    public $locks = [];
+
+    /**
+     * Indicates if values are serialized within the store.
+     *
+     * @var bool
+     */
+    protected $serializesValues;
+
+    /**
+     * Create a new Array store.
+     *
+     * @param  bool  $serializesValues
+     * @return void
+     */
+    public function __construct($serializesValues = false)
+    {
+        $this->serializesValues = $serializesValues;
+    }
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @param  string|array  $key
+     * @return mixed
+     */
+    public function get($key)
+    {
+        if (! isset($this->storage[$key])) {
+            return;
+        }
+
+        $item = $this->storage[$key];
+
+        $expiresAt = $item['expiresAt'] ?? 0;
+
+        if ($expiresAt !== 0 && (Carbon::now()->getPreciseTimestamp(3) / 1000) >= $expiresAt) {
+            $this->forget($key);
+
+            return;
+        }
+
+        return $this->serializesValues ? unserialize($item['value']) : $item['value'];
+    }
+
+    /**
+     * Store an item in the cache for a given number of seconds.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function put($key, $value, $seconds)
+    {
+        $this->storage[$key] = [
+            'value' => $this->serializesValues ? serialize($value) : $value,
+            'expiresAt' => $this->calculateExpiration($seconds),
+        ];
+
+        return true;
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int
+     */
+    public function increment($key, $value = 1)
+    {
+        if (! is_null($existing = $this->get($key))) {
+            return tap(((int) $existing) + $value, function ($incremented) use ($key) {
+                $value = $this->serializesValues ? serialize($incremented) : $incremented;
+
+                $this->storage[$key]['value'] = $value;
+            });
+        }
+
+        $this->forever($key, $value);
+
+        return $value;
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int
+     */
+    public function decrement($key, $value = 1)
+    {
+        return $this->increment($key, $value * -1);
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        return $this->put($key, $value, 0);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forget($key)
+    {
+        if (array_key_exists($key, $this->storage)) {
+            unset($this->storage[$key]);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        $this->storage = [];
+
+        return true;
+    }
+
+    /**
+     * Get the cache key prefix.
+     *
+     * @return string
+     */
+    public function getPrefix()
+    {
+        return '';
+    }
+
+    /**
+     * Get the expiration time of the key.
+     *
+     * @param  int  $seconds
+     * @return float
+     */
+    protected function calculateExpiration($seconds)
+    {
+        return $this->toTimestamp($seconds);
+    }
+
+    /**
+     * Get the UNIX timestamp, with milliseconds, for the given number of seconds in the future.
+     *
+     * @param  int  $seconds
+     * @return float
+     */
+    protected function toTimestamp($seconds)
+    {
+        return $seconds > 0 ? (Carbon::now()->getPreciseTimestamp(3) / 1000) + $seconds : 0;
+    }
+
+    /**
+     * Get a lock instance.
+     *
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function lock($name, $seconds = 0, $owner = null)
+    {
+        return new ArrayLock($this, $name, $seconds, $owner);
+    }
+
+    /**
+     * Restore a lock instance using the owner identifier.
+     *
+     * @param  string  $name
+     * @param  string  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function restoreLock($name, $owner)
+    {
+        return $this->lock($name, 0, $owner);
+    }
+}

+ 85 - 0
vendor/illuminate/cache/CacheLock.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class CacheLock extends Lock
+{
+    /**
+     * The cache store implementation.
+     *
+     * @var \Illuminate\Contracts\Cache\Store
+     */
+    protected $store;
+
+    /**
+     * Create a new lock instance.
+     *
+     * @param  \Illuminate\Contracts\Cache\Store  $store
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return void
+     */
+    public function __construct($store, $name, $seconds, $owner = null)
+    {
+        parent::__construct($name, $seconds, $owner);
+
+        $this->store = $store;
+    }
+
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @return bool
+     */
+    public function acquire()
+    {
+        if (method_exists($this->store, 'add') && $this->seconds > 0) {
+            return $this->store->add(
+                $this->name, $this->owner, $this->seconds
+            );
+        }
+
+        if (! is_null($this->store->get($this->name))) {
+            return false;
+        }
+
+        return ($this->seconds > 0)
+                ? $this->store->put($this->name, $this->owner, $this->seconds)
+                : $this->store->forever($this->name, $this->owner);
+    }
+
+    /**
+     * Release the lock.
+     *
+     * @return bool
+     */
+    public function release()
+    {
+        if ($this->isOwnedByCurrentProcess()) {
+            return $this->store->forget($this->name);
+        }
+
+        return false;
+    }
+
+    /**
+     * Releases this lock regardless of ownership.
+     *
+     * @return void
+     */
+    public function forceRelease()
+    {
+        $this->store->forget($this->name);
+    }
+
+    /**
+     * Returns the owner value written into the driver for this lock.
+     *
+     * @return mixed
+     */
+    protected function getCurrentOwner()
+    {
+        return $this->store->get($this->name);
+    }
+}

+ 431 - 0
vendor/illuminate/cache/CacheManager.php

@@ -0,0 +1,431 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Aws\DynamoDb\DynamoDbClient;
+use Closure;
+use Illuminate\Contracts\Cache\Factory as FactoryContract;
+use Illuminate\Contracts\Cache\Store;
+use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
+use Illuminate\Support\Arr;
+use InvalidArgumentException;
+
+/**
+ * @mixin \Illuminate\Cache\Repository
+ * @mixin \Illuminate\Contracts\Cache\LockProvider
+ */
+class CacheManager implements FactoryContract
+{
+    /**
+     * The application instance.
+     *
+     * @var \Illuminate\Contracts\Foundation\Application
+     */
+    protected $app;
+
+    /**
+     * The array of resolved cache stores.
+     *
+     * @var array
+     */
+    protected $stores = [];
+
+    /**
+     * The registered custom driver creators.
+     *
+     * @var array
+     */
+    protected $customCreators = [];
+
+    /**
+     * Create a new Cache manager instance.
+     *
+     * @param  \Illuminate\Contracts\Foundation\Application  $app
+     * @return void
+     */
+    public function __construct($app)
+    {
+        $this->app = $app;
+    }
+
+    /**
+     * Get a cache store instance by name, wrapped in a repository.
+     *
+     * @param  string|null  $name
+     * @return \Illuminate\Contracts\Cache\Repository
+     */
+    public function store($name = null)
+    {
+        $name = $name ?: $this->getDefaultDriver();
+
+        return $this->stores[$name] ??= $this->resolve($name);
+    }
+
+    /**
+     * Get a cache driver instance.
+     *
+     * @param  string|null  $driver
+     * @return \Illuminate\Contracts\Cache\Repository
+     */
+    public function driver($driver = null)
+    {
+        return $this->store($driver);
+    }
+
+    /**
+     * Resolve the given store.
+     *
+     * @param  string  $name
+     * @return \Illuminate\Contracts\Cache\Repository
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function resolve($name)
+    {
+        $config = $this->getConfig($name);
+
+        if (is_null($config)) {
+            throw new InvalidArgumentException("Cache store [{$name}] is not defined.");
+        }
+
+        if (isset($this->customCreators[$config['driver']])) {
+            return $this->callCustomCreator($config);
+        }
+
+        $driverMethod = 'create'.ucfirst($config['driver']).'Driver';
+
+        if (method_exists($this, $driverMethod)) {
+            return $this->{$driverMethod}($config);
+        }
+
+        throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
+    }
+
+    /**
+     * Call a custom driver creator.
+     *
+     * @param  array  $config
+     * @return mixed
+     */
+    protected function callCustomCreator(array $config)
+    {
+        return $this->customCreators[$config['driver']]($this->app, $config);
+    }
+
+    /**
+     * Create an instance of the APC cache driver.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Cache\Repository
+     */
+    protected function createApcDriver(array $config)
+    {
+        $prefix = $this->getPrefix($config);
+
+        return $this->repository(new ApcStore(new ApcWrapper, $prefix));
+    }
+
+    /**
+     * Create an instance of the array cache driver.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Cache\Repository
+     */
+    protected function createArrayDriver(array $config)
+    {
+        return $this->repository(new ArrayStore($config['serialize'] ?? false));
+    }
+
+    /**
+     * Create an instance of the file cache driver.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Cache\Repository
+     */
+    protected function createFileDriver(array $config)
+    {
+        return $this->repository(
+            (new FileStore($this->app['files'], $config['path'], $config['permission'] ?? null))
+                ->setLockDirectory($config['lock_path'] ?? null)
+        );
+    }
+
+    /**
+     * Create an instance of the Memcached cache driver.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Cache\Repository
+     */
+    protected function createMemcachedDriver(array $config)
+    {
+        $prefix = $this->getPrefix($config);
+
+        $memcached = $this->app['memcached.connector']->connect(
+            $config['servers'],
+            $config['persistent_id'] ?? null,
+            $config['options'] ?? [],
+            array_filter($config['sasl'] ?? [])
+        );
+
+        return $this->repository(new MemcachedStore($memcached, $prefix));
+    }
+
+    /**
+     * Create an instance of the Null cache driver.
+     *
+     * @return \Illuminate\Cache\Repository
+     */
+    protected function createNullDriver()
+    {
+        return $this->repository(new NullStore);
+    }
+
+    /**
+     * Create an instance of the Redis cache driver.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Cache\Repository
+     */
+    protected function createRedisDriver(array $config)
+    {
+        $redis = $this->app['redis'];
+
+        $connection = $config['connection'] ?? 'default';
+
+        $store = new RedisStore($redis, $this->getPrefix($config), $connection);
+
+        return $this->repository(
+            $store->setLockConnection($config['lock_connection'] ?? $connection)
+        );
+    }
+
+    /**
+     * Create an instance of the database cache driver.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Cache\Repository
+     */
+    protected function createDatabaseDriver(array $config)
+    {
+        $connection = $this->app['db']->connection($config['connection'] ?? null);
+
+        $store = new DatabaseStore(
+            $connection,
+            $config['table'],
+            $this->getPrefix($config),
+            $config['lock_table'] ?? 'cache_locks',
+            $config['lock_lottery'] ?? [2, 100],
+            $config['lock_timeout'] ?? 86400,
+        );
+
+        return $this->repository($store->setLockConnection(
+            $this->app['db']->connection($config['lock_connection'] ?? $config['connection'] ?? null)
+        ));
+    }
+
+    /**
+     * Create an instance of the DynamoDB cache driver.
+     *
+     * @param  array  $config
+     * @return \Illuminate\Cache\Repository
+     */
+    protected function createDynamodbDriver(array $config)
+    {
+        $client = $this->newDynamodbClient($config);
+
+        return $this->repository(
+            new DynamoDbStore(
+                $client,
+                $config['table'],
+                $config['attributes']['key'] ?? 'key',
+                $config['attributes']['value'] ?? 'value',
+                $config['attributes']['expiration'] ?? 'expires_at',
+                $this->getPrefix($config)
+            )
+        );
+    }
+
+    /**
+     * Create new DynamoDb Client instance.
+     *
+     * @return \Aws\DynamoDb\DynamoDbClient
+     */
+    protected function newDynamodbClient(array $config)
+    {
+        $dynamoConfig = [
+            'region' => $config['region'],
+            'version' => 'latest',
+            'endpoint' => $config['endpoint'] ?? null,
+        ];
+
+        if (! empty($config['key']) && ! empty($config['secret'])) {
+            $dynamoConfig['credentials'] = Arr::only(
+                $config, ['key', 'secret']
+            );
+        }
+
+        if (! empty($config['token'])) {
+            $dynamoConfig['credentials']['token'] = $config['token'];
+        }
+
+        return new DynamoDbClient($dynamoConfig);
+    }
+
+    /**
+     * Create a new cache repository with the given implementation.
+     *
+     * @param  \Illuminate\Contracts\Cache\Store  $store
+     * @return \Illuminate\Cache\Repository
+     */
+    public function repository(Store $store)
+    {
+        return tap(new Repository($store), function ($repository) {
+            $this->setEventDispatcher($repository);
+        });
+    }
+
+    /**
+     * Set the event dispatcher on the given repository instance.
+     *
+     * @param  \Illuminate\Cache\Repository  $repository
+     * @return void
+     */
+    protected function setEventDispatcher(Repository $repository)
+    {
+        if (! $this->app->bound(DispatcherContract::class)) {
+            return;
+        }
+
+        $repository->setEventDispatcher(
+            $this->app[DispatcherContract::class]
+        );
+    }
+
+    /**
+     * Re-set the event dispatcher on all resolved cache repositories.
+     *
+     * @return void
+     */
+    public function refreshEventDispatcher()
+    {
+        array_map([$this, 'setEventDispatcher'], $this->stores);
+    }
+
+    /**
+     * Get the cache prefix.
+     *
+     * @param  array  $config
+     * @return string
+     */
+    protected function getPrefix(array $config)
+    {
+        return $config['prefix'] ?? $this->app['config']['cache.prefix'];
+    }
+
+    /**
+     * Get the cache connection configuration.
+     *
+     * @param  string  $name
+     * @return array|null
+     */
+    protected function getConfig($name)
+    {
+        if (! is_null($name) && $name !== 'null') {
+            return $this->app['config']["cache.stores.{$name}"];
+        }
+
+        return ['driver' => 'null'];
+    }
+
+    /**
+     * Get the default cache driver name.
+     *
+     * @return string
+     */
+    public function getDefaultDriver()
+    {
+        return $this->app['config']['cache.default'];
+    }
+
+    /**
+     * Set the default cache driver name.
+     *
+     * @param  string  $name
+     * @return void
+     */
+    public function setDefaultDriver($name)
+    {
+        $this->app['config']['cache.default'] = $name;
+    }
+
+    /**
+     * Unset the given driver instances.
+     *
+     * @param  array|string|null  $name
+     * @return $this
+     */
+    public function forgetDriver($name = null)
+    {
+        $name ??= $this->getDefaultDriver();
+
+        foreach ((array) $name as $cacheName) {
+            if (isset($this->stores[$cacheName])) {
+                unset($this->stores[$cacheName]);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Disconnect the given driver and remove from local cache.
+     *
+     * @param  string|null  $name
+     * @return void
+     */
+    public function purge($name = null)
+    {
+        $name ??= $this->getDefaultDriver();
+
+        unset($this->stores[$name]);
+    }
+
+    /**
+     * Register a custom driver creator Closure.
+     *
+     * @param  string  $driver
+     * @param  \Closure  $callback
+     * @return $this
+     */
+    public function extend($driver, Closure $callback)
+    {
+        $this->customCreators[$driver] = $callback->bindTo($this, $this);
+
+        return $this;
+    }
+
+    /**
+     * Set the application instance used by the manager.
+     *
+     * @param  \Illuminate\Contracts\Foundation\Application  $app
+     * @return $this
+     */
+    public function setApplication($app)
+    {
+        $this->app = $app;
+
+        return $this;
+    }
+
+    /**
+     * Dynamically call the default driver instance.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        return $this->store()->$method(...$parameters);
+    }
+}

+ 52 - 0
vendor/illuminate/cache/CacheServiceProvider.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Contracts\Support\DeferrableProvider;
+use Illuminate\Support\ServiceProvider;
+use Symfony\Component\Cache\Adapter\Psr16Adapter;
+
+class CacheServiceProvider extends ServiceProvider implements DeferrableProvider
+{
+    /**
+     * Register the service provider.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        $this->app->singleton('cache', function ($app) {
+            return new CacheManager($app);
+        });
+
+        $this->app->singleton('cache.store', function ($app) {
+            return $app['cache']->driver();
+        });
+
+        $this->app->singleton('cache.psr6', function ($app) {
+            return new Psr16Adapter($app['cache.store']);
+        });
+
+        $this->app->singleton('memcached.connector', function () {
+            return new MemcachedConnector;
+        });
+
+        $this->app->singleton(RateLimiter::class, function ($app) {
+            return new RateLimiter($app->make('cache')->driver(
+                $app['config']->get('cache.limiter')
+            ));
+        });
+    }
+
+    /**
+     * Get the services provided by the provider.
+     *
+     * @return array
+     */
+    public function provides()
+    {
+        return [
+            'cache', 'cache.store', 'cache.psr6', 'memcached.connector', RateLimiter::class,
+        ];
+    }
+}

+ 44 - 0
vendor/illuminate/cache/Console/CacheTableCommand.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace Illuminate\Cache\Console;
+
+use Illuminate\Console\MigrationGeneratorCommand;
+use Symfony\Component\Console\Attribute\AsCommand;
+
+#[AsCommand(name: 'cache:table')]
+class CacheTableCommand extends MigrationGeneratorCommand
+{
+    /**
+     * The console command name.
+     *
+     * @var string
+     */
+    protected $name = 'cache:table';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Create a migration for the cache database table';
+
+    /**
+     * Get the migration table name.
+     *
+     * @return string
+     */
+    protected function migrationTableName()
+    {
+        return 'cache';
+    }
+
+    /**
+     * Get the path to the migration stub file.
+     *
+     * @return string
+     */
+    protected function migrationStubFile()
+    {
+        return __DIR__.'/stubs/cache.stub';
+    }
+}

+ 147 - 0
vendor/illuminate/cache/Console/ClearCommand.php

@@ -0,0 +1,147 @@
+<?php
+
+namespace Illuminate\Cache\Console;
+
+use Illuminate\Cache\CacheManager;
+use Illuminate\Console\Command;
+use Illuminate\Filesystem\Filesystem;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+#[AsCommand(name: 'cache:clear')]
+class ClearCommand extends Command
+{
+    /**
+     * The console command name.
+     *
+     * @var string
+     */
+    protected $name = 'cache:clear';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Flush the application cache';
+
+    /**
+     * The cache manager instance.
+     *
+     * @var \Illuminate\Cache\CacheManager
+     */
+    protected $cache;
+
+    /**
+     * The filesystem instance.
+     *
+     * @var \Illuminate\Filesystem\Filesystem
+     */
+    protected $files;
+
+    /**
+     * Create a new cache clear command instance.
+     *
+     * @param  \Illuminate\Cache\CacheManager  $cache
+     * @param  \Illuminate\Filesystem\Filesystem  $files
+     * @return void
+     */
+    public function __construct(CacheManager $cache, Filesystem $files)
+    {
+        parent::__construct();
+
+        $this->cache = $cache;
+        $this->files = $files;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $this->laravel['events']->dispatch(
+            'cache:clearing', [$this->argument('store'), $this->tags()]
+        );
+
+        $successful = $this->cache()->flush();
+
+        $this->flushFacades();
+
+        if (! $successful) {
+            return $this->components->error('Failed to clear cache. Make sure you have the appropriate permissions.');
+        }
+
+        $this->laravel['events']->dispatch(
+            'cache:cleared', [$this->argument('store'), $this->tags()]
+        );
+
+        $this->components->info('Application cache cleared successfully.');
+    }
+
+    /**
+     * Flush the real-time facades stored in the cache directory.
+     *
+     * @return void
+     */
+    public function flushFacades()
+    {
+        if (! $this->files->exists($storagePath = storage_path('framework/cache'))) {
+            return;
+        }
+
+        foreach ($this->files->files($storagePath) as $file) {
+            if (preg_match('/facade-.*\.php$/', $file)) {
+                $this->files->delete($file);
+            }
+        }
+    }
+
+    /**
+     * Get the cache instance for the command.
+     *
+     * @return \Illuminate\Cache\Repository
+     */
+    protected function cache()
+    {
+        $cache = $this->cache->store($this->argument('store'));
+
+        return empty($this->tags()) ? $cache : $cache->tags($this->tags());
+    }
+
+    /**
+     * Get the tags passed to the command.
+     *
+     * @return array
+     */
+    protected function tags()
+    {
+        return array_filter(explode(',', $this->option('tags') ?? ''));
+    }
+
+    /**
+     * Get the console command arguments.
+     *
+     * @return array
+     */
+    protected function getArguments()
+    {
+        return [
+            ['store', InputArgument::OPTIONAL, 'The name of the store you would like to clear'],
+        ];
+    }
+
+    /**
+     * Get the console command options.
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        return [
+            ['tags', null, InputOption::VALUE_OPTIONAL, 'The cache tags you would like to clear', null],
+        ];
+    }
+}

+ 59 - 0
vendor/illuminate/cache/Console/ForgetCommand.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace Illuminate\Cache\Console;
+
+use Illuminate\Cache\CacheManager;
+use Illuminate\Console\Command;
+use Symfony\Component\Console\Attribute\AsCommand;
+
+#[AsCommand(name: 'cache:forget')]
+class ForgetCommand extends Command
+{
+    /**
+     * The console command name.
+     *
+     * @var string
+     */
+    protected $signature = 'cache:forget {key : The key to remove} {store? : The store to remove the key from}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Remove an item from the cache';
+
+    /**
+     * The cache manager instance.
+     *
+     * @var \Illuminate\Cache\CacheManager
+     */
+    protected $cache;
+
+    /**
+     * Create a new cache clear command instance.
+     *
+     * @param  \Illuminate\Cache\CacheManager  $cache
+     * @return void
+     */
+    public function __construct(CacheManager $cache)
+    {
+        parent::__construct();
+
+        $this->cache = $cache;
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $this->cache->store($this->argument('store'))->forget(
+            $this->argument('key')
+        );
+
+        $this->components->info('The ['.$this->argument('key').'] key has been removed from the cache.');
+    }
+}

+ 60 - 0
vendor/illuminate/cache/Console/PruneStaleTagsCommand.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace Illuminate\Cache\Console;
+
+use Illuminate\Cache\CacheManager;
+use Illuminate\Cache\RedisStore;
+use Illuminate\Console\Command;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Input\InputArgument;
+
+#[AsCommand(name: 'cache:prune-stale-tags')]
+class PruneStaleTagsCommand extends Command
+{
+    /**
+     * The console command name.
+     *
+     * @var string
+     */
+    protected $name = 'cache:prune-stale-tags';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Prune stale cache tags from the cache (Redis only)';
+
+    /**
+     * Execute the console command.
+     *
+     * @param  \Illuminate\Cache\CacheManager  $cache
+     * @return int|null
+     */
+    public function handle(CacheManager $cache)
+    {
+        $cache = $cache->store($this->argument('store'));
+
+        if (! $cache->getStore() instanceof RedisStore) {
+            $this->components->error('Pruning cache tags is only necessary when using Redis.');
+
+            return 1;
+        }
+
+        $cache->flushStaleTags();
+
+        $this->components->info('Stale cache tags pruned successfully.');
+    }
+
+    /**
+     * Get the console command arguments.
+     *
+     * @return array
+     */
+    protected function getArguments()
+    {
+        return [
+            ['store', InputArgument::OPTIONAL, 'The name of the store you would like to prune tags from'],
+        ];
+    }
+}

+ 35 - 0
vendor/illuminate/cache/Console/stubs/cache.stub

@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('cache', function (Blueprint $table) {
+            $table->string('key')->primary();
+            $table->mediumText('value');
+            $table->integer('expiration');
+        });
+
+        Schema::create('cache_locks', function (Blueprint $table) {
+            $table->string('key')->primary();
+            $table->string('owner');
+            $table->integer('expiration');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('cache');
+        Schema::dropIfExists('cache_locks');
+    }
+};

+ 156 - 0
vendor/illuminate/cache/DatabaseLock.php

@@ -0,0 +1,156 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Database\Connection;
+use Illuminate\Database\QueryException;
+
+class DatabaseLock extends Lock
+{
+    /**
+     * The database connection instance.
+     *
+     * @var \Illuminate\Database\Connection
+     */
+    protected $connection;
+
+    /**
+     * The database table name.
+     *
+     * @var string
+     */
+    protected $table;
+
+    /**
+     * The prune probability odds.
+     *
+     * @var array
+     */
+    protected $lottery;
+
+    /**
+     * The default number of seconds that a lock should be held.
+     *
+     * @var int
+     */
+    protected $defaultTimeoutInSeconds;
+
+    /**
+     * Create a new lock instance.
+     *
+     * @param  \Illuminate\Database\Connection  $connection
+     * @param  string  $table
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @param  array  $lottery
+     * @return void
+     */
+    public function __construct(Connection $connection, $table, $name, $seconds, $owner = null, $lottery = [2, 100], $defaultTimeoutInSeconds = 86400)
+    {
+        parent::__construct($name, $seconds, $owner);
+
+        $this->connection = $connection;
+        $this->table = $table;
+        $this->lottery = $lottery;
+        $this->defaultTimeoutInSeconds = $defaultTimeoutInSeconds;
+    }
+
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @return bool
+     */
+    public function acquire()
+    {
+        try {
+            $this->connection->table($this->table)->insert([
+                'key' => $this->name,
+                'owner' => $this->owner,
+                'expiration' => $this->expiresAt(),
+            ]);
+
+            $acquired = true;
+        } catch (QueryException) {
+            $updated = $this->connection->table($this->table)
+                ->where('key', $this->name)
+                ->where(function ($query) {
+                    return $query->where('owner', $this->owner)->orWhere('expiration', '<=', time());
+                })->update([
+                    'owner' => $this->owner,
+                    'expiration' => $this->expiresAt(),
+                ]);
+
+            $acquired = $updated >= 1;
+        }
+
+        if (random_int(1, $this->lottery[1]) <= $this->lottery[0]) {
+            $this->connection->table($this->table)->where('expiration', '<=', time())->delete();
+        }
+
+        return $acquired;
+    }
+
+    /**
+     * Get the UNIX timestamp indicating when the lock should expire.
+     *
+     * @return int
+     */
+    protected function expiresAt()
+    {
+        $lockTimeout = $this->seconds > 0 ? $this->seconds : $this->defaultTimeoutInSeconds;
+
+        return time() + $lockTimeout;
+    }
+
+    /**
+     * Release the lock.
+     *
+     * @return bool
+     */
+    public function release()
+    {
+        if ($this->isOwnedByCurrentProcess()) {
+            $this->connection->table($this->table)
+                        ->where('key', $this->name)
+                        ->where('owner', $this->owner)
+                        ->delete();
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Releases this lock in disregard of ownership.
+     *
+     * @return void
+     */
+    public function forceRelease()
+    {
+        $this->connection->table($this->table)
+                    ->where('key', $this->name)
+                    ->delete();
+    }
+
+    /**
+     * Returns the owner value written into the driver for this lock.
+     *
+     * @return string
+     */
+    protected function getCurrentOwner()
+    {
+        return optional($this->connection->table($this->table)->where('key', $this->name)->first())->owner;
+    }
+
+    /**
+     * Get the name of the database connection being used to manage the lock.
+     *
+     * @return string
+     */
+    public function getConnectionName()
+    {
+        return $this->connection->getName();
+    }
+}

+ 419 - 0
vendor/illuminate/cache/DatabaseStore.php

@@ -0,0 +1,419 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Closure;
+use Illuminate\Contracts\Cache\LockProvider;
+use Illuminate\Contracts\Cache\Store;
+use Illuminate\Database\ConnectionInterface;
+use Illuminate\Database\PostgresConnection;
+use Illuminate\Database\QueryException;
+use Illuminate\Database\SqlServerConnection;
+use Illuminate\Support\InteractsWithTime;
+use Illuminate\Support\Str;
+
+class DatabaseStore implements LockProvider, Store
+{
+    use InteractsWithTime, RetrievesMultipleKeys;
+
+    /**
+     * The database connection instance.
+     *
+     * @var \Illuminate\Database\ConnectionInterface
+     */
+    protected $connection;
+
+    /**
+     * The database connection instance that should be used to manage locks.
+     *
+     * @var \Illuminate\Database\ConnectionInterface
+     */
+    protected $lockConnection;
+
+    /**
+     * The name of the cache table.
+     *
+     * @var string
+     */
+    protected $table;
+
+    /**
+     * A string that should be prepended to keys.
+     *
+     * @var string
+     */
+    protected $prefix;
+
+    /**
+     * The name of the cache locks table.
+     *
+     * @var string
+     */
+    protected $lockTable;
+
+    /**
+     * An array representation of the lock lottery odds.
+     *
+     * @var array
+     */
+    protected $lockLottery;
+
+    /**
+     * The default number of seconds that a lock should be held.
+     *
+     * @var int
+     */
+    protected $defaultLockTimeoutInSeconds;
+
+    /**
+     * Create a new database store.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @param  string  $table
+     * @param  string  $prefix
+     * @param  string  $lockTable
+     * @param  array  $lockLottery
+     * @return void
+     */
+    public function __construct(ConnectionInterface $connection,
+                                                    $table,
+                                                    $prefix = '',
+                                                    $lockTable = 'cache_locks',
+                                                    $lockLottery = [2, 100],
+                                                    $defaultLockTimeoutInSeconds = 86400)
+    {
+        $this->table = $table;
+        $this->prefix = $prefix;
+        $this->connection = $connection;
+        $this->lockTable = $lockTable;
+        $this->lockLottery = $lockLottery;
+        $this->defaultLockTimeoutInSeconds = $defaultLockTimeoutInSeconds;
+    }
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @param  string|array  $key
+     * @return mixed
+     */
+    public function get($key)
+    {
+        $prefixed = $this->prefix.$key;
+
+        $cache = $this->table()->where('key', '=', $prefixed)->first();
+
+        // If we have a cache record we will check the expiration time against current
+        // time on the system and see if the record has expired. If it has, we will
+        // remove the records from the database table so it isn't returned again.
+        if (is_null($cache)) {
+            return;
+        }
+
+        $cache = is_array($cache) ? (object) $cache : $cache;
+
+        // If this cache expiration date is past the current time, we will remove this
+        // item from the cache. Then we will return a null value since the cache is
+        // expired. We will use "Carbon" to make this comparison with the column.
+        if ($this->currentTime() >= $cache->expiration) {
+            $this->forgetIfExpired($key);
+
+            return;
+        }
+
+        return $this->unserialize($cache->value);
+    }
+
+    /**
+     * Store an item in the cache for a given number of seconds.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function put($key, $value, $seconds)
+    {
+        $key = $this->prefix.$key;
+        $value = $this->serialize($value);
+        $expiration = $this->getTime() + $seconds;
+
+        return $this->table()->upsert(compact('key', 'value', 'expiration'), 'key') > 0;
+    }
+
+    /**
+     * Store an item in the cache if the key doesn't exist.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function add($key, $value, $seconds)
+    {
+        if (! is_null($this->get($key))) {
+            return false;
+        }
+
+        $key = $this->prefix.$key;
+        $value = $this->serialize($value);
+        $expiration = $this->getTime() + $seconds;
+
+        if (! $this->getConnection() instanceof SqlServerConnection) {
+            return $this->table()->insertOrIgnore(compact('key', 'value', 'expiration')) > 0;
+        }
+
+        try {
+            return $this->table()->insert(compact('key', 'value', 'expiration'));
+        } catch (QueryException) {
+            // ...
+        }
+
+        return false;
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function increment($key, $value = 1)
+    {
+        return $this->incrementOrDecrement($key, $value, function ($current, $value) {
+            return $current + $value;
+        });
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function decrement($key, $value = 1)
+    {
+        return $this->incrementOrDecrement($key, $value, function ($current, $value) {
+            return $current - $value;
+        });
+    }
+
+    /**
+     * Increment or decrement an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  \Closure  $callback
+     * @return int|bool
+     */
+    protected function incrementOrDecrement($key, $value, Closure $callback)
+    {
+        return $this->connection->transaction(function () use ($key, $value, $callback) {
+            $prefixed = $this->prefix.$key;
+
+            $cache = $this->table()->where('key', $prefixed)
+                        ->lockForUpdate()->first();
+
+            // If there is no value in the cache, we will return false here. Otherwise the
+            // value will be decrypted and we will proceed with this function to either
+            // increment or decrement this value based on the given action callbacks.
+            if (is_null($cache)) {
+                return false;
+            }
+
+            $cache = is_array($cache) ? (object) $cache : $cache;
+
+            $current = $this->unserialize($cache->value);
+
+            // Here we'll call this callback function that was given to the function which
+            // is used to either increment or decrement the function. We use a callback
+            // so we do not have to recreate all this logic in each of the functions.
+            $new = $callback((int) $current, $value);
+
+            if (! is_numeric($current)) {
+                return false;
+            }
+
+            // Here we will update the values in the table. We will also encrypt the value
+            // since database cache values are encrypted by default with secure storage
+            // that can't be easily read. We will return the new value after storing.
+            $this->table()->where('key', $prefixed)->update([
+                'value' => $this->serialize($new),
+            ]);
+
+            return $new;
+        });
+    }
+
+    /**
+     * Get the current system time.
+     *
+     * @return int
+     */
+    protected function getTime()
+    {
+        return $this->currentTime();
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        return $this->put($key, $value, 315360000);
+    }
+
+    /**
+     * Get a lock instance.
+     *
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function lock($name, $seconds = 0, $owner = null)
+    {
+        return new DatabaseLock(
+            $this->lockConnection ?? $this->connection,
+            $this->lockTable,
+            $this->prefix.$name,
+            $seconds,
+            $owner,
+            $this->lockLottery,
+            $this->defaultLockTimeoutInSeconds
+        );
+    }
+
+    /**
+     * Restore a lock instance using the owner identifier.
+     *
+     * @param  string  $name
+     * @param  string  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function restoreLock($name, $owner)
+    {
+        return $this->lock($name, 0, $owner);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forget($key)
+    {
+        $this->table()->where('key', '=', $this->prefix.$key)->delete();
+
+        return true;
+    }
+
+    /**
+     * Remove an item from the cache if it is expired.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forgetIfExpired($key)
+    {
+        $this->table()
+            ->where('key', '=', $this->prefix.$key)
+            ->where('expiration', '<=', $this->getTime())
+            ->delete();
+
+        return true;
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        $this->table()->delete();
+
+        return true;
+    }
+
+    /**
+     * Get a query builder for the cache table.
+     *
+     * @return \Illuminate\Database\Query\Builder
+     */
+    protected function table()
+    {
+        return $this->connection->table($this->table);
+    }
+
+    /**
+     * Get the underlying database connection.
+     *
+     * @return \Illuminate\Database\ConnectionInterface
+     */
+    public function getConnection()
+    {
+        return $this->connection;
+    }
+
+    /**
+     * Specify the name of the connection that should be used to manage locks.
+     *
+     * @param  \Illuminate\Database\ConnectionInterface  $connection
+     * @return $this
+     */
+    public function setLockConnection($connection)
+    {
+        $this->lockConnection = $connection;
+
+        return $this;
+    }
+
+    /**
+     * Get the cache key prefix.
+     *
+     * @return string
+     */
+    public function getPrefix()
+    {
+        return $this->prefix;
+    }
+
+    /**
+     * Serialize the given value.
+     *
+     * @param  mixed  $value
+     * @return string
+     */
+    protected function serialize($value)
+    {
+        $result = serialize($value);
+
+        if ($this->connection instanceof PostgresConnection && str_contains($result, "\0")) {
+            $result = base64_encode($result);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Unserialize the given value.
+     *
+     * @param  string  $value
+     * @return mixed
+     */
+    protected function unserialize($value)
+    {
+        if ($this->connection instanceof PostgresConnection && ! Str::contains($value, [':', ';'])) {
+            $value = base64_decode($value);
+        }
+
+        return unserialize($value);
+    }
+}

+ 77 - 0
vendor/illuminate/cache/DynamoDbLock.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class DynamoDbLock extends Lock
+{
+    /**
+     * The DynamoDB client instance.
+     *
+     * @var \Illuminate\Cache\DynamoDbStore
+     */
+    protected $dynamo;
+
+    /**
+     * Create a new lock instance.
+     *
+     * @param  \Illuminate\Cache\DynamoDbStore  $dynamo
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return void
+     */
+    public function __construct(DynamoDbStore $dynamo, $name, $seconds, $owner = null)
+    {
+        parent::__construct($name, $seconds, $owner);
+
+        $this->dynamo = $dynamo;
+    }
+
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @return bool
+     */
+    public function acquire()
+    {
+        if ($this->seconds > 0) {
+            return $this->dynamo->add($this->name, $this->owner, $this->seconds);
+        }
+
+        return $this->dynamo->add($this->name, $this->owner, 86400);
+    }
+
+    /**
+     * Release the lock.
+     *
+     * @return bool
+     */
+    public function release()
+    {
+        if ($this->isOwnedByCurrentProcess()) {
+            return $this->dynamo->forget($this->name);
+        }
+
+        return false;
+    }
+
+    /**
+     * Release this lock in disregard of ownership.
+     *
+     * @return void
+     */
+    public function forceRelease()
+    {
+        $this->dynamo->forget($this->name);
+    }
+
+    /**
+     * Returns the owner value written into the driver for this lock.
+     *
+     * @return mixed
+     */
+    protected function getCurrentOwner()
+    {
+        return $this->dynamo->get($this->name);
+    }
+}

+ 546 - 0
vendor/illuminate/cache/DynamoDbStore.php

@@ -0,0 +1,546 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Aws\DynamoDb\DynamoDbClient;
+use Aws\DynamoDb\Exception\DynamoDbException;
+use Illuminate\Contracts\Cache\LockProvider;
+use Illuminate\Contracts\Cache\Store;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\InteractsWithTime;
+use Illuminate\Support\Str;
+use RuntimeException;
+
+class DynamoDbStore implements LockProvider, Store
+{
+    use InteractsWithTime;
+
+    /**
+     * The DynamoDB client instance.
+     *
+     * @var \Aws\DynamoDb\DynamoDbClient
+     */
+    protected $dynamo;
+
+    /**
+     * The table name.
+     *
+     * @var string
+     */
+    protected $table;
+
+    /**
+     * The name of the attribute that should hold the key.
+     *
+     * @var string
+     */
+    protected $keyAttribute;
+
+    /**
+     * The name of the attribute that should hold the value.
+     *
+     * @var string
+     */
+    protected $valueAttribute;
+
+    /**
+     * The name of the attribute that should hold the expiration timestamp.
+     *
+     * @var string
+     */
+    protected $expirationAttribute;
+
+    /**
+     * A string that should be prepended to keys.
+     *
+     * @var string
+     */
+    protected $prefix;
+
+    /**
+     * Create a new store instance.
+     *
+     * @param  \Aws\DynamoDb\DynamoDbClient  $dynamo
+     * @param  string  $table
+     * @param  string  $keyAttribute
+     * @param  string  $valueAttribute
+     * @param  string  $expirationAttribute
+     * @param  string  $prefix
+     * @return void
+     */
+    public function __construct(DynamoDbClient $dynamo,
+                                $table,
+                                $keyAttribute = 'key',
+                                $valueAttribute = 'value',
+                                $expirationAttribute = 'expires_at',
+                                $prefix = '')
+    {
+        $this->table = $table;
+        $this->dynamo = $dynamo;
+        $this->keyAttribute = $keyAttribute;
+        $this->valueAttribute = $valueAttribute;
+        $this->expirationAttribute = $expirationAttribute;
+
+        $this->setPrefix($prefix);
+    }
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function get($key)
+    {
+        $response = $this->dynamo->getItem([
+            'TableName' => $this->table,
+            'ConsistentRead' => false,
+            'Key' => [
+                $this->keyAttribute => [
+                    'S' => $this->prefix.$key,
+                ],
+            ],
+        ]);
+
+        if (! isset($response['Item'])) {
+            return;
+        }
+
+        if ($this->isExpired($response['Item'])) {
+            return;
+        }
+
+        if (isset($response['Item'][$this->valueAttribute])) {
+            return $this->unserialize(
+                $response['Item'][$this->valueAttribute]['S'] ??
+                $response['Item'][$this->valueAttribute]['N'] ??
+                null
+            );
+        }
+    }
+
+    /**
+     * Retrieve multiple items from the cache by key.
+     *
+     * Items not found in the cache will have a null value.
+     *
+     * @param  array  $keys
+     * @return array
+     */
+    public function many(array $keys)
+    {
+        if (count($keys) === 0) {
+            return [];
+        }
+
+        $prefixedKeys = array_map(function ($key) {
+            return $this->prefix.$key;
+        }, $keys);
+
+        $response = $this->dynamo->batchGetItem([
+            'RequestItems' => [
+                $this->table => [
+                    'ConsistentRead' => false,
+                    'Keys' => collect($prefixedKeys)->map(function ($key) {
+                        return [
+                            $this->keyAttribute => [
+                                'S' => $key,
+                            ],
+                        ];
+                    })->all(),
+                ],
+            ],
+        ]);
+
+        $now = Carbon::now();
+
+        return array_merge(collect(array_flip($keys))->map(function () {
+            //
+        })->all(), collect($response['Responses'][$this->table])->mapWithKeys(function ($response) use ($now) {
+            if ($this->isExpired($response, $now)) {
+                $value = null;
+            } else {
+                $value = $this->unserialize(
+                    $response[$this->valueAttribute]['S'] ??
+                    $response[$this->valueAttribute]['N'] ??
+                    null
+                );
+            }
+
+            return [Str::replaceFirst($this->prefix, '', $response[$this->keyAttribute]['S']) => $value];
+        })->all());
+    }
+
+    /**
+     * Determine if the given item is expired.
+     *
+     * @param  array  $item
+     * @param  \DateTimeInterface|null  $expiration
+     * @return bool
+     */
+    protected function isExpired(array $item, $expiration = null)
+    {
+        $expiration = $expiration ?: Carbon::now();
+
+        return isset($item[$this->expirationAttribute]) &&
+               $expiration->getTimestamp() >= $item[$this->expirationAttribute]['N'];
+    }
+
+    /**
+     * Store an item in the cache for a given number of seconds.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function put($key, $value, $seconds)
+    {
+        $this->dynamo->putItem([
+            'TableName' => $this->table,
+            'Item' => [
+                $this->keyAttribute => [
+                    'S' => $this->prefix.$key,
+                ],
+                $this->valueAttribute => [
+                    $this->type($value) => $this->serialize($value),
+                ],
+                $this->expirationAttribute => [
+                    'N' => (string) $this->toTimestamp($seconds),
+                ],
+            ],
+        ]);
+
+        return true;
+    }
+
+    /**
+     * Store multiple items in the cache for a given number of seconds.
+     *
+     * @param  array  $values
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function putMany(array $values, $seconds)
+    {
+        if (count($values) === 0) {
+            return true;
+        }
+
+        $expiration = $this->toTimestamp($seconds);
+
+        $this->dynamo->batchWriteItem([
+            'RequestItems' => [
+                $this->table => collect($values)->map(function ($value, $key) use ($expiration) {
+                    return [
+                        'PutRequest' => [
+                            'Item' => [
+                                $this->keyAttribute => [
+                                    'S' => $this->prefix.$key,
+                                ],
+                                $this->valueAttribute => [
+                                    $this->type($value) => $this->serialize($value),
+                                ],
+                                $this->expirationAttribute => [
+                                    'N' => (string) $expiration,
+                                ],
+                            ],
+                        ],
+                    ];
+                })->values()->all(),
+            ],
+        ]);
+
+        return true;
+    }
+
+    /**
+     * Store an item in the cache if the key doesn't exist.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function add($key, $value, $seconds)
+    {
+        try {
+            $this->dynamo->putItem([
+                'TableName' => $this->table,
+                'Item' => [
+                    $this->keyAttribute => [
+                        'S' => $this->prefix.$key,
+                    ],
+                    $this->valueAttribute => [
+                        $this->type($value) => $this->serialize($value),
+                    ],
+                    $this->expirationAttribute => [
+                        'N' => (string) $this->toTimestamp($seconds),
+                    ],
+                ],
+                'ConditionExpression' => 'attribute_not_exists(#key) OR #expires_at < :now',
+                'ExpressionAttributeNames' => [
+                    '#key' => $this->keyAttribute,
+                    '#expires_at' => $this->expirationAttribute,
+                ],
+                'ExpressionAttributeValues' => [
+                    ':now' => [
+                        'N' => (string) $this->currentTime(),
+                    ],
+                ],
+            ]);
+
+            return true;
+        } catch (DynamoDbException $e) {
+            if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) {
+                return false;
+            }
+
+            throw $e;
+        }
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function increment($key, $value = 1)
+    {
+        try {
+            $response = $this->dynamo->updateItem([
+                'TableName' => $this->table,
+                'Key' => [
+                    $this->keyAttribute => [
+                        'S' => $this->prefix.$key,
+                    ],
+                ],
+                'ConditionExpression' => 'attribute_exists(#key) AND #expires_at > :now',
+                'UpdateExpression' => 'SET #value = #value + :amount',
+                'ExpressionAttributeNames' => [
+                    '#key' => $this->keyAttribute,
+                    '#value' => $this->valueAttribute,
+                    '#expires_at' => $this->expirationAttribute,
+                ],
+                'ExpressionAttributeValues' => [
+                    ':now' => [
+                        'N' => (string) $this->currentTime(),
+                    ],
+                    ':amount' => [
+                        'N' => (string) $value,
+                    ],
+                ],
+                'ReturnValues' => 'UPDATED_NEW',
+            ]);
+
+            return (int) $response['Attributes'][$this->valueAttribute]['N'];
+        } catch (DynamoDbException $e) {
+            if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) {
+                return false;
+            }
+
+            throw $e;
+        }
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function decrement($key, $value = 1)
+    {
+        try {
+            $response = $this->dynamo->updateItem([
+                'TableName' => $this->table,
+                'Key' => [
+                    $this->keyAttribute => [
+                        'S' => $this->prefix.$key,
+                    ],
+                ],
+                'ConditionExpression' => 'attribute_exists(#key) AND #expires_at > :now',
+                'UpdateExpression' => 'SET #value = #value - :amount',
+                'ExpressionAttributeNames' => [
+                    '#key' => $this->keyAttribute,
+                    '#value' => $this->valueAttribute,
+                    '#expires_at' => $this->expirationAttribute,
+                ],
+                'ExpressionAttributeValues' => [
+                    ':now' => [
+                        'N' => (string) $this->currentTime(),
+                    ],
+                    ':amount' => [
+                        'N' => (string) $value,
+                    ],
+                ],
+                'ReturnValues' => 'UPDATED_NEW',
+            ]);
+
+            return (int) $response['Attributes'][$this->valueAttribute]['N'];
+        } catch (DynamoDbException $e) {
+            if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) {
+                return false;
+            }
+
+            throw $e;
+        }
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        return $this->put($key, $value, Carbon::now()->addYears(5)->getTimestamp());
+    }
+
+    /**
+     * Get a lock instance.
+     *
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function lock($name, $seconds = 0, $owner = null)
+    {
+        return new DynamoDbLock($this, $this->prefix.$name, $seconds, $owner);
+    }
+
+    /**
+     * Restore a lock instance using the owner identifier.
+     *
+     * @param  string  $name
+     * @param  string  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function restoreLock($name, $owner)
+    {
+        return $this->lock($name, 0, $owner);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forget($key)
+    {
+        $this->dynamo->deleteItem([
+            'TableName' => $this->table,
+            'Key' => [
+                $this->keyAttribute => [
+                    'S' => $this->prefix.$key,
+                ],
+            ],
+        ]);
+
+        return true;
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     *
+     * @throws \RuntimeException
+     */
+    public function flush()
+    {
+        throw new RuntimeException('DynamoDb does not support flushing an entire table. Please create a new table.');
+    }
+
+    /**
+     * Get the UNIX timestamp for the given number of seconds.
+     *
+     * @param  int  $seconds
+     * @return int
+     */
+    protected function toTimestamp($seconds)
+    {
+        return $seconds > 0
+                    ? $this->availableAt($seconds)
+                    : $this->currentTime();
+    }
+
+    /**
+     * Serialize the value.
+     *
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function serialize($value)
+    {
+        return is_numeric($value) ? (string) $value : serialize($value);
+    }
+
+    /**
+     * Unserialize the value.
+     *
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function unserialize($value)
+    {
+        if (filter_var($value, FILTER_VALIDATE_INT) !== false) {
+            return (int) $value;
+        }
+
+        if (is_numeric($value)) {
+            return (float) $value;
+        }
+
+        return unserialize($value);
+    }
+
+    /**
+     * Get the DynamoDB type for the given value.
+     *
+     * @param  mixed  $value
+     * @return string
+     */
+    protected function type($value)
+    {
+        return is_numeric($value) ? 'N' : 'S';
+    }
+
+    /**
+     * Get the cache key prefix.
+     *
+     * @return string
+     */
+    public function getPrefix()
+    {
+        return $this->prefix;
+    }
+
+    /**
+     * Set the cache key prefix.
+     *
+     * @param  string  $prefix
+     * @return void
+     */
+    public function setPrefix($prefix)
+    {
+        $this->prefix = ! empty($prefix) ? $prefix.':' : '';
+    }
+
+    /**
+     * Get the DynamoDb Client instance.
+     *
+     * @return \Aws\DynamoDb\DynamoDbClient
+     */
+    public function getClient()
+    {
+        return $this->dynamo;
+    }
+}

+ 46 - 0
vendor/illuminate/cache/Events/CacheEvent.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace Illuminate\Cache\Events;
+
+abstract class CacheEvent
+{
+    /**
+     * The key of the event.
+     *
+     * @var string
+     */
+    public $key;
+
+    /**
+     * The tags that were assigned to the key.
+     *
+     * @var array
+     */
+    public $tags;
+
+    /**
+     * Create a new event instance.
+     *
+     * @param  string  $key
+     * @param  array  $tags
+     * @return void
+     */
+    public function __construct($key, array $tags = [])
+    {
+        $this->key = $key;
+        $this->tags = $tags;
+    }
+
+    /**
+     * Set the tags for the cache event.
+     *
+     * @param  array  $tags
+     * @return $this
+     */
+    public function setTags($tags)
+    {
+        $this->tags = $tags;
+
+        return $this;
+    }
+}

+ 28 - 0
vendor/illuminate/cache/Events/CacheHit.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace Illuminate\Cache\Events;
+
+class CacheHit extends CacheEvent
+{
+    /**
+     * The value that was retrieved.
+     *
+     * @var mixed
+     */
+    public $value;
+
+    /**
+     * Create a new event instance.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  array  $tags
+     * @return void
+     */
+    public function __construct($key, $value, array $tags = [])
+    {
+        parent::__construct($key, $tags);
+
+        $this->value = $value;
+    }
+}

+ 8 - 0
vendor/illuminate/cache/Events/CacheMissed.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace Illuminate\Cache\Events;
+
+class CacheMissed extends CacheEvent
+{
+    //
+}

+ 8 - 0
vendor/illuminate/cache/Events/KeyForgotten.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace Illuminate\Cache\Events;
+
+class KeyForgotten extends CacheEvent
+{
+    //
+}

+ 37 - 0
vendor/illuminate/cache/Events/KeyWritten.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace Illuminate\Cache\Events;
+
+class KeyWritten extends CacheEvent
+{
+    /**
+     * The value that was written.
+     *
+     * @var mixed
+     */
+    public $value;
+
+    /**
+     * The number of seconds the key should be valid.
+     *
+     * @var int|null
+     */
+    public $seconds;
+
+    /**
+     * Create a new event instance.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int|null  $seconds
+     * @param  array  $tags
+     * @return void
+     */
+    public function __construct($key, $value, $seconds = null, $tags = [])
+    {
+        parent::__construct($key, $tags);
+
+        $this->value = $value;
+        $this->seconds = $seconds;
+    }
+}

+ 16 - 0
vendor/illuminate/cache/FileLock.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class FileLock extends CacheLock
+{
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @return bool
+     */
+    public function acquire()
+    {
+        return $this->store->add($this->name, $this->owner, $this->seconds);
+    }
+}

+ 405 - 0
vendor/illuminate/cache/FileStore.php

@@ -0,0 +1,405 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Exception;
+use Illuminate\Contracts\Cache\LockProvider;
+use Illuminate\Contracts\Cache\Store;
+use Illuminate\Contracts\Filesystem\LockTimeoutException;
+use Illuminate\Filesystem\Filesystem;
+use Illuminate\Filesystem\LockableFile;
+use Illuminate\Support\InteractsWithTime;
+
+class FileStore implements Store, LockProvider
+{
+    use InteractsWithTime, RetrievesMultipleKeys;
+
+    /**
+     * The Illuminate Filesystem instance.
+     *
+     * @var \Illuminate\Filesystem\Filesystem
+     */
+    protected $files;
+
+    /**
+     * The file cache directory.
+     *
+     * @var string
+     */
+    protected $directory;
+
+    /**
+     * The file cache lock directory.
+     *
+     * @var string|null
+     */
+    protected $lockDirectory;
+
+    /**
+     * Octal representation of the cache file permissions.
+     *
+     * @var int|null
+     */
+    protected $filePermission;
+
+    /**
+     * Create a new file cache store instance.
+     *
+     * @param  \Illuminate\Filesystem\Filesystem  $files
+     * @param  string  $directory
+     * @param  int|null  $filePermission
+     * @return void
+     */
+    public function __construct(Filesystem $files, $directory, $filePermission = null)
+    {
+        $this->files = $files;
+        $this->directory = $directory;
+        $this->filePermission = $filePermission;
+    }
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @param  string|array  $key
+     * @return mixed
+     */
+    public function get($key)
+    {
+        return $this->getPayload($key)['data'] ?? null;
+    }
+
+    /**
+     * Store an item in the cache for a given number of seconds.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function put($key, $value, $seconds)
+    {
+        $this->ensureCacheDirectoryExists($path = $this->path($key));
+
+        $result = $this->files->put(
+            $path, $this->expiration($seconds).serialize($value), true
+        );
+
+        if ($result !== false && $result > 0) {
+            $this->ensurePermissionsAreCorrect($path);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Store an item in the cache if the key doesn't exist.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function add($key, $value, $seconds)
+    {
+        $this->ensureCacheDirectoryExists($path = $this->path($key));
+
+        $file = new LockableFile($path, 'c+');
+
+        try {
+            $file->getExclusiveLock();
+        } catch (LockTimeoutException) {
+            $file->close();
+
+            return false;
+        }
+
+        $expire = $file->read(10);
+
+        if (empty($expire) || $this->currentTime() >= $expire) {
+            $file->truncate()
+                ->write($this->expiration($seconds).serialize($value))
+                ->close();
+
+            $this->ensurePermissionsAreCorrect($path);
+
+            return true;
+        }
+
+        $file->close();
+
+        return false;
+    }
+
+    /**
+     * Create the file cache directory if necessary.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    protected function ensureCacheDirectoryExists($path)
+    {
+        $directory = dirname($path);
+
+        if (! $this->files->exists($directory)) {
+            $this->files->makeDirectory($directory, 0777, true, true);
+
+            // We're creating two levels of directories (e.g. 7e/24), so we check them both...
+            $this->ensurePermissionsAreCorrect($directory);
+            $this->ensurePermissionsAreCorrect(dirname($directory));
+        }
+    }
+
+    /**
+     * Ensure the created node has the correct permissions.
+     *
+     * @param  string  $path
+     * @return void
+     */
+    protected function ensurePermissionsAreCorrect($path)
+    {
+        if (is_null($this->filePermission) ||
+            intval($this->files->chmod($path), 8) == $this->filePermission) {
+            return;
+        }
+
+        $this->files->chmod($path, $this->filePermission);
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int
+     */
+    public function increment($key, $value = 1)
+    {
+        $raw = $this->getPayload($key);
+
+        return tap(((int) $raw['data']) + $value, function ($newValue) use ($key, $raw) {
+            $this->put($key, $newValue, $raw['time'] ?? 0);
+        });
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int
+     */
+    public function decrement($key, $value = 1)
+    {
+        return $this->increment($key, $value * -1);
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        return $this->put($key, $value, 0);
+    }
+
+    /**
+     * Get a lock instance.
+     *
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function lock($name, $seconds = 0, $owner = null)
+    {
+        $this->ensureCacheDirectoryExists($this->lockDirectory ?? $this->directory);
+
+        return new FileLock(
+            new static($this->files, $this->lockDirectory ?? $this->directory, $this->filePermission),
+            $name,
+            $seconds,
+            $owner
+        );
+    }
+
+    /**
+     * Restore a lock instance using the owner identifier.
+     *
+     * @param  string  $name
+     * @param  string  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function restoreLock($name, $owner)
+    {
+        return $this->lock($name, 0, $owner);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forget($key)
+    {
+        if ($this->files->exists($file = $this->path($key))) {
+            return $this->files->delete($file);
+        }
+
+        return false;
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        if (! $this->files->isDirectory($this->directory)) {
+            return false;
+        }
+
+        foreach ($this->files->directories($this->directory) as $directory) {
+            $deleted = $this->files->deleteDirectory($directory);
+
+            if (! $deleted || $this->files->exists($directory)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Retrieve an item and expiry time from the cache by key.
+     *
+     * @param  string  $key
+     * @return array
+     */
+    protected function getPayload($key)
+    {
+        $path = $this->path($key);
+
+        // If the file doesn't exist, we obviously cannot return the cache so we will
+        // just return null. Otherwise, we'll get the contents of the file and get
+        // the expiration UNIX timestamps from the start of the file's contents.
+        try {
+            if (is_null($contents = $this->files->get($path, true))) {
+                return $this->emptyPayload();
+            }
+
+            $expire = substr($contents, 0, 10);
+        } catch (Exception) {
+            return $this->emptyPayload();
+        }
+
+        // If the current time is greater than expiration timestamps we will delete
+        // the file and return null. This helps clean up the old files and keeps
+        // this directory much cleaner for us as old files aren't hanging out.
+        if ($this->currentTime() >= $expire) {
+            $this->forget($key);
+
+            return $this->emptyPayload();
+        }
+
+        try {
+            $data = unserialize(substr($contents, 10));
+        } catch (Exception) {
+            $this->forget($key);
+
+            return $this->emptyPayload();
+        }
+
+        // Next, we'll extract the number of seconds that are remaining for a cache
+        // so that we can properly retain the time for things like the increment
+        // operation that may be performed on this cache on a later operation.
+        $time = $expire - $this->currentTime();
+
+        return compact('data', 'time');
+    }
+
+    /**
+     * Get a default empty payload for the cache.
+     *
+     * @return array
+     */
+    protected function emptyPayload()
+    {
+        return ['data' => null, 'time' => null];
+    }
+
+    /**
+     * Get the full path for the given cache key.
+     *
+     * @param  string  $key
+     * @return string
+     */
+    public function path($key)
+    {
+        $parts = array_slice(str_split($hash = sha1($key), 2), 0, 2);
+
+        return $this->directory.'/'.implode('/', $parts).'/'.$hash;
+    }
+
+    /**
+     * Get the expiration time based on the given seconds.
+     *
+     * @param  int  $seconds
+     * @return int
+     */
+    protected function expiration($seconds)
+    {
+        $time = $this->availableAt($seconds);
+
+        return $seconds === 0 || $time > 9999999999 ? 9999999999 : $time;
+    }
+
+    /**
+     * Get the Filesystem instance.
+     *
+     * @return \Illuminate\Filesystem\Filesystem
+     */
+    public function getFilesystem()
+    {
+        return $this->files;
+    }
+
+    /**
+     * Get the working directory of the cache.
+     *
+     * @return string
+     */
+    public function getDirectory()
+    {
+        return $this->directory;
+    }
+
+    /**
+     * Set the cache directory where locks should be stored.
+     *
+     * @param  string|null  $lockDirectory
+     * @return $this
+     */
+    public function setLockDirectory($lockDirectory)
+    {
+        $this->lockDirectory = $lockDirectory;
+
+        return $this;
+    }
+
+    /**
+     * Get the cache key prefix.
+     *
+     * @return string
+     */
+    public function getPrefix()
+    {
+        return '';
+    }
+}

+ 31 - 0
vendor/illuminate/cache/HasCacheLock.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace Illuminate\Cache;
+
+trait HasCacheLock
+{
+    /**
+     * Get a lock instance.
+     *
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function lock($name, $seconds = 0, $owner = null)
+    {
+        return new CacheLock($this, $name, $seconds, $owner);
+    }
+
+    /**
+     * Restore a lock instance using the owner identifier.
+     *
+     * @param  string  $name
+     * @param  string  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function restoreLock($name, $owner)
+    {
+        return $this->lock($name, 0, $owner);
+    }
+}

+ 21 - 0
vendor/illuminate/cache/LICENSE.md

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Taylor Otwell
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 168 - 0
vendor/illuminate/cache/Lock.php

@@ -0,0 +1,168 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Contracts\Cache\Lock as LockContract;
+use Illuminate\Contracts\Cache\LockTimeoutException;
+use Illuminate\Support\InteractsWithTime;
+use Illuminate\Support\Sleep;
+use Illuminate\Support\Str;
+
+abstract class Lock implements LockContract
+{
+    use InteractsWithTime;
+
+    /**
+     * The name of the lock.
+     *
+     * @var string
+     */
+    protected $name;
+
+    /**
+     * The number of seconds the lock should be maintained.
+     *
+     * @var int
+     */
+    protected $seconds;
+
+    /**
+     * The scope identifier of this lock.
+     *
+     * @var string
+     */
+    protected $owner;
+
+    /**
+     * The number of milliseconds to wait before re-attempting to acquire a lock while blocking.
+     *
+     * @var int
+     */
+    protected $sleepMilliseconds = 250;
+
+    /**
+     * Create a new lock instance.
+     *
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return void
+     */
+    public function __construct($name, $seconds, $owner = null)
+    {
+        if (is_null($owner)) {
+            $owner = Str::random();
+        }
+
+        $this->name = $name;
+        $this->owner = $owner;
+        $this->seconds = $seconds;
+    }
+
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @return bool
+     */
+    abstract public function acquire();
+
+    /**
+     * Release the lock.
+     *
+     * @return bool
+     */
+    abstract public function release();
+
+    /**
+     * Returns the owner value written into the driver for this lock.
+     *
+     * @return string
+     */
+    abstract protected function getCurrentOwner();
+
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @param  callable|null  $callback
+     * @return mixed
+     */
+    public function get($callback = null)
+    {
+        $result = $this->acquire();
+
+        if ($result && is_callable($callback)) {
+            try {
+                return $callback();
+            } finally {
+                $this->release();
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Attempt to acquire the lock for the given number of seconds.
+     *
+     * @param  int  $seconds
+     * @param  callable|null  $callback
+     * @return mixed
+     *
+     * @throws \Illuminate\Contracts\Cache\LockTimeoutException
+     */
+    public function block($seconds, $callback = null)
+    {
+        $starting = $this->currentTime();
+
+        while (! $this->acquire()) {
+            Sleep::usleep($this->sleepMilliseconds * 1000);
+
+            if ($this->currentTime() - $seconds >= $starting) {
+                throw new LockTimeoutException;
+            }
+        }
+
+        if (is_callable($callback)) {
+            try {
+                return $callback();
+            } finally {
+                $this->release();
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the current owner of the lock.
+     *
+     * @return string
+     */
+    public function owner()
+    {
+        return $this->owner;
+    }
+
+    /**
+     * Determines whether this lock is allowed to release the lock in the driver.
+     *
+     * @return bool
+     */
+    public function isOwnedByCurrentProcess()
+    {
+        return $this->getCurrentOwner() === $this->owner;
+    }
+
+    /**
+     * Specify the number of milliseconds to sleep in between blocked lock acquisition attempts.
+     *
+     * @param  int  $milliseconds
+     * @return $this
+     */
+    public function betweenBlockedAttemptsSleepFor($milliseconds)
+    {
+        $this->sleepMilliseconds = $milliseconds;
+
+        return $this;
+    }
+}

+ 25 - 0
vendor/illuminate/cache/LuaScripts.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class LuaScripts
+{
+    /**
+     * Get the Lua script to atomically release a lock.
+     *
+     * KEYS[1] - The name of the lock
+     * ARGV[1] - The owner key of the lock instance trying to release it
+     *
+     * @return string
+     */
+    public static function releaseLock()
+    {
+        return <<<'LUA'
+if redis.call("get",KEYS[1]) == ARGV[1] then
+    return redis.call("del",KEYS[1])
+else
+    return 0
+end
+LUA;
+    }
+}

+ 87 - 0
vendor/illuminate/cache/MemcachedConnector.php

@@ -0,0 +1,87 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Memcached;
+
+class MemcachedConnector
+{
+    /**
+     * Create a new Memcached connection.
+     *
+     * @param  array  $servers
+     * @param  string|null  $connectionId
+     * @param  array  $options
+     * @param  array  $credentials
+     * @return \Memcached
+     */
+    public function connect(array $servers, $connectionId = null, array $options = [], array $credentials = [])
+    {
+        $memcached = $this->getMemcached(
+            $connectionId, $credentials, $options
+        );
+
+        if (! $memcached->getServerList()) {
+            // For each server in the array, we'll just extract the configuration and add
+            // the server to the Memcached connection. Once we have added all of these
+            // servers we'll verify the connection is successful and return it back.
+            foreach ($servers as $server) {
+                $memcached->addServer(
+                    $server['host'], $server['port'], $server['weight']
+                );
+            }
+        }
+
+        return $memcached;
+    }
+
+    /**
+     * Get a new Memcached instance.
+     *
+     * @param  string|null  $connectionId
+     * @param  array  $credentials
+     * @param  array  $options
+     * @return \Memcached
+     */
+    protected function getMemcached($connectionId, array $credentials, array $options)
+    {
+        $memcached = $this->createMemcachedInstance($connectionId);
+
+        if (count($credentials) === 2) {
+            $this->setCredentials($memcached, $credentials);
+        }
+
+        if (count($options)) {
+            $memcached->setOptions($options);
+        }
+
+        return $memcached;
+    }
+
+    /**
+     * Create the Memcached instance.
+     *
+     * @param  string|null  $connectionId
+     * @return \Memcached
+     */
+    protected function createMemcachedInstance($connectionId)
+    {
+        return empty($connectionId) ? new Memcached : new Memcached($connectionId);
+    }
+
+    /**
+     * Set the SASL credentials on the Memcached connection.
+     *
+     * @param  \Memcached  $memcached
+     * @param  array  $credentials
+     * @return void
+     */
+    protected function setCredentials($memcached, $credentials)
+    {
+        [$username, $password] = $credentials;
+
+        $memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
+
+        $memcached->setSaslAuthData($username, $password);
+    }
+}

+ 75 - 0
vendor/illuminate/cache/MemcachedLock.php

@@ -0,0 +1,75 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class MemcachedLock extends Lock
+{
+    /**
+     * The Memcached instance.
+     *
+     * @var \Memcached
+     */
+    protected $memcached;
+
+    /**
+     * Create a new lock instance.
+     *
+     * @param  \Memcached  $memcached
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return void
+     */
+    public function __construct($memcached, $name, $seconds, $owner = null)
+    {
+        parent::__construct($name, $seconds, $owner);
+
+        $this->memcached = $memcached;
+    }
+
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @return bool
+     */
+    public function acquire()
+    {
+        return $this->memcached->add(
+            $this->name, $this->owner, $this->seconds
+        );
+    }
+
+    /**
+     * Release the lock.
+     *
+     * @return bool
+     */
+    public function release()
+    {
+        if ($this->isOwnedByCurrentProcess()) {
+            return $this->memcached->delete($this->name);
+        }
+
+        return false;
+    }
+
+    /**
+     * Releases this lock in disregard of ownership.
+     *
+     * @return void
+     */
+    public function forceRelease()
+    {
+        $this->memcached->delete($this->name);
+    }
+
+    /**
+     * Returns the owner value written into the driver for this lock.
+     *
+     * @return mixed
+     */
+    protected function getCurrentOwner()
+    {
+        return $this->memcached->get($this->name);
+    }
+}

+ 279 - 0
vendor/illuminate/cache/MemcachedStore.php

@@ -0,0 +1,279 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Contracts\Cache\LockProvider;
+use Illuminate\Support\InteractsWithTime;
+use Memcached;
+use ReflectionMethod;
+
+class MemcachedStore extends TaggableStore implements LockProvider
+{
+    use InteractsWithTime;
+
+    /**
+     * The Memcached instance.
+     *
+     * @var \Memcached
+     */
+    protected $memcached;
+
+    /**
+     * A string that should be prepended to keys.
+     *
+     * @var string
+     */
+    protected $prefix;
+
+    /**
+     * Indicates whether we are using Memcached version >= 3.0.0.
+     *
+     * @var bool
+     */
+    protected $onVersionThree;
+
+    /**
+     * Create a new Memcached store.
+     *
+     * @param  \Memcached  $memcached
+     * @param  string  $prefix
+     * @return void
+     */
+    public function __construct($memcached, $prefix = '')
+    {
+        $this->setPrefix($prefix);
+        $this->memcached = $memcached;
+
+        $this->onVersionThree = (new ReflectionMethod('Memcached', 'getMulti'))
+                            ->getNumberOfParameters() == 2;
+    }
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function get($key)
+    {
+        $value = $this->memcached->get($this->prefix.$key);
+
+        if ($this->memcached->getResultCode() == 0) {
+            return $value;
+        }
+    }
+
+    /**
+     * Retrieve multiple items from the cache by key.
+     *
+     * Items not found in the cache will have a null value.
+     *
+     * @param  array  $keys
+     * @return array
+     */
+    public function many(array $keys)
+    {
+        $prefixedKeys = array_map(function ($key) {
+            return $this->prefix.$key;
+        }, $keys);
+
+        if ($this->onVersionThree) {
+            $values = $this->memcached->getMulti($prefixedKeys, Memcached::GET_PRESERVE_ORDER);
+        } else {
+            $null = null;
+
+            $values = $this->memcached->getMulti($prefixedKeys, $null, Memcached::GET_PRESERVE_ORDER);
+        }
+
+        if ($this->memcached->getResultCode() != 0) {
+            return array_fill_keys($keys, null);
+        }
+
+        return array_combine($keys, $values);
+    }
+
+    /**
+     * Store an item in the cache for a given number of seconds.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function put($key, $value, $seconds)
+    {
+        return $this->memcached->set(
+            $this->prefix.$key, $value, $this->calculateExpiration($seconds)
+        );
+    }
+
+    /**
+     * Store multiple items in the cache for a given number of seconds.
+     *
+     * @param  array  $values
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function putMany(array $values, $seconds)
+    {
+        $prefixedValues = [];
+
+        foreach ($values as $key => $value) {
+            $prefixedValues[$this->prefix.$key] = $value;
+        }
+
+        return $this->memcached->setMulti(
+            $prefixedValues, $this->calculateExpiration($seconds)
+        );
+    }
+
+    /**
+     * Store an item in the cache if the key doesn't exist.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function add($key, $value, $seconds)
+    {
+        return $this->memcached->add(
+            $this->prefix.$key, $value, $this->calculateExpiration($seconds)
+        );
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function increment($key, $value = 1)
+    {
+        return $this->memcached->increment($this->prefix.$key, $value);
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function decrement($key, $value = 1)
+    {
+        return $this->memcached->decrement($this->prefix.$key, $value);
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        return $this->put($key, $value, 0);
+    }
+
+    /**
+     * Get a lock instance.
+     *
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function lock($name, $seconds = 0, $owner = null)
+    {
+        return new MemcachedLock($this->memcached, $this->prefix.$name, $seconds, $owner);
+    }
+
+    /**
+     * Restore a lock instance using the owner identifier.
+     *
+     * @param  string  $name
+     * @param  string  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function restoreLock($name, $owner)
+    {
+        return $this->lock($name, 0, $owner);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forget($key)
+    {
+        return $this->memcached->delete($this->prefix.$key);
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        return $this->memcached->flush();
+    }
+
+    /**
+     * Get the expiration time of the key.
+     *
+     * @param  int  $seconds
+     * @return int
+     */
+    protected function calculateExpiration($seconds)
+    {
+        return $this->toTimestamp($seconds);
+    }
+
+    /**
+     * Get the UNIX timestamp for the given number of seconds.
+     *
+     * @param  int  $seconds
+     * @return int
+     */
+    protected function toTimestamp($seconds)
+    {
+        return $seconds > 0 ? $this->availableAt($seconds) : 0;
+    }
+
+    /**
+     * Get the underlying Memcached connection.
+     *
+     * @return \Memcached
+     */
+    public function getMemcached()
+    {
+        return $this->memcached;
+    }
+
+    /**
+     * Get the cache key prefix.
+     *
+     * @return string
+     */
+    public function getPrefix()
+    {
+        return $this->prefix;
+    }
+
+    /**
+     * Set the cache key prefix.
+     *
+     * @param  string  $prefix
+     * @return void
+     */
+    public function setPrefix($prefix)
+    {
+        $this->prefix = ! empty($prefix) ? $prefix.':' : '';
+    }
+}

+ 46 - 0
vendor/illuminate/cache/NoLock.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class NoLock extends Lock
+{
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @return bool
+     */
+    public function acquire()
+    {
+        return true;
+    }
+
+    /**
+     * Release the lock.
+     *
+     * @return bool
+     */
+    public function release()
+    {
+        return true;
+    }
+
+    /**
+     * Releases this lock in disregard of ownership.
+     *
+     * @return void
+     */
+    public function forceRelease()
+    {
+        //
+    }
+
+    /**
+     * Returns the owner value written into the driver for this lock.
+     *
+     * @return mixed
+     */
+    protected function getCurrentOwner()
+    {
+        return $this->owner;
+    }
+}

+ 126 - 0
vendor/illuminate/cache/NullStore.php

@@ -0,0 +1,126 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Contracts\Cache\LockProvider;
+
+class NullStore extends TaggableStore implements LockProvider
+{
+    use RetrievesMultipleKeys;
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @param  string  $key
+     * @return void
+     */
+    public function get($key)
+    {
+        //
+    }
+
+    /**
+     * Store an item in the cache for a given number of seconds.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function put($key, $value, $seconds)
+    {
+        return false;
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function increment($key, $value = 1)
+    {
+        return false;
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function decrement($key, $value = 1)
+    {
+        return false;
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        return false;
+    }
+
+    /**
+     * Get a lock instance.
+     *
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function lock($name, $seconds = 0, $owner = null)
+    {
+        return new NoLock($name, $seconds, $owner);
+    }
+
+    /**
+     * Restore a lock instance using the owner identifier.
+     *
+     * @param  string  $name
+     * @param  string  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function restoreLock($name, $owner)
+    {
+        return $this->lock($name, 0, $owner);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forget($key)
+    {
+        return true;
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        return true;
+    }
+
+    /**
+     * Get the cache key prefix.
+     *
+     * @return string
+     */
+    public function getPrefix()
+    {
+        return '';
+    }
+}

+ 35 - 0
vendor/illuminate/cache/PhpRedisLock.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Redis\Connections\PhpRedisConnection;
+
+class PhpRedisLock extends RedisLock
+{
+    /**
+     * Create a new phpredis lock instance.
+     *
+     * @param  \Illuminate\Redis\Connections\PhpRedisConnection  $redis
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return void
+     */
+    public function __construct(PhpRedisConnection $redis, string $name, int $seconds, ?string $owner = null)
+    {
+        parent::__construct($redis, $name, $seconds, $owner);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function release()
+    {
+        return (bool) $this->redis->eval(
+            LuaScripts::releaseLock(),
+            1,
+            $this->name,
+            ...$this->redis->pack([$this->owner])
+        );
+    }
+}

+ 238 - 0
vendor/illuminate/cache/RateLimiter.php

@@ -0,0 +1,238 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Closure;
+use Illuminate\Contracts\Cache\Repository as Cache;
+use Illuminate\Support\InteractsWithTime;
+
+class RateLimiter
+{
+    use InteractsWithTime;
+
+    /**
+     * The cache store implementation.
+     *
+     * @var \Illuminate\Contracts\Cache\Repository
+     */
+    protected $cache;
+
+    /**
+     * The configured limit object resolvers.
+     *
+     * @var array
+     */
+    protected $limiters = [];
+
+    /**
+     * Create a new rate limiter instance.
+     *
+     * @param  \Illuminate\Contracts\Cache\Repository  $cache
+     * @return void
+     */
+    public function __construct(Cache $cache)
+    {
+        $this->cache = $cache;
+    }
+
+    /**
+     * Register a named limiter configuration.
+     *
+     * @param  string  $name
+     * @param  \Closure  $callback
+     * @return $this
+     */
+    public function for(string $name, Closure $callback)
+    {
+        $this->limiters[$name] = $callback;
+
+        return $this;
+    }
+
+    /**
+     * Get the given named rate limiter.
+     *
+     * @param  string  $name
+     * @return \Closure|null
+     */
+    public function limiter(string $name)
+    {
+        return $this->limiters[$name] ?? null;
+    }
+
+    /**
+     * Attempts to execute a callback if it's not limited.
+     *
+     * @param  string  $key
+     * @param  int  $maxAttempts
+     * @param  \Closure  $callback
+     * @param  int  $decaySeconds
+     * @return mixed
+     */
+    public function attempt($key, $maxAttempts, Closure $callback, $decaySeconds = 60)
+    {
+        if ($this->tooManyAttempts($key, $maxAttempts)) {
+            return false;
+        }
+
+        if (is_null($result = $callback())) {
+            $result = true;
+        }
+
+        return tap($result, function () use ($key, $decaySeconds) {
+            $this->hit($key, $decaySeconds);
+        });
+    }
+
+    /**
+     * Determine if the given key has been "accessed" too many times.
+     *
+     * @param  string  $key
+     * @param  int  $maxAttempts
+     * @return bool
+     */
+    public function tooManyAttempts($key, $maxAttempts)
+    {
+        if ($this->attempts($key) >= $maxAttempts) {
+            if ($this->cache->has($this->cleanRateLimiterKey($key).':timer')) {
+                return true;
+            }
+
+            $this->resetAttempts($key);
+        }
+
+        return false;
+    }
+
+    /**
+     * Increment (by 1) the counter for a given key for a given decay time.
+     *
+     * @param  string  $key
+     * @param  int  $decaySeconds
+     * @return int
+     */
+    public function hit($key, $decaySeconds = 60)
+    {
+        return $this->increment($key, $decaySeconds);
+    }
+
+    /**
+     * Increment the counter for a given key for a given decay time by a given amount.
+     *
+     * @param  string  $key
+     * @param  int  $decaySeconds
+     * @param  int  $amount
+     * @return int
+     */
+    public function increment($key, $decaySeconds = 60, $amount = 1)
+    {
+        $key = $this->cleanRateLimiterKey($key);
+
+        $this->cache->add(
+            $key.':timer', $this->availableAt($decaySeconds), $decaySeconds
+        );
+
+        $added = $this->cache->add($key, 0, $decaySeconds);
+
+        $hits = (int) $this->cache->increment($key, $amount);
+
+        if (! $added && $hits == 1) {
+            $this->cache->put($key, 1, $decaySeconds);
+        }
+
+        return $hits;
+    }
+
+    /**
+     * Get the number of attempts for the given key.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function attempts($key)
+    {
+        $key = $this->cleanRateLimiterKey($key);
+
+        return $this->cache->get($key, 0);
+    }
+
+    /**
+     * Reset the number of attempts for the given key.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function resetAttempts($key)
+    {
+        $key = $this->cleanRateLimiterKey($key);
+
+        return $this->cache->forget($key);
+    }
+
+    /**
+     * Get the number of retries left for the given key.
+     *
+     * @param  string  $key
+     * @param  int  $maxAttempts
+     * @return int
+     */
+    public function remaining($key, $maxAttempts)
+    {
+        $key = $this->cleanRateLimiterKey($key);
+
+        $attempts = $this->attempts($key);
+
+        return $maxAttempts - $attempts;
+    }
+
+    /**
+     * Get the number of retries left for the given key.
+     *
+     * @param  string  $key
+     * @param  int  $maxAttempts
+     * @return int
+     */
+    public function retriesLeft($key, $maxAttempts)
+    {
+        return $this->remaining($key, $maxAttempts);
+    }
+
+    /**
+     * Clear the hits and lockout timer for the given key.
+     *
+     * @param  string  $key
+     * @return void
+     */
+    public function clear($key)
+    {
+        $key = $this->cleanRateLimiterKey($key);
+
+        $this->resetAttempts($key);
+
+        $this->cache->forget($key.':timer');
+    }
+
+    /**
+     * Get the number of seconds until the "key" is accessible again.
+     *
+     * @param  string  $key
+     * @return int
+     */
+    public function availableIn($key)
+    {
+        $key = $this->cleanRateLimiterKey($key);
+
+        return max(0, $this->cache->get($key.':timer') - $this->currentTime());
+    }
+
+    /**
+     * Clean the rate limiter key from unicode characters.
+     *
+     * @param  string  $key
+     * @return string
+     */
+    public function cleanRateLimiterKey($key)
+    {
+        return preg_replace('/&([a-z])[a-z]+;/i', '$1', htmlentities($key));
+    }
+}

+ 18 - 0
vendor/illuminate/cache/RateLimiting/GlobalLimit.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace Illuminate\Cache\RateLimiting;
+
+class GlobalLimit extends Limit
+{
+    /**
+     * Create a new limit instance.
+     *
+     * @param  int  $maxAttempts
+     * @param  int  $decayMinutes
+     * @return void
+     */
+    public function __construct(int $maxAttempts, int $decayMinutes = 1)
+    {
+        parent::__construct('', $maxAttempts, $decayMinutes);
+    }
+}

+ 132 - 0
vendor/illuminate/cache/RateLimiting/Limit.php

@@ -0,0 +1,132 @@
+<?php
+
+namespace Illuminate\Cache\RateLimiting;
+
+class Limit
+{
+    /**
+     * The rate limit signature key.
+     *
+     * @var mixed
+     */
+    public $key;
+
+    /**
+     * The maximum number of attempts allowed within the given number of minutes.
+     *
+     * @var int
+     */
+    public $maxAttempts;
+
+    /**
+     * The number of minutes until the rate limit is reset.
+     *
+     * @var int
+     */
+    public $decayMinutes;
+
+    /**
+     * The response generator callback.
+     *
+     * @var callable
+     */
+    public $responseCallback;
+
+    /**
+     * Create a new limit instance.
+     *
+     * @param  mixed  $key
+     * @param  int  $maxAttempts
+     * @param  int  $decayMinutes
+     * @return void
+     */
+    public function __construct($key = '', int $maxAttempts = 60, int $decayMinutes = 1)
+    {
+        $this->key = $key;
+        $this->maxAttempts = $maxAttempts;
+        $this->decayMinutes = $decayMinutes;
+    }
+
+    /**
+     * Create a new rate limit.
+     *
+     * @param  int  $maxAttempts
+     * @return static
+     */
+    public static function perMinute($maxAttempts)
+    {
+        return new static('', $maxAttempts);
+    }
+
+    /**
+     * Create a new rate limit using minutes as decay time.
+     *
+     * @param  int  $decayMinutes
+     * @param  int  $maxAttempts
+     * @return static
+     */
+    public static function perMinutes($decayMinutes, $maxAttempts)
+    {
+        return new static('', $maxAttempts, $decayMinutes);
+    }
+
+    /**
+     * Create a new rate limit using hours as decay time.
+     *
+     * @param  int  $maxAttempts
+     * @param  int  $decayHours
+     * @return static
+     */
+    public static function perHour($maxAttempts, $decayHours = 1)
+    {
+        return new static('', $maxAttempts, 60 * $decayHours);
+    }
+
+    /**
+     * Create a new rate limit using days as decay time.
+     *
+     * @param  int  $maxAttempts
+     * @param  int  $decayDays
+     * @return static
+     */
+    public static function perDay($maxAttempts, $decayDays = 1)
+    {
+        return new static('', $maxAttempts, 60 * 24 * $decayDays);
+    }
+
+    /**
+     * Create a new unlimited rate limit.
+     *
+     * @return static
+     */
+    public static function none()
+    {
+        return new Unlimited;
+    }
+
+    /**
+     * Set the key of the rate limit.
+     *
+     * @param  mixed  $key
+     * @return $this
+     */
+    public function by($key)
+    {
+        $this->key = $key;
+
+        return $this;
+    }
+
+    /**
+     * Set the callback that should generate the response when the limit is exceeded.
+     *
+     * @param  callable  $callback
+     * @return $this
+     */
+    public function response(callable $callback)
+    {
+        $this->responseCallback = $callback;
+
+        return $this;
+    }
+}

+ 16 - 0
vendor/illuminate/cache/RateLimiting/Unlimited.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace Illuminate\Cache\RateLimiting;
+
+class Unlimited extends GlobalLimit
+{
+    /**
+     * Create a new limit instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct(PHP_INT_MAX);
+    }
+}

+ 83 - 0
vendor/illuminate/cache/RedisLock.php

@@ -0,0 +1,83 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class RedisLock extends Lock
+{
+    /**
+     * The Redis factory implementation.
+     *
+     * @var \Illuminate\Redis\Connections\Connection
+     */
+    protected $redis;
+
+    /**
+     * Create a new lock instance.
+     *
+     * @param  \Illuminate\Redis\Connections\Connection  $redis
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return void
+     */
+    public function __construct($redis, $name, $seconds, $owner = null)
+    {
+        parent::__construct($name, $seconds, $owner);
+
+        $this->redis = $redis;
+    }
+
+    /**
+     * Attempt to acquire the lock.
+     *
+     * @return bool
+     */
+    public function acquire()
+    {
+        if ($this->seconds > 0) {
+            return $this->redis->set($this->name, $this->owner, 'EX', $this->seconds, 'NX') == true;
+        }
+
+        return $this->redis->setnx($this->name, $this->owner) === 1;
+    }
+
+    /**
+     * Release the lock.
+     *
+     * @return bool
+     */
+    public function release()
+    {
+        return (bool) $this->redis->eval(LuaScripts::releaseLock(), 1, $this->name, $this->owner);
+    }
+
+    /**
+     * Releases this lock in disregard of ownership.
+     *
+     * @return void
+     */
+    public function forceRelease()
+    {
+        $this->redis->del($this->name);
+    }
+
+    /**
+     * Returns the owner value written into the driver for this lock.
+     *
+     * @return string
+     */
+    protected function getCurrentOwner()
+    {
+        return $this->redis->get($this->name);
+    }
+
+    /**
+     * Get the name of the Redis connection being used to manage the lock.
+     *
+     * @return string
+     */
+    public function getConnectionName()
+    {
+        return $this->redis->getName();
+    }
+}

+ 419 - 0
vendor/illuminate/cache/RedisStore.php

@@ -0,0 +1,419 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Contracts\Cache\LockProvider;
+use Illuminate\Contracts\Redis\Factory as Redis;
+use Illuminate\Redis\Connections\PhpRedisConnection;
+use Illuminate\Redis\Connections\PredisConnection;
+use Illuminate\Support\LazyCollection;
+use Illuminate\Support\Str;
+
+class RedisStore extends TaggableStore implements LockProvider
+{
+    /**
+     * The Redis factory implementation.
+     *
+     * @var \Illuminate\Contracts\Redis\Factory
+     */
+    protected $redis;
+
+    /**
+     * A string that should be prepended to keys.
+     *
+     * @var string
+     */
+    protected $prefix;
+
+    /**
+     * The Redis connection instance that should be used to manage locks.
+     *
+     * @var string
+     */
+    protected $connection;
+
+    /**
+     * The name of the connection that should be used for locks.
+     *
+     * @var string
+     */
+    protected $lockConnection;
+
+    /**
+     * Create a new Redis store.
+     *
+     * @param  \Illuminate\Contracts\Redis\Factory  $redis
+     * @param  string  $prefix
+     * @param  string  $connection
+     * @return void
+     */
+    public function __construct(Redis $redis, $prefix = '', $connection = 'default')
+    {
+        $this->redis = $redis;
+        $this->setPrefix($prefix);
+        $this->setConnection($connection);
+    }
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @param  string|array  $key
+     * @return mixed
+     */
+    public function get($key)
+    {
+        $value = $this->connection()->get($this->prefix.$key);
+
+        return ! is_null($value) ? $this->unserialize($value) : null;
+    }
+
+    /**
+     * Retrieve multiple items from the cache by key.
+     *
+     * Items not found in the cache will have a null value.
+     *
+     * @param  array  $keys
+     * @return array
+     */
+    public function many(array $keys)
+    {
+        if (count($keys) === 0) {
+            return [];
+        }
+
+        $results = [];
+
+        $values = $this->connection()->mget(array_map(function ($key) {
+            return $this->prefix.$key;
+        }, $keys));
+
+        foreach ($values as $index => $value) {
+            $results[$keys[$index]] = ! is_null($value) ? $this->unserialize($value) : null;
+        }
+
+        return $results;
+    }
+
+    /**
+     * Store an item in the cache for a given number of seconds.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function put($key, $value, $seconds)
+    {
+        return (bool) $this->connection()->setex(
+            $this->prefix.$key, (int) max(1, $seconds), $this->serialize($value)
+        );
+    }
+
+    /**
+     * Store multiple items in the cache for a given number of seconds.
+     *
+     * @param  array  $values
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function putMany(array $values, $seconds)
+    {
+        $serializedValues = [];
+
+        foreach ($values as $key => $value) {
+            $serializedValues[$this->prefix.$key] = $this->serialize($value);
+        }
+
+        $this->connection()->multi();
+
+        $manyResult = null;
+
+        foreach ($serializedValues as $key => $value) {
+            $result = (bool) $this->connection()->setex(
+                $key, (int) max(1, $seconds), $value
+            );
+
+            $manyResult = is_null($manyResult) ? $result : $result && $manyResult;
+        }
+
+        $this->connection()->exec();
+
+        return $manyResult ?: false;
+    }
+
+    /**
+     * Store an item in the cache if the key doesn't exist.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function add($key, $value, $seconds)
+    {
+        $lua = "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])";
+
+        return (bool) $this->connection()->eval(
+            $lua, 1, $this->prefix.$key, $this->serialize($value), (int) max(1, $seconds)
+        );
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int
+     */
+    public function increment($key, $value = 1)
+    {
+        return $this->connection()->incrby($this->prefix.$key, $value);
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int
+     */
+    public function decrement($key, $value = 1)
+    {
+        return $this->connection()->decrby($this->prefix.$key, $value);
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        return (bool) $this->connection()->set($this->prefix.$key, $this->serialize($value));
+    }
+
+    /**
+     * Get a lock instance.
+     *
+     * @param  string  $name
+     * @param  int  $seconds
+     * @param  string|null  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function lock($name, $seconds = 0, $owner = null)
+    {
+        $lockName = $this->prefix.$name;
+
+        $lockConnection = $this->lockConnection();
+
+        if ($lockConnection instanceof PhpRedisConnection) {
+            return new PhpRedisLock($lockConnection, $lockName, $seconds, $owner);
+        }
+
+        return new RedisLock($lockConnection, $lockName, $seconds, $owner);
+    }
+
+    /**
+     * Restore a lock instance using the owner identifier.
+     *
+     * @param  string  $name
+     * @param  string  $owner
+     * @return \Illuminate\Contracts\Cache\Lock
+     */
+    public function restoreLock($name, $owner)
+    {
+        return $this->lock($name, 0, $owner);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forget($key)
+    {
+        return (bool) $this->connection()->del($this->prefix.$key);
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        $this->connection()->flushdb();
+
+        return true;
+    }
+
+    /**
+     * Remove all expired tag set entries.
+     *
+     * @return void
+     */
+    public function flushStaleTags()
+    {
+        foreach ($this->currentTags()->chunk(1000) as $tags) {
+            $this->tags($tags->all())->flushStale();
+        }
+    }
+
+    /**
+     * Begin executing a new tags operation.
+     *
+     * @param  array|mixed  $names
+     * @return \Illuminate\Cache\RedisTaggedCache
+     */
+    public function tags($names)
+    {
+        return new RedisTaggedCache(
+            $this, new RedisTagSet($this, is_array($names) ? $names : func_get_args())
+        );
+    }
+
+    /**
+     * Get a collection of all of the cache tags currently being used.
+     *
+     * @param  int  $chunkSize
+     * @return \Illuminate\Support\LazyCollection
+     */
+    protected function currentTags($chunkSize = 1000)
+    {
+        $connection = $this->connection();
+
+        // Connections can have a global prefix...
+        $connectionPrefix = match (true) {
+            $connection instanceof PhpRedisConnection => $connection->_prefix(''),
+            $connection instanceof PredisConnection => $connection->getOptions()->prefix ?: '',
+            default => '',
+        };
+
+        $prefix = $connectionPrefix.$this->getPrefix();
+
+        return LazyCollection::make(function () use ($connection, $chunkSize, $prefix) {
+            $cursor = $defaultCursorValue = '0';
+
+            do {
+                [$cursor, $tagsChunk] = $connection->scan(
+                    $cursor,
+                    ['match' => $prefix.'tag:*:entries', 'count' => $chunkSize]
+                );
+
+                if (! is_array($tagsChunk)) {
+                    break;
+                }
+
+                $tagsChunk = array_unique($tagsChunk);
+
+                if (empty($tagsChunk)) {
+                    continue;
+                }
+
+                foreach ($tagsChunk as $tag) {
+                    yield $tag;
+                }
+            } while (((string) $cursor) !== $defaultCursorValue);
+        })->map(fn (string $tagKey) => Str::match('/^'.preg_quote($prefix, '/').'tag:(.*):entries$/', $tagKey));
+    }
+
+    /**
+     * Get the Redis connection instance.
+     *
+     * @return \Illuminate\Redis\Connections\Connection
+     */
+    public function connection()
+    {
+        return $this->redis->connection($this->connection);
+    }
+
+    /**
+     * Get the Redis connection instance that should be used to manage locks.
+     *
+     * @return \Illuminate\Redis\Connections\Connection
+     */
+    public function lockConnection()
+    {
+        return $this->redis->connection($this->lockConnection ?? $this->connection);
+    }
+
+    /**
+     * Specify the name of the connection that should be used to store data.
+     *
+     * @param  string  $connection
+     * @return void
+     */
+    public function setConnection($connection)
+    {
+        $this->connection = $connection;
+    }
+
+    /**
+     * Specify the name of the connection that should be used to manage locks.
+     *
+     * @param  string  $connection
+     * @return $this
+     */
+    public function setLockConnection($connection)
+    {
+        $this->lockConnection = $connection;
+
+        return $this;
+    }
+
+    /**
+     * Get the Redis database instance.
+     *
+     * @return \Illuminate\Contracts\Redis\Factory
+     */
+    public function getRedis()
+    {
+        return $this->redis;
+    }
+
+    /**
+     * Get the cache key prefix.
+     *
+     * @return string
+     */
+    public function getPrefix()
+    {
+        return $this->prefix;
+    }
+
+    /**
+     * Set the cache key prefix.
+     *
+     * @param  string  $prefix
+     * @return void
+     */
+    public function setPrefix($prefix)
+    {
+        $this->prefix = ! empty($prefix) ? $prefix.':' : '';
+    }
+
+    /**
+     * Serialize the value.
+     *
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function serialize($value)
+    {
+        return is_numeric($value) && ! in_array($value, [INF, -INF]) && ! is_nan($value) ? $value : serialize($value);
+    }
+
+    /**
+     * Unserialize the value.
+     *
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function unserialize($value)
+    {
+        return is_numeric($value) ? $value : unserialize($value);
+    }
+}

+ 125 - 0
vendor/illuminate/cache/RedisTagSet.php

@@ -0,0 +1,125 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Support\Carbon;
+use Illuminate\Support\LazyCollection;
+
+class RedisTagSet extends TagSet
+{
+    /**
+     * Add a reference entry to the tag set's underlying sorted set.
+     *
+     * @param  string  $key
+     * @param  int|null  $ttl
+     * @param  string  $updateWhen
+     * @return void
+     */
+    public function addEntry(string $key, ?int $ttl = null, $updateWhen = null)
+    {
+        $ttl = is_null($ttl) ? -1 : Carbon::now()->addSeconds($ttl)->getTimestamp();
+
+        foreach ($this->tagIds() as $tagKey) {
+            if ($updateWhen) {
+                $this->store->connection()->zadd($this->store->getPrefix().$tagKey, $updateWhen, $ttl, $key);
+            } else {
+                $this->store->connection()->zadd($this->store->getPrefix().$tagKey, $ttl, $key);
+            }
+        }
+    }
+
+    /**
+     * Get all of the cache entry keys for the tag set.
+     *
+     * @return \Illuminate\Support\LazyCollection
+     */
+    public function entries()
+    {
+        return LazyCollection::make(function () {
+            foreach ($this->tagIds() as $tagKey) {
+                $cursor = $defaultCursorValue = '0';
+
+                do {
+                    [$cursor, $entries] = $this->store->connection()->zscan(
+                        $this->store->getPrefix().$tagKey,
+                        $cursor,
+                        ['match' => '*', 'count' => 1000]
+                    );
+
+                    if (! is_array($entries)) {
+                        break;
+                    }
+
+                    $entries = array_unique(array_keys($entries));
+
+                    if (count($entries) === 0) {
+                        continue;
+                    }
+
+                    foreach ($entries as $entry) {
+                        yield $entry;
+                    }
+                } while (((string) $cursor) !== $defaultCursorValue);
+            }
+        });
+    }
+
+    /**
+     * Remove the stale entries from the tag set.
+     *
+     * @return void
+     */
+    public function flushStaleEntries()
+    {
+        $this->store->connection()->pipeline(function ($pipe) {
+            foreach ($this->tagIds() as $tagKey) {
+                $pipe->zremrangebyscore($this->store->getPrefix().$tagKey, 0, Carbon::now()->getTimestamp());
+            }
+        });
+    }
+
+    /**
+     * Flush the tag from the cache.
+     *
+     * @param  string  $name
+     */
+    public function flushTag($name)
+    {
+        return $this->resetTag($name);
+    }
+
+    /**
+     * Reset the tag and return the new tag identifier.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function resetTag($name)
+    {
+        $this->store->forget($this->tagKey($name));
+
+        return $this->tagId($name);
+    }
+
+    /**
+     * Get the unique tag identifier for a given tag.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function tagId($name)
+    {
+        return "tag:{$name}:entries";
+    }
+
+    /**
+     * Get the tag identifier key for a given tag.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function tagKey($name)
+    {
+        return "tag:{$name}:entries";
+    }
+}

+ 141 - 0
vendor/illuminate/cache/RedisTaggedCache.php

@@ -0,0 +1,141 @@
+<?php
+
+namespace Illuminate\Cache;
+
+class RedisTaggedCache extends TaggedCache
+{
+    /**
+     * Store an item in the cache if the key does not exist.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  \DateTimeInterface|\DateInterval|int|null  $ttl
+     * @return bool
+     */
+    public function add($key, $value, $ttl = null)
+    {
+        $seconds = null;
+
+        if ($ttl !== null) {
+            $seconds = $this->getSeconds($ttl);
+
+            if ($seconds > 0) {
+                $this->tags->addEntry(
+                    $this->itemKey($key),
+                    $seconds
+                );
+            }
+        }
+
+        return parent::add($key, $value, $ttl);
+    }
+
+    /**
+     * Store an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  \DateTimeInterface|\DateInterval|int|null  $ttl
+     * @return bool
+     */
+    public function put($key, $value, $ttl = null)
+    {
+        if (is_null($ttl)) {
+            return $this->forever($key, $value);
+        }
+
+        $seconds = $this->getSeconds($ttl);
+
+        if ($seconds > 0) {
+            $this->tags->addEntry(
+                $this->itemKey($key),
+                $seconds
+            );
+        }
+
+        return parent::put($key, $value, $ttl);
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function increment($key, $value = 1)
+    {
+        $this->tags->addEntry($this->itemKey($key), updateWhen: 'NX');
+
+        return parent::increment($key, $value);
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function decrement($key, $value = 1)
+    {
+        $this->tags->addEntry($this->itemKey($key), updateWhen: 'NX');
+
+        return parent::decrement($key, $value);
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        $this->tags->addEntry($this->itemKey($key));
+
+        return parent::forever($key, $value);
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        $this->flushValues();
+        $this->tags->flush();
+
+        return true;
+    }
+
+    /**
+     * Flush the individual cache entries for the tags.
+     *
+     * @return void
+     */
+    protected function flushValues()
+    {
+        $entries = $this->tags->entries()
+            ->map(fn (string $key) => $this->store->getPrefix().$key)
+            ->chunk(1000);
+
+        foreach ($entries as $cacheKeys) {
+            $this->store->connection()->del(...$cacheKeys);
+        }
+    }
+
+    /**
+     * Remove all stale reference entries from the tag set.
+     *
+     * @return bool
+     */
+    public function flushStale()
+    {
+        $this->tags->flushStaleEntries();
+
+        return true;
+    }
+}

+ 704 - 0
vendor/illuminate/cache/Repository.php

@@ -0,0 +1,704 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use ArrayAccess;
+use BadMethodCallException;
+use Closure;
+use DateTimeInterface;
+use Illuminate\Cache\Events\CacheHit;
+use Illuminate\Cache\Events\CacheMissed;
+use Illuminate\Cache\Events\KeyForgotten;
+use Illuminate\Cache\Events\KeyWritten;
+use Illuminate\Contracts\Cache\Repository as CacheContract;
+use Illuminate\Contracts\Cache\Store;
+use Illuminate\Contracts\Events\Dispatcher;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\InteractsWithTime;
+use Illuminate\Support\Traits\Macroable;
+
+/**
+ * @mixin \Illuminate\Contracts\Cache\Store
+ */
+class Repository implements ArrayAccess, CacheContract
+{
+    use InteractsWithTime, Macroable {
+        __call as macroCall;
+    }
+
+    /**
+     * The cache store implementation.
+     *
+     * @var \Illuminate\Contracts\Cache\Store
+     */
+    protected $store;
+
+    /**
+     * The event dispatcher implementation.
+     *
+     * @var \Illuminate\Contracts\Events\Dispatcher
+     */
+    protected $events;
+
+    /**
+     * The default number of seconds to store items.
+     *
+     * @var int|null
+     */
+    protected $default = 3600;
+
+    /**
+     * Create a new cache repository instance.
+     *
+     * @param  \Illuminate\Contracts\Cache\Store  $store
+     * @return void
+     */
+    public function __construct(Store $store)
+    {
+        $this->store = $store;
+    }
+
+    /**
+     * Determine if an item exists in the cache.
+     *
+     * @param  array|string  $key
+     * @return bool
+     */
+    public function has($key): bool
+    {
+        return ! is_null($this->get($key));
+    }
+
+    /**
+     * Determine if an item doesn't exist in the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function missing($key)
+    {
+        return ! $this->has($key);
+    }
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @template TCacheValue
+     *
+     * @param  array|string  $key
+     * @param  TCacheValue|(\Closure(): TCacheValue)  $default
+     * @return (TCacheValue is null ? mixed : TCacheValue)
+     */
+    public function get($key, $default = null): mixed
+    {
+        if (is_array($key)) {
+            return $this->many($key);
+        }
+
+        $value = $this->store->get($this->itemKey($key));
+
+        // If we could not find the cache value, we will fire the missed event and get
+        // the default value for this cache value. This default could be a callback
+        // so we will execute the value function which will resolve it if needed.
+        if (is_null($value)) {
+            $this->event(new CacheMissed($key));
+
+            $value = value($default);
+        } else {
+            $this->event(new CacheHit($key, $value));
+        }
+
+        return $value;
+    }
+
+    /**
+     * Retrieve multiple items from the cache by key.
+     *
+     * Items not found in the cache will have a null value.
+     *
+     * @param  array  $keys
+     * @return array
+     */
+    public function many(array $keys)
+    {
+        $values = $this->store->many(collect($keys)->map(function ($value, $key) {
+            return is_string($key) ? $key : $value;
+        })->values()->all());
+
+        return collect($values)->map(function ($value, $key) use ($keys) {
+            return $this->handleManyResult($keys, $key, $value);
+        })->all();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return iterable
+     */
+    public function getMultiple($keys, $default = null): iterable
+    {
+        $defaults = [];
+
+        foreach ($keys as $key) {
+            $defaults[$key] = $default;
+        }
+
+        return $this->many($defaults);
+    }
+
+    /**
+     * Handle a result for the "many" method.
+     *
+     * @param  array  $keys
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    protected function handleManyResult($keys, $key, $value)
+    {
+        // If we could not find the cache value, we will fire the missed event and get
+        // the default value for this cache value. This default could be a callback
+        // so we will execute the value function which will resolve it if needed.
+        if (is_null($value)) {
+            $this->event(new CacheMissed($key));
+
+            return (isset($keys[$key]) && ! array_is_list($keys)) ? value($keys[$key]) : null;
+        }
+
+        // If we found a valid value we will fire the "hit" event and return the value
+        // back from this function. The "hit" event gives developers an opportunity
+        // to listen for every possible cache "hit" throughout this applications.
+        $this->event(new CacheHit($key, $value));
+
+        return $value;
+    }
+
+    /**
+     * Retrieve an item from the cache and delete it.
+     *
+     * @template TCacheValue
+     *
+     * @param  array|string  $key
+     * @param  TCacheValue|(\Closure(): TCacheValue)  $default
+     * @return (TCacheValue is null ? mixed : TCacheValue)
+     */
+    public function pull($key, $default = null)
+    {
+        return tap($this->get($key, $default), function () use ($key) {
+            $this->forget($key);
+        });
+    }
+
+    /**
+     * Store an item in the cache.
+     *
+     * @param  array|string  $key
+     * @param  mixed  $value
+     * @param  \DateTimeInterface|\DateInterval|int|null  $ttl
+     * @return bool
+     */
+    public function put($key, $value, $ttl = null)
+    {
+        if (is_array($key)) {
+            return $this->putMany($key, $value);
+        }
+
+        if ($ttl === null) {
+            return $this->forever($key, $value);
+        }
+
+        $seconds = $this->getSeconds($ttl);
+
+        if ($seconds <= 0) {
+            return $this->forget($key);
+        }
+
+        $result = $this->store->put($this->itemKey($key), $value, $seconds);
+
+        if ($result) {
+            $this->event(new KeyWritten($key, $value, $seconds));
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return bool
+     */
+    public function set($key, $value, $ttl = null): bool
+    {
+        return $this->put($key, $value, $ttl);
+    }
+
+    /**
+     * Store multiple items in the cache for a given number of seconds.
+     *
+     * @param  array  $values
+     * @param  \DateTimeInterface|\DateInterval|int|null  $ttl
+     * @return bool
+     */
+    public function putMany(array $values, $ttl = null)
+    {
+        if ($ttl === null) {
+            return $this->putManyForever($values);
+        }
+
+        $seconds = $this->getSeconds($ttl);
+
+        if ($seconds <= 0) {
+            return $this->deleteMultiple(array_keys($values));
+        }
+
+        $result = $this->store->putMany($values, $seconds);
+
+        if ($result) {
+            foreach ($values as $key => $value) {
+                $this->event(new KeyWritten($key, $value, $seconds));
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Store multiple items in the cache indefinitely.
+     *
+     * @param  array  $values
+     * @return bool
+     */
+    protected function putManyForever(array $values)
+    {
+        $result = true;
+
+        foreach ($values as $key => $value) {
+            if (! $this->forever($key, $value)) {
+                $result = false;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return bool
+     */
+    public function setMultiple($values, $ttl = null): bool
+    {
+        return $this->putMany(is_array($values) ? $values : iterator_to_array($values), $ttl);
+    }
+
+    /**
+     * Store an item in the cache if the key does not exist.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @param  \DateTimeInterface|\DateInterval|int|null  $ttl
+     * @return bool
+     */
+    public function add($key, $value, $ttl = null)
+    {
+        $seconds = null;
+
+        if ($ttl !== null) {
+            $seconds = $this->getSeconds($ttl);
+
+            if ($seconds <= 0) {
+                return false;
+            }
+
+            // If the store has an "add" method we will call the method on the store so it
+            // has a chance to override this logic. Some drivers better support the way
+            // this operation should work with a total "atomic" implementation of it.
+            if (method_exists($this->store, 'add')) {
+                return $this->store->add(
+                    $this->itemKey($key), $value, $seconds
+                );
+            }
+        }
+
+        // If the value did not exist in the cache, we will put the value in the cache
+        // so it exists for subsequent requests. Then, we will return true so it is
+        // easy to know if the value gets added. Otherwise, we will return false.
+        if (is_null($this->get($key))) {
+            return $this->put($key, $value, $seconds);
+        }
+
+        return false;
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function increment($key, $value = 1)
+    {
+        return $this->store->increment($key, $value);
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function decrement($key, $value = 1)
+    {
+        return $this->store->decrement($key, $value);
+    }
+
+    /**
+     * Store an item in the cache indefinitely.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function forever($key, $value)
+    {
+        $result = $this->store->forever($this->itemKey($key), $value);
+
+        if ($result) {
+            $this->event(new KeyWritten($key, $value));
+        }
+
+        return $result;
+    }
+
+    /**
+     * Get an item from the cache, or execute the given Closure and store the result.
+     *
+     * @template TCacheValue
+     *
+     * @param  string  $key
+     * @param  \Closure|\DateTimeInterface|\DateInterval|int|null  $ttl
+     * @param  \Closure(): TCacheValue  $callback
+     * @return TCacheValue
+     */
+    public function remember($key, $ttl, Closure $callback)
+    {
+        $value = $this->get($key);
+
+        // If the item exists in the cache we will just return this immediately and if
+        // not we will execute the given Closure and cache the result of that for a
+        // given number of seconds so it's available for all subsequent requests.
+        if (! is_null($value)) {
+            return $value;
+        }
+
+        $value = $callback();
+
+        $this->put($key, $value, value($ttl, $value));
+
+        return $value;
+    }
+
+    /**
+     * Get an item from the cache, or execute the given Closure and store the result forever.
+     *
+     * @template TCacheValue
+     *
+     * @param  string  $key
+     * @param  \Closure(): TCacheValue  $callback
+     * @return TCacheValue
+     */
+    public function sear($key, Closure $callback)
+    {
+        return $this->rememberForever($key, $callback);
+    }
+
+    /**
+     * Get an item from the cache, or execute the given Closure and store the result forever.
+     *
+     * @template TCacheValue
+     *
+     * @param  string  $key
+     * @param  \Closure(): TCacheValue  $callback
+     * @return TCacheValue
+     */
+    public function rememberForever($key, Closure $callback)
+    {
+        $value = $this->get($key);
+
+        // If the item exists in the cache we will just return this immediately
+        // and if not we will execute the given Closure and cache the result
+        // of that forever so it is available for all subsequent requests.
+        if (! is_null($value)) {
+            return $value;
+        }
+
+        $this->forever($key, $value = $callback());
+
+        return $value;
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function forget($key)
+    {
+        return tap($this->store->forget($this->itemKey($key)), function ($result) use ($key) {
+            if ($result) {
+                $this->event(new KeyForgotten($key));
+            }
+        });
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return bool
+     */
+    public function delete($key): bool
+    {
+        return $this->forget($key);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return bool
+     */
+    public function deleteMultiple($keys): bool
+    {
+        $result = true;
+
+        foreach ($keys as $key) {
+            if (! $this->forget($key)) {
+                $result = false;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return bool
+     */
+    public function clear(): bool
+    {
+        return $this->store->flush();
+    }
+
+    /**
+     * Begin executing a new tags operation if the store supports it.
+     *
+     * @param  array|mixed  $names
+     * @return \Illuminate\Cache\TaggedCache
+     *
+     * @throws \BadMethodCallException
+     */
+    public function tags($names)
+    {
+        if (! $this->supportsTags()) {
+            throw new BadMethodCallException('This cache store does not support tagging.');
+        }
+
+        $cache = $this->store->tags(is_array($names) ? $names : func_get_args());
+
+        if (! is_null($this->events)) {
+            $cache->setEventDispatcher($this->events);
+        }
+
+        return $cache->setDefaultCacheTime($this->default);
+    }
+
+    /**
+     * Format the key for a cache item.
+     *
+     * @param  string  $key
+     * @return string
+     */
+    protected function itemKey($key)
+    {
+        return $key;
+    }
+
+    /**
+     * Calculate the number of seconds for the given TTL.
+     *
+     * @param  \DateTimeInterface|\DateInterval|int  $ttl
+     * @return int
+     */
+    protected function getSeconds($ttl)
+    {
+        $duration = $this->parseDateInterval($ttl);
+
+        if ($duration instanceof DateTimeInterface) {
+            $duration = Carbon::now()->diffInRealSeconds($duration, false);
+        }
+
+        return (int) ($duration > 0 ? $duration : 0);
+    }
+
+    /**
+     * Determine if the current store supports tags.
+     *
+     * @return bool
+     */
+    public function supportsTags()
+    {
+        return method_exists($this->store, 'tags');
+    }
+
+    /**
+     * Get the default cache time.
+     *
+     * @return int|null
+     */
+    public function getDefaultCacheTime()
+    {
+        return $this->default;
+    }
+
+    /**
+     * Set the default cache time in seconds.
+     *
+     * @param  int|null  $seconds
+     * @return $this
+     */
+    public function setDefaultCacheTime($seconds)
+    {
+        $this->default = $seconds;
+
+        return $this;
+    }
+
+    /**
+     * Get the cache store implementation.
+     *
+     * @return \Illuminate\Contracts\Cache\Store
+     */
+    public function getStore()
+    {
+        return $this->store;
+    }
+
+    /**
+     * Set the cache store implementation.
+     *
+     * @param  \Illuminate\Contracts\Cache\Store  $store
+     * @return static
+     */
+    public function setStore($store)
+    {
+        $this->store = $store;
+
+        return $this;
+    }
+
+    /**
+     * Fire an event for this cache instance.
+     *
+     * @param  object|string  $event
+     * @return void
+     */
+    protected function event($event)
+    {
+        $this->events?->dispatch($event);
+    }
+
+    /**
+     * Get the event dispatcher instance.
+     *
+     * @return \Illuminate\Contracts\Events\Dispatcher
+     */
+    public function getEventDispatcher()
+    {
+        return $this->events;
+    }
+
+    /**
+     * Set the event dispatcher instance.
+     *
+     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
+     * @return void
+     */
+    public function setEventDispatcher(Dispatcher $events)
+    {
+        $this->events = $events;
+    }
+
+    /**
+     * Determine if a cached value exists.
+     *
+     * @param  string  $key
+     * @return bool
+     */
+    public function offsetExists($key): bool
+    {
+        return $this->has($key);
+    }
+
+    /**
+     * Retrieve an item from the cache by key.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function offsetGet($key): mixed
+    {
+        return $this->get($key);
+    }
+
+    /**
+     * Store an item in the cache for the default time.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return void
+     */
+    public function offsetSet($key, $value): void
+    {
+        $this->put($key, $value, $this->default);
+    }
+
+    /**
+     * Remove an item from the cache.
+     *
+     * @param  string  $key
+     * @return void
+     */
+    public function offsetUnset($key): void
+    {
+        $this->forget($key);
+    }
+
+    /**
+     * Handle dynamic calls into macros or pass missing methods to the store.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        if (static::hasMacro($method)) {
+            return $this->macroCall($method, $parameters);
+        }
+
+        return $this->store->$method(...$parameters);
+    }
+
+    /**
+     * Clone cache repository instance.
+     *
+     * @return void
+     */
+    public function __clone()
+    {
+        $this->store = clone $this->store;
+    }
+}

+ 49 - 0
vendor/illuminate/cache/RetrievesMultipleKeys.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace Illuminate\Cache;
+
+trait RetrievesMultipleKeys
+{
+    /**
+     * Retrieve multiple items from the cache by key.
+     *
+     * Items not found in the cache will have a null value.
+     *
+     * @param  array  $keys
+     * @return array
+     */
+    public function many(array $keys)
+    {
+        $return = [];
+
+        $keys = collect($keys)->mapWithKeys(function ($value, $key) {
+            return [is_string($key) ? $key : $value => is_string($key) ? $value : null];
+        })->all();
+
+        foreach ($keys as $key => $default) {
+            $return[$key] = $this->get($key, $default);
+        }
+
+        return $return;
+    }
+
+    /**
+     * Store multiple items in the cache for a given number of seconds.
+     *
+     * @param  array  $values
+     * @param  int  $seconds
+     * @return bool
+     */
+    public function putMany(array $values, $seconds)
+    {
+        $manyResult = null;
+
+        foreach ($values as $key => $value) {
+            $result = $this->put($key, $value, $seconds);
+
+            $manyResult = is_null($manyResult) ? $result : $result && $manyResult;
+        }
+
+        return $manyResult ?: false;
+    }
+}

+ 130 - 0
vendor/illuminate/cache/TagSet.php

@@ -0,0 +1,130 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Contracts\Cache\Store;
+
+class TagSet
+{
+    /**
+     * The cache store implementation.
+     *
+     * @var \Illuminate\Contracts\Cache\Store
+     */
+    protected $store;
+
+    /**
+     * The tag names.
+     *
+     * @var array
+     */
+    protected $names = [];
+
+    /**
+     * Create a new TagSet instance.
+     *
+     * @param  \Illuminate\Contracts\Cache\Store  $store
+     * @param  array  $names
+     * @return void
+     */
+    public function __construct(Store $store, array $names = [])
+    {
+        $this->store = $store;
+        $this->names = $names;
+    }
+
+    /**
+     * Reset all tags in the set.
+     *
+     * @return void
+     */
+    public function reset()
+    {
+        array_walk($this->names, [$this, 'resetTag']);
+    }
+
+    /**
+     * Reset the tag and return the new tag identifier.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function resetTag($name)
+    {
+        $this->store->forever($this->tagKey($name), $id = str_replace('.', '', uniqid('', true)));
+
+        return $id;
+    }
+
+    /**
+     * Flush all the tags in the set.
+     *
+     * @return void
+     */
+    public function flush()
+    {
+        array_walk($this->names, [$this, 'flushTag']);
+    }
+
+    /**
+     * Flush the tag from the cache.
+     *
+     * @param  string  $name
+     */
+    public function flushTag($name)
+    {
+        $this->store->forget($this->tagKey($name));
+    }
+
+    /**
+     * Get a unique namespace that changes when any of the tags are flushed.
+     *
+     * @return string
+     */
+    public function getNamespace()
+    {
+        return implode('|', $this->tagIds());
+    }
+
+    /**
+     * Get an array of tag identifiers for all of the tags in the set.
+     *
+     * @return array
+     */
+    protected function tagIds()
+    {
+        return array_map([$this, 'tagId'], $this->names);
+    }
+
+    /**
+     * Get the unique tag identifier for a given tag.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function tagId($name)
+    {
+        return $this->store->get($this->tagKey($name)) ?: $this->resetTag($name);
+    }
+
+    /**
+     * Get the tag identifier key for a given tag.
+     *
+     * @param  string  $name
+     * @return string
+     */
+    public function tagKey($name)
+    {
+        return 'tag:'.$name.':key';
+    }
+
+    /**
+     * Get all of the tag names in the set.
+     *
+     * @return array
+     */
+    public function getNames()
+    {
+        return $this->names;
+    }
+}

+ 19 - 0
vendor/illuminate/cache/TaggableStore.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Contracts\Cache\Store;
+
+abstract class TaggableStore implements Store
+{
+    /**
+     * Begin executing a new tags operation.
+     *
+     * @param  array|mixed  $names
+     * @return \Illuminate\Cache\TaggedCache
+     */
+    public function tags($names)
+    {
+        return new TaggedCache($this, new TagSet($this, is_array($names) ? $names : func_get_args()));
+    }
+}

+ 125 - 0
vendor/illuminate/cache/TaggedCache.php

@@ -0,0 +1,125 @@
+<?php
+
+namespace Illuminate\Cache;
+
+use Illuminate\Contracts\Cache\Store;
+
+class TaggedCache extends Repository
+{
+    use RetrievesMultipleKeys {
+        putMany as putManyAlias;
+    }
+
+    /**
+     * The tag set instance.
+     *
+     * @var \Illuminate\Cache\TagSet
+     */
+    protected $tags;
+
+    /**
+     * Create a new tagged cache instance.
+     *
+     * @param  \Illuminate\Contracts\Cache\Store  $store
+     * @param  \Illuminate\Cache\TagSet  $tags
+     * @return void
+     */
+    public function __construct(Store $store, TagSet $tags)
+    {
+        parent::__construct($store);
+
+        $this->tags = $tags;
+    }
+
+    /**
+     * Store multiple items in the cache for a given number of seconds.
+     *
+     * @param  array  $values
+     * @param  int|null  $ttl
+     * @return bool
+     */
+    public function putMany(array $values, $ttl = null)
+    {
+        if ($ttl === null) {
+            return $this->putManyForever($values);
+        }
+
+        return $this->putManyAlias($values, $ttl);
+    }
+
+    /**
+     * Increment the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function increment($key, $value = 1)
+    {
+        return $this->store->increment($this->itemKey($key), $value);
+    }
+
+    /**
+     * Decrement the value of an item in the cache.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return int|bool
+     */
+    public function decrement($key, $value = 1)
+    {
+        return $this->store->decrement($this->itemKey($key), $value);
+    }
+
+    /**
+     * Remove all items from the cache.
+     *
+     * @return bool
+     */
+    public function flush()
+    {
+        $this->tags->reset();
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function itemKey($key)
+    {
+        return $this->taggedItemKey($key);
+    }
+
+    /**
+     * Get a fully qualified key for a tagged item.
+     *
+     * @param  string  $key
+     * @return string
+     */
+    public function taggedItemKey($key)
+    {
+        return sha1($this->tags->getNamespace()).':'.$key;
+    }
+
+    /**
+     * Fire an event for this cache instance.
+     *
+     * @param  \Illuminate\Cache\Events\CacheEvent  $event
+     * @return void
+     */
+    protected function event($event)
+    {
+        parent::event($event->setTags($this->tags->getNames()));
+    }
+
+    /**
+     * Get the tag set instance.
+     *
+     * @return \Illuminate\Cache\TagSet
+     */
+    public function getTags()
+    {
+        return $this->tags;
+    }
+}

+ 49 - 0
vendor/illuminate/cache/composer.json

@@ -0,0 +1,49 @@
+{
+    "name": "illuminate/cache",
+    "description": "The Illuminate Cache package.",
+    "license": "MIT",
+    "homepage": "https://laravel.com",
+    "support": {
+        "issues": "https://github.com/laravel/framework/issues",
+        "source": "https://github.com/laravel/framework"
+    },
+    "authors": [
+        {
+            "name": "Taylor Otwell",
+            "email": "taylor@laravel.com"
+        }
+    ],
+    "require": {
+        "php": "^8.1",
+        "illuminate/collections": "^10.0",
+        "illuminate/contracts": "^10.0",
+        "illuminate/macroable": "^10.0",
+        "illuminate/support": "^10.0"
+    },
+    "provide": {
+        "psr/simple-cache-implementation": "1.0|2.0|3.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Illuminate\\Cache\\": ""
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "10.x-dev"
+        }
+    },
+    "suggest": {
+        "ext-apcu": "Required to use the APC cache driver.",
+        "ext-filter": "Required to use the DynamoDb cache driver.",
+        "ext-memcached": "Required to use the memcache cache driver.",
+        "illuminate/database": "Required to use the database cache driver (^10.0).",
+        "illuminate/filesystem": "Required to use the file cache driver (^10.0).",
+        "illuminate/redis": "Required to use the redis cache driver (^10.0).",
+        "symfony/cache": "Required to use PSR-6 cache bridge (^6.2)."
+    },
+    "config": {
+        "sort-packages": true
+    },
+    "minimum-stability": "dev"
+}

+ 939 - 0
vendor/illuminate/collections/Arr.php

@@ -0,0 +1,939 @@
+<?php
+
+namespace Illuminate\Support;
+
+use ArgumentCountError;
+use ArrayAccess;
+use Illuminate\Support\Traits\Macroable;
+use InvalidArgumentException;
+
+class Arr
+{
+    use Macroable;
+
+    /**
+     * Determine whether the given value is array accessible.
+     *
+     * @param  mixed  $value
+     * @return bool
+     */
+    public static function accessible($value)
+    {
+        return is_array($value) || $value instanceof ArrayAccess;
+    }
+
+    /**
+     * Add an element to an array using "dot" notation if it doesn't exist.
+     *
+     * @param  array  $array
+     * @param  string|int|float  $key
+     * @param  mixed  $value
+     * @return array
+     */
+    public static function add($array, $key, $value)
+    {
+        if (is_null(static::get($array, $key))) {
+            static::set($array, $key, $value);
+        }
+
+        return $array;
+    }
+
+    /**
+     * Collapse an array of arrays into a single array.
+     *
+     * @param  iterable  $array
+     * @return array
+     */
+    public static function collapse($array)
+    {
+        $results = [];
+
+        foreach ($array as $values) {
+            if ($values instanceof Collection) {
+                $values = $values->all();
+            } elseif (! is_array($values)) {
+                continue;
+            }
+
+            $results[] = $values;
+        }
+
+        return array_merge([], ...$results);
+    }
+
+    /**
+     * Cross join the given arrays, returning all possible permutations.
+     *
+     * @param  iterable  ...$arrays
+     * @return array
+     */
+    public static function crossJoin(...$arrays)
+    {
+        $results = [[]];
+
+        foreach ($arrays as $index => $array) {
+            $append = [];
+
+            foreach ($results as $product) {
+                foreach ($array as $item) {
+                    $product[$index] = $item;
+
+                    $append[] = $product;
+                }
+            }
+
+            $results = $append;
+        }
+
+        return $results;
+    }
+
+    /**
+     * Divide an array into two arrays. One with keys and the other with values.
+     *
+     * @param  array  $array
+     * @return array
+     */
+    public static function divide($array)
+    {
+        return [array_keys($array), array_values($array)];
+    }
+
+    /**
+     * Flatten a multi-dimensional associative array with dots.
+     *
+     * @param  iterable  $array
+     * @param  string  $prepend
+     * @return array
+     */
+    public static function dot($array, $prepend = '')
+    {
+        $results = [];
+
+        foreach ($array as $key => $value) {
+            if (is_array($value) && ! empty($value)) {
+                $results = array_merge($results, static::dot($value, $prepend.$key.'.'));
+            } else {
+                $results[$prepend.$key] = $value;
+            }
+        }
+
+        return $results;
+    }
+
+    /**
+     * Convert a flatten "dot" notation array into an expanded array.
+     *
+     * @param  iterable  $array
+     * @return array
+     */
+    public static function undot($array)
+    {
+        $results = [];
+
+        foreach ($array as $key => $value) {
+            static::set($results, $key, $value);
+        }
+
+        return $results;
+    }
+
+    /**
+     * Get all of the given array except for a specified array of keys.
+     *
+     * @param  array  $array
+     * @param  array|string|int|float  $keys
+     * @return array
+     */
+    public static function except($array, $keys)
+    {
+        static::forget($array, $keys);
+
+        return $array;
+    }
+
+    /**
+     * Determine if the given key exists in the provided array.
+     *
+     * @param  \ArrayAccess|array  $array
+     * @param  string|int  $key
+     * @return bool
+     */
+    public static function exists($array, $key)
+    {
+        if ($array instanceof Enumerable) {
+            return $array->has($key);
+        }
+
+        if ($array instanceof ArrayAccess) {
+            return $array->offsetExists($key);
+        }
+
+        if (is_float($key)) {
+            $key = (string) $key;
+        }
+
+        return array_key_exists($key, $array);
+    }
+
+    /**
+     * Return the first element in an array passing a given truth test.
+     *
+     * @param  iterable  $array
+     * @param  callable|null  $callback
+     * @param  mixed  $default
+     * @return mixed
+     */
+    public static function first($array, ?callable $callback = null, $default = null)
+    {
+        if (is_null($callback)) {
+            if (empty($array)) {
+                return value($default);
+            }
+
+            foreach ($array as $item) {
+                return $item;
+            }
+
+            return value($default);
+        }
+
+        foreach ($array as $key => $value) {
+            if ($callback($value, $key)) {
+                return $value;
+            }
+        }
+
+        return value($default);
+    }
+
+    /**
+     * Return the last element in an array passing a given truth test.
+     *
+     * @param  array  $array
+     * @param  callable|null  $callback
+     * @param  mixed  $default
+     * @return mixed
+     */
+    public static function last($array, ?callable $callback = null, $default = null)
+    {
+        if (is_null($callback)) {
+            return empty($array) ? value($default) : end($array);
+        }
+
+        return static::first(array_reverse($array, true), $callback, $default);
+    }
+
+    /**
+     * Take the first or last {$limit} items from an array.
+     *
+     * @param  array  $array
+     * @param  int  $limit
+     * @return array
+     */
+    public static function take($array, $limit)
+    {
+        if ($limit < 0) {
+            return array_slice($array, $limit, abs($limit));
+        }
+
+        return array_slice($array, 0, $limit);
+    }
+
+    /**
+     * Flatten a multi-dimensional array into a single level.
+     *
+     * @param  iterable  $array
+     * @param  int  $depth
+     * @return array
+     */
+    public static function flatten($array, $depth = INF)
+    {
+        $result = [];
+
+        foreach ($array as $item) {
+            $item = $item instanceof Collection ? $item->all() : $item;
+
+            if (! is_array($item)) {
+                $result[] = $item;
+            } else {
+                $values = $depth === 1
+                    ? array_values($item)
+                    : static::flatten($item, $depth - 1);
+
+                foreach ($values as $value) {
+                    $result[] = $value;
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Remove one or many array items from a given array using "dot" notation.
+     *
+     * @param  array  $array
+     * @param  array|string|int|float  $keys
+     * @return void
+     */
+    public static function forget(&$array, $keys)
+    {
+        $original = &$array;
+
+        $keys = (array) $keys;
+
+        if (count($keys) === 0) {
+            return;
+        }
+
+        foreach ($keys as $key) {
+            // if the exact key exists in the top-level, remove it
+            if (static::exists($array, $key)) {
+                unset($array[$key]);
+
+                continue;
+            }
+
+            $parts = explode('.', $key);
+
+            // clean up before each pass
+            $array = &$original;
+
+            while (count($parts) > 1) {
+                $part = array_shift($parts);
+
+                if (isset($array[$part]) && static::accessible($array[$part])) {
+                    $array = &$array[$part];
+                } else {
+                    continue 2;
+                }
+            }
+
+            unset($array[array_shift($parts)]);
+        }
+    }
+
+    /**
+     * Get an item from an array using "dot" notation.
+     *
+     * @param  \ArrayAccess|array  $array
+     * @param  string|int|null  $key
+     * @param  mixed  $default
+     * @return mixed
+     */
+    public static function get($array, $key, $default = null)
+    {
+        if (! static::accessible($array)) {
+            return value($default);
+        }
+
+        if (is_null($key)) {
+            return $array;
+        }
+
+        if (static::exists($array, $key)) {
+            return $array[$key];
+        }
+
+        if (! str_contains($key, '.')) {
+            return $array[$key] ?? value($default);
+        }
+
+        foreach (explode('.', $key) as $segment) {
+            if (static::accessible($array) && static::exists($array, $segment)) {
+                $array = $array[$segment];
+            } else {
+                return value($default);
+            }
+        }
+
+        return $array;
+    }
+
+    /**
+     * Check if an item or items exist in an array using "dot" notation.
+     *
+     * @param  \ArrayAccess|array  $array
+     * @param  string|array  $keys
+     * @return bool
+     */
+    public static function has($array, $keys)
+    {
+        $keys = (array) $keys;
+
+        if (! $array || $keys === []) {
+            return false;
+        }
+
+        foreach ($keys as $key) {
+            $subKeyArray = $array;
+
+            if (static::exists($array, $key)) {
+                continue;
+            }
+
+            foreach (explode('.', $key) as $segment) {
+                if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) {
+                    $subKeyArray = $subKeyArray[$segment];
+                } else {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Determine if any of the keys exist in an array using "dot" notation.
+     *
+     * @param  \ArrayAccess|array  $array
+     * @param  string|array  $keys
+     * @return bool
+     */
+    public static function hasAny($array, $keys)
+    {
+        if (is_null($keys)) {
+            return false;
+        }
+
+        $keys = (array) $keys;
+
+        if (! $array) {
+            return false;
+        }
+
+        if ($keys === []) {
+            return false;
+        }
+
+        foreach ($keys as $key) {
+            if (static::has($array, $key)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Determines if an array is associative.
+     *
+     * An array is "associative" if it doesn't have sequential numerical keys beginning with zero.
+     *
+     * @param  array  $array
+     * @return bool
+     */
+    public static function isAssoc(array $array)
+    {
+        return ! array_is_list($array);
+    }
+
+    /**
+     * Determines if an array is a list.
+     *
+     * An array is a "list" if all array keys are sequential integers starting from 0 with no gaps in between.
+     *
+     * @param  array  $array
+     * @return bool
+     */
+    public static function isList($array)
+    {
+        return array_is_list($array);
+    }
+
+    /**
+     * Join all items using a string. The final items can use a separate glue string.
+     *
+     * @param  array  $array
+     * @param  string  $glue
+     * @param  string  $finalGlue
+     * @return string
+     */
+    public static function join($array, $glue, $finalGlue = '')
+    {
+        if ($finalGlue === '') {
+            return implode($glue, $array);
+        }
+
+        if (count($array) === 0) {
+            return '';
+        }
+
+        if (count($array) === 1) {
+            return end($array);
+        }
+
+        $finalItem = array_pop($array);
+
+        return implode($glue, $array).$finalGlue.$finalItem;
+    }
+
+    /**
+     * Key an associative array by a field or using a callback.
+     *
+     * @param  array  $array
+     * @param  callable|array|string  $keyBy
+     * @return array
+     */
+    public static function keyBy($array, $keyBy)
+    {
+        return Collection::make($array)->keyBy($keyBy)->all();
+    }
+
+    /**
+     * Prepend the key names of an associative array.
+     *
+     * @param  array  $array
+     * @param  string  $prependWith
+     * @return array
+     */
+    public static function prependKeysWith($array, $prependWith)
+    {
+        return static::mapWithKeys($array, fn ($item, $key) => [$prependWith.$key => $item]);
+    }
+
+    /**
+     * Get a subset of the items from the given array.
+     *
+     * @param  array  $array
+     * @param  array|string  $keys
+     * @return array
+     */
+    public static function only($array, $keys)
+    {
+        return array_intersect_key($array, array_flip((array) $keys));
+    }
+
+    /**
+     * Select an array of values from an array.
+     *
+     * @param  array  $array
+     * @param  array|string  $keys
+     * @return array
+     */
+    public static function select($array, $keys)
+    {
+        $keys = static::wrap($keys);
+
+        return static::map($array, function ($item) use ($keys) {
+            $result = [];
+
+            foreach ($keys as $key) {
+                if (Arr::accessible($item) && Arr::exists($item, $key)) {
+                    $result[$key] = $item[$key];
+                } elseif (is_object($item) && isset($item->{$key})) {
+                    $result[$key] = $item->{$key};
+                }
+            }
+
+            return $result;
+        });
+    }
+
+    /**
+     * Pluck an array of values from an array.
+     *
+     * @param  iterable  $array
+     * @param  string|array|int|null  $value
+     * @param  string|array|null  $key
+     * @return array
+     */
+    public static function pluck($array, $value, $key = null)
+    {
+        $results = [];
+
+        [$value, $key] = static::explodePluckParameters($value, $key);
+
+        foreach ($array as $item) {
+            $itemValue = data_get($item, $value);
+
+            // If the key is "null", we will just append the value to the array and keep
+            // looping. Otherwise we will key the array using the value of the key we
+            // received from the developer. Then we'll return the final array form.
+            if (is_null($key)) {
+                $results[] = $itemValue;
+            } else {
+                $itemKey = data_get($item, $key);
+
+                if (is_object($itemKey) && method_exists($itemKey, '__toString')) {
+                    $itemKey = (string) $itemKey;
+                }
+
+                $results[$itemKey] = $itemValue;
+            }
+        }
+
+        return $results;
+    }
+
+    /**
+     * Explode the "value" and "key" arguments passed to "pluck".
+     *
+     * @param  string|array  $value
+     * @param  string|array|null  $key
+     * @return array
+     */
+    protected static function explodePluckParameters($value, $key)
+    {
+        $value = is_string($value) ? explode('.', $value) : $value;
+
+        $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
+
+        return [$value, $key];
+    }
+
+    /**
+     * Run a map over each of the items in the array.
+     *
+     * @param  array  $array
+     * @param  callable  $callback
+     * @return array
+     */
+    public static function map(array $array, callable $callback)
+    {
+        $keys = array_keys($array);
+
+        try {
+            $items = array_map($callback, $array, $keys);
+        } catch (ArgumentCountError) {
+            $items = array_map($callback, $array);
+        }
+
+        return array_combine($keys, $items);
+    }
+
+    /**
+     * Run an associative map over each of the items.
+     *
+     * The callback should return an associative array with a single key/value pair.
+     *
+     * @template TKey
+     * @template TValue
+     * @template TMapWithKeysKey of array-key
+     * @template TMapWithKeysValue
+     *
+     * @param  array<TKey, TValue>  $array
+     * @param  callable(TValue, TKey): array<TMapWithKeysKey, TMapWithKeysValue>  $callback
+     * @return array
+     */
+    public static function mapWithKeys(array $array, callable $callback)
+    {
+        $result = [];
+
+        foreach ($array as $key => $value) {
+            $assoc = $callback($value, $key);
+
+            foreach ($assoc as $mapKey => $mapValue) {
+                $result[$mapKey] = $mapValue;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Push an item onto the beginning of an array.
+     *
+     * @param  array  $array
+     * @param  mixed  $value
+     * @param  mixed  $key
+     * @return array
+     */
+    public static function prepend($array, $value, $key = null)
+    {
+        if (func_num_args() == 2) {
+            array_unshift($array, $value);
+        } else {
+            $array = [$key => $value] + $array;
+        }
+
+        return $array;
+    }
+
+    /**
+     * Get a value from the array, and remove it.
+     *
+     * @param  array  $array
+     * @param  string|int  $key
+     * @param  mixed  $default
+     * @return mixed
+     */
+    public static function pull(&$array, $key, $default = null)
+    {
+        $value = static::get($array, $key, $default);
+
+        static::forget($array, $key);
+
+        return $value;
+    }
+
+    /**
+     * Convert the array into a query string.
+     *
+     * @param  array  $array
+     * @return string
+     */
+    public static function query($array)
+    {
+        return http_build_query($array, '', '&', PHP_QUERY_RFC3986);
+    }
+
+    /**
+     * Get one or a specified number of random values from an array.
+     *
+     * @param  array  $array
+     * @param  int|null  $number
+     * @param  bool  $preserveKeys
+     * @return mixed
+     *
+     * @throws \InvalidArgumentException
+     */
+    public static function random($array, $number = null, $preserveKeys = false)
+    {
+        $requested = is_null($number) ? 1 : $number;
+
+        $count = count($array);
+
+        if ($requested > $count) {
+            throw new InvalidArgumentException(
+                "You requested {$requested} items, but there are only {$count} items available."
+            );
+        }
+
+        if (is_null($number)) {
+            return $array[array_rand($array)];
+        }
+
+        if ((int) $number === 0) {
+            return [];
+        }
+
+        $keys = array_rand($array, $number);
+
+        $results = [];
+
+        if ($preserveKeys) {
+            foreach ((array) $keys as $key) {
+                $results[$key] = $array[$key];
+            }
+        } else {
+            foreach ((array) $keys as $key) {
+                $results[] = $array[$key];
+            }
+        }
+
+        return $results;
+    }
+
+    /**
+     * Set an array item to a given value using "dot" notation.
+     *
+     * If no key is given to the method, the entire array will be replaced.
+     *
+     * @param  array  $array
+     * @param  string|int|null  $key
+     * @param  mixed  $value
+     * @return array
+     */
+    public static function set(&$array, $key, $value)
+    {
+        if (is_null($key)) {
+            return $array = $value;
+        }
+
+        $keys = explode('.', $key);
+
+        foreach ($keys as $i => $key) {
+            if (count($keys) === 1) {
+                break;
+            }
+
+            unset($keys[$i]);
+
+            // If the key doesn't exist at this depth, we will just create an empty array
+            // to hold the next value, allowing us to create the arrays to hold final
+            // values at the correct depth. Then we'll keep digging into the array.
+            if (! isset($array[$key]) || ! is_array($array[$key])) {
+                $array[$key] = [];
+            }
+
+            $array = &$array[$key];
+        }
+
+        $array[array_shift($keys)] = $value;
+
+        return $array;
+    }
+
+    /**
+     * Shuffle the given array and return the result.
+     *
+     * @param  array  $array
+     * @param  int|null  $seed
+     * @return array
+     */
+    public static function shuffle($array, $seed = null)
+    {
+        if (is_null($seed)) {
+            shuffle($array);
+        } else {
+            mt_srand($seed);
+            shuffle($array);
+            mt_srand();
+        }
+
+        return $array;
+    }
+
+    /**
+     * Sort the array using the given callback or "dot" notation.
+     *
+     * @param  array  $array
+     * @param  callable|array|string|null  $callback
+     * @return array
+     */
+    public static function sort($array, $callback = null)
+    {
+        return Collection::make($array)->sortBy($callback)->all();
+    }
+
+    /**
+     * Sort the array in descending order using the given callback or "dot" notation.
+     *
+     * @param  array  $array
+     * @param  callable|array|string|null  $callback
+     * @return array
+     */
+    public static function sortDesc($array, $callback = null)
+    {
+        return Collection::make($array)->sortByDesc($callback)->all();
+    }
+
+    /**
+     * Recursively sort an array by keys and values.
+     *
+     * @param  array  $array
+     * @param  int  $options
+     * @param  bool  $descending
+     * @return array
+     */
+    public static function sortRecursive($array, $options = SORT_REGULAR, $descending = false)
+    {
+        foreach ($array as &$value) {
+            if (is_array($value)) {
+                $value = static::sortRecursive($value, $options, $descending);
+            }
+        }
+
+        if (! array_is_list($array)) {
+            $descending
+                    ? krsort($array, $options)
+                    : ksort($array, $options);
+        } else {
+            $descending
+                    ? rsort($array, $options)
+                    : sort($array, $options);
+        }
+
+        return $array;
+    }
+
+    /**
+     * Recursively sort an array by keys and values in descending order.
+     *
+     * @param  array  $array
+     * @param  int  $options
+     * @return array
+     */
+    public static function sortRecursiveDesc($array, $options = SORT_REGULAR)
+    {
+        return static::sortRecursive($array, $options, true);
+    }
+
+    /**
+     * Conditionally compile classes from an array into a CSS class list.
+     *
+     * @param  array  $array
+     * @return string
+     */
+    public static function toCssClasses($array)
+    {
+        $classList = static::wrap($array);
+
+        $classes = [];
+
+        foreach ($classList as $class => $constraint) {
+            if (is_numeric($class)) {
+                $classes[] = $constraint;
+            } elseif ($constraint) {
+                $classes[] = $class;
+            }
+        }
+
+        return implode(' ', $classes);
+    }
+
+    /**
+     * Conditionally compile styles from an array into a style list.
+     *
+     * @param  array  $array
+     * @return string
+     */
+    public static function toCssStyles($array)
+    {
+        $styleList = static::wrap($array);
+
+        $styles = [];
+
+        foreach ($styleList as $class => $constraint) {
+            if (is_numeric($class)) {
+                $styles[] = Str::finish($constraint, ';');
+            } elseif ($constraint) {
+                $styles[] = Str::finish($class, ';');
+            }
+        }
+
+        return implode(' ', $styles);
+    }
+
+    /**
+     * Filter the array using the given callback.
+     *
+     * @param  array  $array
+     * @param  callable  $callback
+     * @return array
+     */
+    public static function where($array, callable $callback)
+    {
+        return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH);
+    }
+
+    /**
+     * Filter items where the value is not null.
+     *
+     * @param  array  $array
+     * @return array
+     */
+    public static function whereNotNull($array)
+    {
+        return static::where($array, fn ($value) => ! is_null($value));
+    }
+
+    /**
+     * If the given value is not an array and not null, wrap it in one.
+     *
+     * @param  mixed  $value
+     * @return array
+     */
+    public static function wrap($value)
+    {
+        if (is_null($value)) {
+            return [];
+        }
+
+        return is_array($value) ? $value : [$value];
+    }
+}

+ 1821 - 0
vendor/illuminate/collections/Collection.php

@@ -0,0 +1,1821 @@
+<?php
+
+namespace Illuminate\Support;
+
+use ArrayAccess;
+use ArrayIterator;
+use Illuminate\Contracts\Support\CanBeEscapedWhenCastToString;
+use Illuminate\Support\Traits\EnumeratesValues;
+use Illuminate\Support\Traits\Macroable;
+use InvalidArgumentException;
+use stdClass;
+use Traversable;
+
+/**
+ * @template TKey of array-key
+ *
+ * @template-covariant TValue
+ *
+ * @implements \ArrayAccess<TKey, TValue>
+ * @implements \Illuminate\Support\Enumerable<TKey, TValue>
+ */
+class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerable
+{
+    /**
+     * @use \Illuminate\Support\Traits\EnumeratesValues<TKey, TValue>
+     */
+    use EnumeratesValues, Macroable;
+
+    /**
+     * The items contained in the collection.
+     *
+     * @var array<TKey, TValue>
+     */
+    protected $items = [];
+
+    /**
+     * Create a new collection.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>|null  $items
+     * @return void
+     */
+    public function __construct($items = [])
+    {
+        $this->items = $this->getArrayableItems($items);
+    }
+
+    /**
+     * Create a collection with the given range.
+     *
+     * @param  int  $from
+     * @param  int  $to
+     * @return static<int, int>
+     */
+    public static function range($from, $to)
+    {
+        return new static(range($from, $to));
+    }
+
+    /**
+     * Get all of the items in the collection.
+     *
+     * @return array<TKey, TValue>
+     */
+    public function all()
+    {
+        return $this->items;
+    }
+
+    /**
+     * Get a lazy collection for the items in this collection.
+     *
+     * @return \Illuminate\Support\LazyCollection<TKey, TValue>
+     */
+    public function lazy()
+    {
+        return new LazyCollection($this->items);
+    }
+
+    /**
+     * Get the average value of a given key.
+     *
+     * @param  (callable(TValue): float|int)|string|null  $callback
+     * @return float|int|null
+     */
+    public function avg($callback = null)
+    {
+        $callback = $this->valueRetriever($callback);
+
+        $items = $this
+            ->map(fn ($value) => $callback($value))
+            ->filter(fn ($value) => ! is_null($value));
+
+        if ($count = $items->count()) {
+            return $items->sum() / $count;
+        }
+    }
+
+    /**
+     * Get the median of a given key.
+     *
+     * @param  string|array<array-key, string>|null  $key
+     * @return float|int|null
+     */
+    public function median($key = null)
+    {
+        $values = (isset($key) ? $this->pluck($key) : $this)
+            ->filter(fn ($item) => ! is_null($item))
+            ->sort()->values();
+
+        $count = $values->count();
+
+        if ($count === 0) {
+            return;
+        }
+
+        $middle = (int) ($count / 2);
+
+        if ($count % 2) {
+            return $values->get($middle);
+        }
+
+        return (new static([
+            $values->get($middle - 1), $values->get($middle),
+        ]))->average();
+    }
+
+    /**
+     * Get the mode of a given key.
+     *
+     * @param  string|array<array-key, string>|null  $key
+     * @return array<int, float|int>|null
+     */
+    public function mode($key = null)
+    {
+        if ($this->count() === 0) {
+            return;
+        }
+
+        $collection = isset($key) ? $this->pluck($key) : $this;
+
+        $counts = new static;
+
+        $collection->each(fn ($value) => $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1);
+
+        $sorted = $counts->sort();
+
+        $highestValue = $sorted->last();
+
+        return $sorted->filter(fn ($value) => $value == $highestValue)
+            ->sort()->keys()->all();
+    }
+
+    /**
+     * Collapse the collection of items into a single array.
+     *
+     * @return static<int, mixed>
+     */
+    public function collapse()
+    {
+        return new static(Arr::collapse($this->items));
+    }
+
+    /**
+     * Determine if an item exists in the collection.
+     *
+     * @param  (callable(TValue, TKey): bool)|TValue|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function contains($key, $operator = null, $value = null)
+    {
+        if (func_num_args() === 1) {
+            if ($this->useAsCallable($key)) {
+                $placeholder = new stdClass;
+
+                return $this->first($key, $placeholder) !== $placeholder;
+            }
+
+            return in_array($key, $this->items);
+        }
+
+        return $this->contains($this->operatorForWhere(...func_get_args()));
+    }
+
+    /**
+     * Determine if an item exists, using strict comparison.
+     *
+     * @param  (callable(TValue): bool)|TValue|array-key  $key
+     * @param  TValue|null  $value
+     * @return bool
+     */
+    public function containsStrict($key, $value = null)
+    {
+        if (func_num_args() === 2) {
+            return $this->contains(fn ($item) => data_get($item, $key) === $value);
+        }
+
+        if ($this->useAsCallable($key)) {
+            return ! is_null($this->first($key));
+        }
+
+        return in_array($key, $this->items, true);
+    }
+
+    /**
+     * Determine if an item is not contained in the collection.
+     *
+     * @param  mixed  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function doesntContain($key, $operator = null, $value = null)
+    {
+        return ! $this->contains(...func_get_args());
+    }
+
+    /**
+     * Cross join with the given lists, returning all possible permutations.
+     *
+     * @template TCrossJoinKey
+     * @template TCrossJoinValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TCrossJoinKey, TCrossJoinValue>|iterable<TCrossJoinKey, TCrossJoinValue>  ...$lists
+     * @return static<int, array<int, TValue|TCrossJoinValue>>
+     */
+    public function crossJoin(...$lists)
+    {
+        return new static(Arr::crossJoin(
+            $this->items, ...array_map([$this, 'getArrayableItems'], $lists)
+        ));
+    }
+
+    /**
+     * Get the items in the collection that are not present in the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @return static
+     */
+    public function diff($items)
+    {
+        return new static(array_diff($this->items, $this->getArrayableItems($items)));
+    }
+
+    /**
+     * Get the items in the collection that are not present in the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @param  callable(TValue, TValue): int  $callback
+     * @return static
+     */
+    public function diffUsing($items, callable $callback)
+    {
+        return new static(array_udiff($this->items, $this->getArrayableItems($items), $callback));
+    }
+
+    /**
+     * Get the items in the collection whose keys and values are not present in the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function diffAssoc($items)
+    {
+        return new static(array_diff_assoc($this->items, $this->getArrayableItems($items)));
+    }
+
+    /**
+     * Get the items in the collection whose keys and values are not present in the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @param  callable(TKey, TKey): int  $callback
+     * @return static
+     */
+    public function diffAssocUsing($items, callable $callback)
+    {
+        return new static(array_diff_uassoc($this->items, $this->getArrayableItems($items), $callback));
+    }
+
+    /**
+     * Get the items in the collection whose keys are not present in the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function diffKeys($items)
+    {
+        return new static(array_diff_key($this->items, $this->getArrayableItems($items)));
+    }
+
+    /**
+     * Get the items in the collection whose keys are not present in the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @param  callable(TKey, TKey): int  $callback
+     * @return static
+     */
+    public function diffKeysUsing($items, callable $callback)
+    {
+        return new static(array_diff_ukey($this->items, $this->getArrayableItems($items), $callback));
+    }
+
+    /**
+     * Retrieve duplicate items from the collection.
+     *
+     * @param  (callable(TValue): bool)|string|null  $callback
+     * @param  bool  $strict
+     * @return static
+     */
+    public function duplicates($callback = null, $strict = false)
+    {
+        $items = $this->map($this->valueRetriever($callback));
+
+        $uniqueItems = $items->unique(null, $strict);
+
+        $compare = $this->duplicateComparator($strict);
+
+        $duplicates = new static;
+
+        foreach ($items as $key => $value) {
+            if ($uniqueItems->isNotEmpty() && $compare($value, $uniqueItems->first())) {
+                $uniqueItems->shift();
+            } else {
+                $duplicates[$key] = $value;
+            }
+        }
+
+        return $duplicates;
+    }
+
+    /**
+     * Retrieve duplicate items from the collection using strict comparison.
+     *
+     * @param  (callable(TValue): bool)|string|null  $callback
+     * @return static
+     */
+    public function duplicatesStrict($callback = null)
+    {
+        return $this->duplicates($callback, true);
+    }
+
+    /**
+     * Get the comparison function to detect duplicates.
+     *
+     * @param  bool  $strict
+     * @return callable(TValue, TValue): bool
+     */
+    protected function duplicateComparator($strict)
+    {
+        if ($strict) {
+            return fn ($a, $b) => $a === $b;
+        }
+
+        return fn ($a, $b) => $a == $b;
+    }
+
+    /**
+     * Get all items except for those with the specified keys.
+     *
+     * @param  \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>|string  $keys
+     * @return static
+     */
+    public function except($keys)
+    {
+        if (is_null($keys)) {
+            return new static($this->items);
+        }
+
+        if ($keys instanceof Enumerable) {
+            $keys = $keys->all();
+        } elseif (! is_array($keys)) {
+            $keys = func_get_args();
+        }
+
+        return new static(Arr::except($this->items, $keys));
+    }
+
+    /**
+     * Run a filter over each of the items.
+     *
+     * @param  (callable(TValue, TKey): bool)|null  $callback
+     * @return static
+     */
+    public function filter(?callable $callback = null)
+    {
+        if ($callback) {
+            return new static(Arr::where($this->items, $callback));
+        }
+
+        return new static(array_filter($this->items));
+    }
+
+    /**
+     * Get the first item from the collection passing the given truth test.
+     *
+     * @template TFirstDefault
+     *
+     * @param  (callable(TValue, TKey): bool)|null  $callback
+     * @param  TFirstDefault|(\Closure(): TFirstDefault)  $default
+     * @return TValue|TFirstDefault
+     */
+    public function first(?callable $callback = null, $default = null)
+    {
+        return Arr::first($this->items, $callback, $default);
+    }
+
+    /**
+     * Get a flattened array of the items in the collection.
+     *
+     * @param  int  $depth
+     * @return static<int, mixed>
+     */
+    public function flatten($depth = INF)
+    {
+        return new static(Arr::flatten($this->items, $depth));
+    }
+
+    /**
+     * Flip the items in the collection.
+     *
+     * @return static<TValue, TKey>
+     */
+    public function flip()
+    {
+        return new static(array_flip($this->items));
+    }
+
+    /**
+     * Remove an item from the collection by key.
+     *
+     * \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TKey>|TKey  $keys
+     *
+     * @return $this
+     */
+    public function forget($keys)
+    {
+        foreach ($this->getArrayableItems($keys) as $key) {
+            $this->offsetUnset($key);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get an item from the collection by key.
+     *
+     * @template TGetDefault
+     *
+     * @param  TKey  $key
+     * @param  TGetDefault|(\Closure(): TGetDefault)  $default
+     * @return TValue|TGetDefault
+     */
+    public function get($key, $default = null)
+    {
+        if (array_key_exists($key, $this->items)) {
+            return $this->items[$key];
+        }
+
+        return value($default);
+    }
+
+    /**
+     * Get an item from the collection by key or add it to collection if it does not exist.
+     *
+     * @template TGetOrPutValue
+     *
+     * @param  mixed  $key
+     * @param  TGetOrPutValue|(\Closure(): TGetOrPutValue)  $value
+     * @return TValue|TGetOrPutValue
+     */
+    public function getOrPut($key, $value)
+    {
+        if (array_key_exists($key, $this->items)) {
+            return $this->items[$key];
+        }
+
+        $this->offsetSet($key, $value = value($value));
+
+        return $value;
+    }
+
+    /**
+     * Group an associative array by a field or using a callback.
+     *
+     * @param  (callable(TValue, TKey): array-key)|array|string  $groupBy
+     * @param  bool  $preserveKeys
+     * @return static<array-key, static<array-key, TValue>>
+     */
+    public function groupBy($groupBy, $preserveKeys = false)
+    {
+        if (! $this->useAsCallable($groupBy) && is_array($groupBy)) {
+            $nextGroups = $groupBy;
+
+            $groupBy = array_shift($nextGroups);
+        }
+
+        $groupBy = $this->valueRetriever($groupBy);
+
+        $results = [];
+
+        foreach ($this->items as $key => $value) {
+            $groupKeys = $groupBy($value, $key);
+
+            if (! is_array($groupKeys)) {
+                $groupKeys = [$groupKeys];
+            }
+
+            foreach ($groupKeys as $groupKey) {
+                $groupKey = match (true) {
+                    is_bool($groupKey) => (int) $groupKey,
+                    $groupKey instanceof \BackedEnum => $groupKey->value,
+                    $groupKey instanceof \Stringable => (string) $groupKey,
+                    default => $groupKey,
+                };
+
+                if (! array_key_exists($groupKey, $results)) {
+                    $results[$groupKey] = new static;
+                }
+
+                $results[$groupKey]->offsetSet($preserveKeys ? $key : null, $value);
+            }
+        }
+
+        $result = new static($results);
+
+        if (! empty($nextGroups)) {
+            return $result->map->groupBy($nextGroups, $preserveKeys);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Key an associative array by a field or using a callback.
+     *
+     * @param  (callable(TValue, TKey): array-key)|array|string  $keyBy
+     * @return static<array-key, TValue>
+     */
+    public function keyBy($keyBy)
+    {
+        $keyBy = $this->valueRetriever($keyBy);
+
+        $results = [];
+
+        foreach ($this->items as $key => $item) {
+            $resolvedKey = $keyBy($item, $key);
+
+            if (is_object($resolvedKey)) {
+                $resolvedKey = (string) $resolvedKey;
+            }
+
+            $results[$resolvedKey] = $item;
+        }
+
+        return new static($results);
+    }
+
+    /**
+     * Determine if an item exists in the collection by key.
+     *
+     * @param  TKey|array<array-key, TKey>  $key
+     * @return bool
+     */
+    public function has($key)
+    {
+        $keys = is_array($key) ? $key : func_get_args();
+
+        foreach ($keys as $value) {
+            if (! array_key_exists($value, $this->items)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Determine if any of the keys exist in the collection.
+     *
+     * @param  mixed  $key
+     * @return bool
+     */
+    public function hasAny($key)
+    {
+        if ($this->isEmpty()) {
+            return false;
+        }
+
+        $keys = is_array($key) ? $key : func_get_args();
+
+        foreach ($keys as $value) {
+            if ($this->has($value)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Concatenate values of a given key as a string.
+     *
+     * @param  callable|string  $value
+     * @param  string|null  $glue
+     * @return string
+     */
+    public function implode($value, $glue = null)
+    {
+        if ($this->useAsCallable($value)) {
+            return implode($glue ?? '', $this->map($value)->all());
+        }
+
+        $first = $this->first();
+
+        if (is_array($first) || (is_object($first) && ! $first instanceof Stringable)) {
+            return implode($glue ?? '', $this->pluck($value)->all());
+        }
+
+        return implode($value ?? '', $this->items);
+    }
+
+    /**
+     * Intersect the collection with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function intersect($items)
+    {
+        return new static(array_intersect($this->items, $this->getArrayableItems($items)));
+    }
+
+    /**
+     * Intersect the collection with the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @param  callable(TValue, TValue): int  $callback
+     * @return static
+     */
+    public function intersectUsing($items, callable $callback)
+    {
+        return new static(array_uintersect($this->items, $this->getArrayableItems($items), $callback));
+    }
+
+    /**
+     * Intersect the collection with the given items with additional index check.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function intersectAssoc($items)
+    {
+        return new static(array_intersect_assoc($this->items, $this->getArrayableItems($items)));
+    }
+
+    /**
+     * Intersect the collection with the given items with additional index check, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @param  callable(TValue, TValue): int  $callback
+     * @return static
+     */
+    public function intersectAssocUsing($items, callable $callback)
+    {
+        return new static(array_intersect_uassoc($this->items, $this->getArrayableItems($items), $callback));
+    }
+
+    /**
+     * Intersect the collection with the given items by key.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function intersectByKeys($items)
+    {
+        return new static(array_intersect_key(
+            $this->items, $this->getArrayableItems($items)
+        ));
+    }
+
+    /**
+     * Determine if the collection is empty or not.
+     *
+     * @return bool
+     */
+    public function isEmpty()
+    {
+        return empty($this->items);
+    }
+
+    /**
+     * Determine if the collection contains a single item.
+     *
+     * @return bool
+     */
+    public function containsOneItem()
+    {
+        return $this->count() === 1;
+    }
+
+    /**
+     * Join all items from the collection using a string. The final items can use a separate glue string.
+     *
+     * @param  string  $glue
+     * @param  string  $finalGlue
+     * @return string
+     */
+    public function join($glue, $finalGlue = '')
+    {
+        if ($finalGlue === '') {
+            return $this->implode($glue);
+        }
+
+        $count = $this->count();
+
+        if ($count === 0) {
+            return '';
+        }
+
+        if ($count === 1) {
+            return $this->last();
+        }
+
+        $collection = new static($this->items);
+
+        $finalItem = $collection->pop();
+
+        return $collection->implode($glue).$finalGlue.$finalItem;
+    }
+
+    /**
+     * Get the keys of the collection items.
+     *
+     * @return static<int, TKey>
+     */
+    public function keys()
+    {
+        return new static(array_keys($this->items));
+    }
+
+    /**
+     * Get the last item from the collection.
+     *
+     * @template TLastDefault
+     *
+     * @param  (callable(TValue, TKey): bool)|null  $callback
+     * @param  TLastDefault|(\Closure(): TLastDefault)  $default
+     * @return TValue|TLastDefault
+     */
+    public function last(?callable $callback = null, $default = null)
+    {
+        return Arr::last($this->items, $callback, $default);
+    }
+
+    /**
+     * Get the values of a given key.
+     *
+     * @param  string|int|array<array-key, string>  $value
+     * @param  string|null  $key
+     * @return static<array-key, mixed>
+     */
+    public function pluck($value, $key = null)
+    {
+        return new static(Arr::pluck($this->items, $value, $key));
+    }
+
+    /**
+     * Run a map over each of the items.
+     *
+     * @template TMapValue
+     *
+     * @param  callable(TValue, TKey): TMapValue  $callback
+     * @return static<TKey, TMapValue>
+     */
+    public function map(callable $callback)
+    {
+        return new static(Arr::map($this->items, $callback));
+    }
+
+    /**
+     * Run a dictionary map over the items.
+     *
+     * The callback should return an associative array with a single key/value pair.
+     *
+     * @template TMapToDictionaryKey of array-key
+     * @template TMapToDictionaryValue
+     *
+     * @param  callable(TValue, TKey): array<TMapToDictionaryKey, TMapToDictionaryValue>  $callback
+     * @return static<TMapToDictionaryKey, array<int, TMapToDictionaryValue>>
+     */
+    public function mapToDictionary(callable $callback)
+    {
+        $dictionary = [];
+
+        foreach ($this->items as $key => $item) {
+            $pair = $callback($item, $key);
+
+            $key = key($pair);
+
+            $value = reset($pair);
+
+            if (! isset($dictionary[$key])) {
+                $dictionary[$key] = [];
+            }
+
+            $dictionary[$key][] = $value;
+        }
+
+        return new static($dictionary);
+    }
+
+    /**
+     * Run an associative map over each of the items.
+     *
+     * The callback should return an associative array with a single key/value pair.
+     *
+     * @template TMapWithKeysKey of array-key
+     * @template TMapWithKeysValue
+     *
+     * @param  callable(TValue, TKey): array<TMapWithKeysKey, TMapWithKeysValue>  $callback
+     * @return static<TMapWithKeysKey, TMapWithKeysValue>
+     */
+    public function mapWithKeys(callable $callback)
+    {
+        return new static(Arr::mapWithKeys($this->items, $callback));
+    }
+
+    /**
+     * Merge the collection with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function merge($items)
+    {
+        return new static(array_merge($this->items, $this->getArrayableItems($items)));
+    }
+
+    /**
+     * Recursively merge the collection with the given items.
+     *
+     * @template TMergeRecursiveValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TMergeRecursiveValue>|iterable<TKey, TMergeRecursiveValue>  $items
+     * @return static<TKey, TValue|TMergeRecursiveValue>
+     */
+    public function mergeRecursive($items)
+    {
+        return new static(array_merge_recursive($this->items, $this->getArrayableItems($items)));
+    }
+
+    /**
+     * Create a collection by using this collection for keys and another for its values.
+     *
+     * @template TCombineValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TCombineValue>|iterable<array-key, TCombineValue>  $values
+     * @return static<TValue, TCombineValue>
+     */
+    public function combine($values)
+    {
+        return new static(array_combine($this->all(), $this->getArrayableItems($values)));
+    }
+
+    /**
+     * Union the collection with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function union($items)
+    {
+        return new static($this->items + $this->getArrayableItems($items));
+    }
+
+    /**
+     * Create a new collection consisting of every n-th element.
+     *
+     * @param  int  $step
+     * @param  int  $offset
+     * @return static
+     */
+    public function nth($step, $offset = 0)
+    {
+        $new = [];
+
+        $position = 0;
+
+        foreach ($this->slice($offset)->items as $item) {
+            if ($position % $step === 0) {
+                $new[] = $item;
+            }
+
+            $position++;
+        }
+
+        return new static($new);
+    }
+
+    /**
+     * Get the items with the specified keys.
+     *
+     * @param  \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>|string|null  $keys
+     * @return static
+     */
+    public function only($keys)
+    {
+        if (is_null($keys)) {
+            return new static($this->items);
+        }
+
+        if ($keys instanceof Enumerable) {
+            $keys = $keys->all();
+        }
+
+        $keys = is_array($keys) ? $keys : func_get_args();
+
+        return new static(Arr::only($this->items, $keys));
+    }
+
+    /**
+     * Select specific values from the items within the collection.
+     *
+     * @param  \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>|string|null  $keys
+     * @return static
+     */
+    public function select($keys)
+    {
+        if (is_null($keys)) {
+            return new static($this->items);
+        }
+
+        if ($keys instanceof Enumerable) {
+            $keys = $keys->all();
+        }
+
+        $keys = is_array($keys) ? $keys : func_get_args();
+
+        return new static(Arr::select($this->items, $keys));
+    }
+
+    /**
+     * Get and remove the last N items from the collection.
+     *
+     * @param  int  $count
+     * @return static<int, TValue>|TValue|null
+     */
+    public function pop($count = 1)
+    {
+        if ($count === 1) {
+            return array_pop($this->items);
+        }
+
+        if ($this->isEmpty()) {
+            return new static;
+        }
+
+        $results = [];
+
+        $collectionCount = $this->count();
+
+        foreach (range(1, min($count, $collectionCount)) as $item) {
+            array_push($results, array_pop($this->items));
+        }
+
+        return new static($results);
+    }
+
+    /**
+     * Push an item onto the beginning of the collection.
+     *
+     * @param  TValue  $value
+     * @param  TKey  $key
+     * @return $this
+     */
+    public function prepend($value, $key = null)
+    {
+        $this->items = Arr::prepend($this->items, ...func_get_args());
+
+        return $this;
+    }
+
+    /**
+     * Push one or more items onto the end of the collection.
+     *
+     * @param  TValue  ...$values
+     * @return $this
+     */
+    public function push(...$values)
+    {
+        foreach ($values as $value) {
+            $this->items[] = $value;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Push all of the given items onto the collection.
+     *
+     * @template TConcatKey of array-key
+     * @template TConcatValue
+     *
+     * @param  iterable<TConcatKey, TConcatValue>  $source
+     * @return static<TKey|TConcatKey, TValue|TConcatValue>
+     */
+    public function concat($source)
+    {
+        $result = new static($this);
+
+        foreach ($source as $item) {
+            $result->push($item);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Get and remove an item from the collection.
+     *
+     * @template TPullDefault
+     *
+     * @param  TKey  $key
+     * @param  TPullDefault|(\Closure(): TPullDefault)  $default
+     * @return TValue|TPullDefault
+     */
+    public function pull($key, $default = null)
+    {
+        return Arr::pull($this->items, $key, $default);
+    }
+
+    /**
+     * Put an item in the collection by key.
+     *
+     * @param  TKey  $key
+     * @param  TValue  $value
+     * @return $this
+     */
+    public function put($key, $value)
+    {
+        $this->offsetSet($key, $value);
+
+        return $this;
+    }
+
+    /**
+     * Get one or a specified number of items randomly from the collection.
+     *
+     * @param  (callable(self<TKey, TValue>): int)|int|null  $number
+     * @param  bool  $preserveKeys
+     * @return static<int, TValue>|TValue
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function random($number = null, $preserveKeys = false)
+    {
+        if (is_null($number)) {
+            return Arr::random($this->items);
+        }
+
+        if (is_callable($number)) {
+            return new static(Arr::random($this->items, $number($this), $preserveKeys));
+        }
+
+        return new static(Arr::random($this->items, $number, $preserveKeys));
+    }
+
+    /**
+     * Replace the collection items with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function replace($items)
+    {
+        return new static(array_replace($this->items, $this->getArrayableItems($items)));
+    }
+
+    /**
+     * Recursively replace the collection items with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function replaceRecursive($items)
+    {
+        return new static(array_replace_recursive($this->items, $this->getArrayableItems($items)));
+    }
+
+    /**
+     * Reverse items order.
+     *
+     * @return static
+     */
+    public function reverse()
+    {
+        return new static(array_reverse($this->items, true));
+    }
+
+    /**
+     * Search the collection for a given value and return the corresponding key if successful.
+     *
+     * @param  TValue|(callable(TValue,TKey): bool)  $value
+     * @param  bool  $strict
+     * @return TKey|false
+     */
+    public function search($value, $strict = false)
+    {
+        if (! $this->useAsCallable($value)) {
+            return array_search($value, $this->items, $strict);
+        }
+
+        foreach ($this->items as $key => $item) {
+            if ($value($item, $key)) {
+                return $key;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Get and remove the first N items from the collection.
+     *
+     * @param  int  $count
+     * @return static<int, TValue>|TValue|null
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function shift($count = 1)
+    {
+        if ($count < 0) {
+            throw new InvalidArgumentException('Number of shifted items may not be less than zero.');
+        }
+
+        if ($this->isEmpty()) {
+            return null;
+        }
+
+        if ($count === 0) {
+            return new static;
+        }
+
+        if ($count === 1) {
+            return array_shift($this->items);
+        }
+
+        $results = [];
+
+        $collectionCount = $this->count();
+
+        foreach (range(1, min($count, $collectionCount)) as $item) {
+            array_push($results, array_shift($this->items));
+        }
+
+        return new static($results);
+    }
+
+    /**
+     * Shuffle the items in the collection.
+     *
+     * @param  int|null  $seed
+     * @return static
+     */
+    public function shuffle($seed = null)
+    {
+        return new static(Arr::shuffle($this->items, $seed));
+    }
+
+    /**
+     * Create chunks representing a "sliding window" view of the items in the collection.
+     *
+     * @param  int  $size
+     * @param  int  $step
+     * @return static<int, static>
+     */
+    public function sliding($size = 2, $step = 1)
+    {
+        $chunks = floor(($this->count() - $size) / $step) + 1;
+
+        return static::times($chunks, fn ($number) => $this->slice(($number - 1) * $step, $size));
+    }
+
+    /**
+     * Skip the first {$count} items.
+     *
+     * @param  int  $count
+     * @return static
+     */
+    public function skip($count)
+    {
+        return $this->slice($count);
+    }
+
+    /**
+     * Skip items in the collection until the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function skipUntil($value)
+    {
+        return new static($this->lazy()->skipUntil($value)->all());
+    }
+
+    /**
+     * Skip items in the collection while the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function skipWhile($value)
+    {
+        return new static($this->lazy()->skipWhile($value)->all());
+    }
+
+    /**
+     * Slice the underlying collection array.
+     *
+     * @param  int  $offset
+     * @param  int|null  $length
+     * @return static
+     */
+    public function slice($offset, $length = null)
+    {
+        return new static(array_slice($this->items, $offset, $length, true));
+    }
+
+    /**
+     * Split a collection into a certain number of groups.
+     *
+     * @param  int  $numberOfGroups
+     * @return static<int, static>
+     */
+    public function split($numberOfGroups)
+    {
+        if ($this->isEmpty()) {
+            return new static;
+        }
+
+        $groups = new static;
+
+        $groupSize = floor($this->count() / $numberOfGroups);
+
+        $remain = $this->count() % $numberOfGroups;
+
+        $start = 0;
+
+        for ($i = 0; $i < $numberOfGroups; $i++) {
+            $size = $groupSize;
+
+            if ($i < $remain) {
+                $size++;
+            }
+
+            if ($size) {
+                $groups->push(new static(array_slice($this->items, $start, $size)));
+
+                $start += $size;
+            }
+        }
+
+        return $groups;
+    }
+
+    /**
+     * Split a collection into a certain number of groups, and fill the first groups completely.
+     *
+     * @param  int  $numberOfGroups
+     * @return static<int, static>
+     */
+    public function splitIn($numberOfGroups)
+    {
+        return $this->chunk(ceil($this->count() / $numberOfGroups));
+    }
+
+    /**
+     * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.
+     *
+     * @param  (callable(TValue, TKey): bool)|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return TValue
+     *
+     * @throws \Illuminate\Support\ItemNotFoundException
+     * @throws \Illuminate\Support\MultipleItemsFoundException
+     */
+    public function sole($key = null, $operator = null, $value = null)
+    {
+        $filter = func_num_args() > 1
+            ? $this->operatorForWhere(...func_get_args())
+            : $key;
+
+        $items = $this->unless($filter == null)->filter($filter);
+
+        $count = $items->count();
+
+        if ($count === 0) {
+            throw new ItemNotFoundException;
+        }
+
+        if ($count > 1) {
+            throw new MultipleItemsFoundException($count);
+        }
+
+        return $items->first();
+    }
+
+    /**
+     * Get the first item in the collection but throw an exception if no matching items exist.
+     *
+     * @param  (callable(TValue, TKey): bool)|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return TValue
+     *
+     * @throws \Illuminate\Support\ItemNotFoundException
+     */
+    public function firstOrFail($key = null, $operator = null, $value = null)
+    {
+        $filter = func_num_args() > 1
+            ? $this->operatorForWhere(...func_get_args())
+            : $key;
+
+        $placeholder = new stdClass();
+
+        $item = $this->first($filter, $placeholder);
+
+        if ($item === $placeholder) {
+            throw new ItemNotFoundException;
+        }
+
+        return $item;
+    }
+
+    /**
+     * Chunk the collection into chunks of the given size.
+     *
+     * @param  int  $size
+     * @return static<int, static>
+     */
+    public function chunk($size)
+    {
+        if ($size <= 0) {
+            return new static;
+        }
+
+        $chunks = [];
+
+        foreach (array_chunk($this->items, $size, true) as $chunk) {
+            $chunks[] = new static($chunk);
+        }
+
+        return new static($chunks);
+    }
+
+    /**
+     * Chunk the collection into chunks with a callback.
+     *
+     * @param  callable(TValue, TKey, static<int, TValue>): bool  $callback
+     * @return static<int, static<int, TValue>>
+     */
+    public function chunkWhile(callable $callback)
+    {
+        return new static(
+            $this->lazy()->chunkWhile($callback)->mapInto(static::class)
+        );
+    }
+
+    /**
+     * Sort through each item with a callback.
+     *
+     * @param  (callable(TValue, TValue): int)|null|int  $callback
+     * @return static
+     */
+    public function sort($callback = null)
+    {
+        $items = $this->items;
+
+        $callback && is_callable($callback)
+            ? uasort($items, $callback)
+            : asort($items, $callback ?? SORT_REGULAR);
+
+        return new static($items);
+    }
+
+    /**
+     * Sort items in descending order.
+     *
+     * @param  int  $options
+     * @return static
+     */
+    public function sortDesc($options = SORT_REGULAR)
+    {
+        $items = $this->items;
+
+        arsort($items, $options);
+
+        return new static($items);
+    }
+
+    /**
+     * Sort the collection using the given callback.
+     *
+     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback
+     * @param  int  $options
+     * @param  bool  $descending
+     * @return static
+     */
+    public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
+    {
+        if (is_array($callback) && ! is_callable($callback)) {
+            return $this->sortByMany($callback, $options);
+        }
+
+        $results = [];
+
+        $callback = $this->valueRetriever($callback);
+
+        // First we will loop through the items and get the comparator from a callback
+        // function which we were given. Then, we will sort the returned values and
+        // grab all the corresponding values for the sorted keys from this array.
+        foreach ($this->items as $key => $value) {
+            $results[$key] = $callback($value, $key);
+        }
+
+        $descending ? arsort($results, $options)
+            : asort($results, $options);
+
+        // Once we have sorted all of the keys in the array, we will loop through them
+        // and grab the corresponding model so we can set the underlying items list
+        // to the sorted version. Then we'll just return the collection instance.
+        foreach (array_keys($results) as $key) {
+            $results[$key] = $this->items[$key];
+        }
+
+        return new static($results);
+    }
+
+    /**
+     * Sort the collection using multiple comparisons.
+     *
+     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>  $comparisons
+     * @param  int  $options
+     * @return static
+     */
+    protected function sortByMany(array $comparisons = [], int $options = SORT_REGULAR)
+    {
+        $items = $this->items;
+
+        uasort($items, function ($a, $b) use ($comparisons, $options) {
+            foreach ($comparisons as $comparison) {
+                $comparison = Arr::wrap($comparison);
+
+                $prop = $comparison[0];
+
+                $ascending = Arr::get($comparison, 1, true) === true ||
+                             Arr::get($comparison, 1, true) === 'asc';
+
+                if (! is_string($prop) && is_callable($prop)) {
+                    $result = $prop($a, $b);
+                } else {
+                    $values = [data_get($a, $prop), data_get($b, $prop)];
+
+                    if (! $ascending) {
+                        $values = array_reverse($values);
+                    }
+
+                    if (($options & SORT_FLAG_CASE) === SORT_FLAG_CASE) {
+                        if (($options & SORT_NATURAL) === SORT_NATURAL) {
+                            $result = strnatcasecmp($values[0], $values[1]);
+                        } else {
+                            $result = strcasecmp($values[0], $values[1]);
+                        }
+                    } else {
+                        $result = match ($options) {
+                            SORT_NUMERIC => intval($values[0]) <=> intval($values[1]),
+                            SORT_STRING => strcmp($values[0], $values[1]),
+                            SORT_NATURAL => strnatcmp($values[0], $values[1]),
+                            SORT_LOCALE_STRING => strcoll($values[0], $values[1]),
+                            default => $values[0] <=> $values[1],
+                        };
+                    }
+                }
+
+                if ($result === 0) {
+                    continue;
+                }
+
+                return $result;
+            }
+        });
+
+        return new static($items);
+    }
+
+    /**
+     * Sort the collection in descending order using the given callback.
+     *
+     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback
+     * @param  int  $options
+     * @return static
+     */
+    public function sortByDesc($callback, $options = SORT_REGULAR)
+    {
+        if (is_array($callback) && ! is_callable($callback)) {
+            foreach ($callback as $index => $key) {
+                $comparison = Arr::wrap($key);
+
+                $comparison[1] = 'desc';
+
+                $callback[$index] = $comparison;
+            }
+        }
+
+        return $this->sortBy($callback, $options, true);
+    }
+
+    /**
+     * Sort the collection keys.
+     *
+     * @param  int  $options
+     * @param  bool  $descending
+     * @return static
+     */
+    public function sortKeys($options = SORT_REGULAR, $descending = false)
+    {
+        $items = $this->items;
+
+        $descending ? krsort($items, $options) : ksort($items, $options);
+
+        return new static($items);
+    }
+
+    /**
+     * Sort the collection keys in descending order.
+     *
+     * @param  int  $options
+     * @return static
+     */
+    public function sortKeysDesc($options = SORT_REGULAR)
+    {
+        return $this->sortKeys($options, true);
+    }
+
+    /**
+     * Sort the collection keys using a callback.
+     *
+     * @param  callable(TKey, TKey): int  $callback
+     * @return static
+     */
+    public function sortKeysUsing(callable $callback)
+    {
+        $items = $this->items;
+
+        uksort($items, $callback);
+
+        return new static($items);
+    }
+
+    /**
+     * Splice a portion of the underlying collection array.
+     *
+     * @param  int  $offset
+     * @param  int|null  $length
+     * @param  array<array-key, TValue>  $replacement
+     * @return static
+     */
+    public function splice($offset, $length = null, $replacement = [])
+    {
+        if (func_num_args() === 1) {
+            return new static(array_splice($this->items, $offset));
+        }
+
+        return new static(array_splice($this->items, $offset, $length, $this->getArrayableItems($replacement)));
+    }
+
+    /**
+     * Take the first or last {$limit} items.
+     *
+     * @param  int  $limit
+     * @return static
+     */
+    public function take($limit)
+    {
+        if ($limit < 0) {
+            return $this->slice($limit, abs($limit));
+        }
+
+        return $this->slice(0, $limit);
+    }
+
+    /**
+     * Take items in the collection until the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function takeUntil($value)
+    {
+        return new static($this->lazy()->takeUntil($value)->all());
+    }
+
+    /**
+     * Take items in the collection while the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function takeWhile($value)
+    {
+        return new static($this->lazy()->takeWhile($value)->all());
+    }
+
+    /**
+     * Transform each item in the collection using a callback.
+     *
+     * @param  callable(TValue, TKey): TValue  $callback
+     * @return $this
+     */
+    public function transform(callable $callback)
+    {
+        $this->items = $this->map($callback)->all();
+
+        return $this;
+    }
+
+    /**
+     * Flatten a multi-dimensional associative array with dots.
+     *
+     * @return static
+     */
+    public function dot()
+    {
+        return new static(Arr::dot($this->all()));
+    }
+
+    /**
+     * Convert a flatten "dot" notation array into an expanded array.
+     *
+     * @return static
+     */
+    public function undot()
+    {
+        return new static(Arr::undot($this->all()));
+    }
+
+    /**
+     * Return only unique items from the collection array.
+     *
+     * @param  (callable(TValue, TKey): mixed)|string|null  $key
+     * @param  bool  $strict
+     * @return static
+     */
+    public function unique($key = null, $strict = false)
+    {
+        if (is_null($key) && $strict === false) {
+            return new static(array_unique($this->items, SORT_REGULAR));
+        }
+
+        $callback = $this->valueRetriever($key);
+
+        $exists = [];
+
+        return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {
+            if (in_array($id = $callback($item, $key), $exists, $strict)) {
+                return true;
+            }
+
+            $exists[] = $id;
+        });
+    }
+
+    /**
+     * Reset the keys on the underlying array.
+     *
+     * @return static<int, TValue>
+     */
+    public function values()
+    {
+        return new static(array_values($this->items));
+    }
+
+    /**
+     * Zip the collection together with one or more arrays.
+     *
+     * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]);
+     *      => [[1, 4], [2, 5], [3, 6]]
+     *
+     * @template TZipValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TZipValue>|iterable<array-key, TZipValue>  ...$items
+     * @return static<int, static<int, TValue|TZipValue>>
+     */
+    public function zip($items)
+    {
+        $arrayableItems = array_map(fn ($items) => $this->getArrayableItems($items), func_get_args());
+
+        $params = array_merge([fn () => new static(func_get_args()), $this->items], $arrayableItems);
+
+        return new static(array_map(...$params));
+    }
+
+    /**
+     * Pad collection to the specified length with a value.
+     *
+     * @template TPadValue
+     *
+     * @param  int  $size
+     * @param  TPadValue  $value
+     * @return static<int, TValue|TPadValue>
+     */
+    public function pad($size, $value)
+    {
+        return new static(array_pad($this->items, $size, $value));
+    }
+
+    /**
+     * Get an iterator for the items.
+     *
+     * @return \ArrayIterator<TKey, TValue>
+     */
+    public function getIterator(): Traversable
+    {
+        return new ArrayIterator($this->items);
+    }
+
+    /**
+     * Count the number of items in the collection.
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        return count($this->items);
+    }
+
+    /**
+     * Count the number of items in the collection by a field or using a callback.
+     *
+     * @param  (callable(TValue, TKey): array-key)|string|null  $countBy
+     * @return static<array-key, int>
+     */
+    public function countBy($countBy = null)
+    {
+        return new static($this->lazy()->countBy($countBy)->all());
+    }
+
+    /**
+     * Add an item to the collection.
+     *
+     * @param  TValue  $item
+     * @return $this
+     */
+    public function add($item)
+    {
+        $this->items[] = $item;
+
+        return $this;
+    }
+
+    /**
+     * Get a base Support collection instance from this collection.
+     *
+     * @return \Illuminate\Support\Collection<TKey, TValue>
+     */
+    public function toBase()
+    {
+        return new self($this);
+    }
+
+    /**
+     * Determine if an item exists at an offset.
+     *
+     * @param  TKey  $key
+     * @return bool
+     */
+    public function offsetExists($key): bool
+    {
+        return isset($this->items[$key]);
+    }
+
+    /**
+     * Get an item at a given offset.
+     *
+     * @param  TKey  $key
+     * @return TValue
+     */
+    public function offsetGet($key): mixed
+    {
+        return $this->items[$key];
+    }
+
+    /**
+     * Set the item at a given offset.
+     *
+     * @param  TKey|null  $key
+     * @param  TValue  $value
+     * @return void
+     */
+    public function offsetSet($key, $value): void
+    {
+        if (is_null($key)) {
+            $this->items[] = $value;
+        } else {
+            $this->items[$key] = $value;
+        }
+    }
+
+    /**
+     * Unset the item at a given offset.
+     *
+     * @param  TKey  $key
+     * @return void
+     */
+    public function offsetUnset($key): void
+    {
+        unset($this->items[$key]);
+    }
+}

+ 1263 - 0
vendor/illuminate/collections/Enumerable.php

@@ -0,0 +1,1263 @@
+<?php
+
+namespace Illuminate\Support;
+
+use CachingIterator;
+use Countable;
+use Illuminate\Contracts\Support\Arrayable;
+use Illuminate\Contracts\Support\Jsonable;
+use IteratorAggregate;
+use JsonSerializable;
+use Traversable;
+
+/**
+ * @template TKey of array-key
+ *
+ * @template-covariant TValue
+ *
+ * @extends \Illuminate\Contracts\Support\Arrayable<TKey, TValue>
+ * @extends \IteratorAggregate<TKey, TValue>
+ */
+interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable
+{
+    /**
+     * Create a new collection instance if the value isn't one already.
+     *
+     * @template TMakeKey of array-key
+     * @template TMakeValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TMakeKey, TMakeValue>|iterable<TMakeKey, TMakeValue>|null  $items
+     * @return static<TMakeKey, TMakeValue>
+     */
+    public static function make($items = []);
+
+    /**
+     * Create a new instance by invoking the callback a given amount of times.
+     *
+     * @param  int  $number
+     * @param  callable|null  $callback
+     * @return static
+     */
+    public static function times($number, ?callable $callback = null);
+
+    /**
+     * Create a collection with the given range.
+     *
+     * @param  int  $from
+     * @param  int  $to
+     * @return static
+     */
+    public static function range($from, $to);
+
+    /**
+     * Wrap the given value in a collection if applicable.
+     *
+     * @template TWrapValue
+     *
+     * @param  iterable<array-key, TWrapValue>|TWrapValue  $value
+     * @return static<array-key, TWrapValue>
+     */
+    public static function wrap($value);
+
+    /**
+     * Get the underlying items from the given collection if applicable.
+     *
+     * @template TUnwrapKey of array-key
+     * @template TUnwrapValue
+     *
+     * @param  array<TUnwrapKey, TUnwrapValue>|static<TUnwrapKey, TUnwrapValue>  $value
+     * @return array<TUnwrapKey, TUnwrapValue>
+     */
+    public static function unwrap($value);
+
+    /**
+     * Create a new instance with no items.
+     *
+     * @return static
+     */
+    public static function empty();
+
+    /**
+     * Get all items in the enumerable.
+     *
+     * @return array
+     */
+    public function all();
+
+    /**
+     * Alias for the "avg" method.
+     *
+     * @param  (callable(TValue): float|int)|string|null  $callback
+     * @return float|int|null
+     */
+    public function average($callback = null);
+
+    /**
+     * Get the median of a given key.
+     *
+     * @param  string|array<array-key, string>|null  $key
+     * @return float|int|null
+     */
+    public function median($key = null);
+
+    /**
+     * Get the mode of a given key.
+     *
+     * @param  string|array<array-key, string>|null  $key
+     * @return array<int, float|int>|null
+     */
+    public function mode($key = null);
+
+    /**
+     * Collapse the items into a single enumerable.
+     *
+     * @return static<int, mixed>
+     */
+    public function collapse();
+
+    /**
+     * Alias for the "contains" method.
+     *
+     * @param  (callable(TValue, TKey): bool)|TValue|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function some($key, $operator = null, $value = null);
+
+    /**
+     * Determine if an item exists, using strict comparison.
+     *
+     * @param  (callable(TValue): bool)|TValue|array-key  $key
+     * @param  TValue|null  $value
+     * @return bool
+     */
+    public function containsStrict($key, $value = null);
+
+    /**
+     * Get the average value of a given key.
+     *
+     * @param  (callable(TValue): float|int)|string|null  $callback
+     * @return float|int|null
+     */
+    public function avg($callback = null);
+
+    /**
+     * Determine if an item exists in the enumerable.
+     *
+     * @param  (callable(TValue, TKey): bool)|TValue|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function contains($key, $operator = null, $value = null);
+
+    /**
+     * Determine if an item is not contained in the collection.
+     *
+     * @param  mixed  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function doesntContain($key, $operator = null, $value = null);
+
+    /**
+     * Cross join with the given lists, returning all possible permutations.
+     *
+     * @template TCrossJoinKey
+     * @template TCrossJoinValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TCrossJoinKey, TCrossJoinValue>|iterable<TCrossJoinKey, TCrossJoinValue>  ...$lists
+     * @return static<int, array<int, TValue|TCrossJoinValue>>
+     */
+    public function crossJoin(...$lists);
+
+    /**
+     * Dump the collection and end the script.
+     *
+     * @param  mixed  ...$args
+     * @return never
+     */
+    public function dd(...$args);
+
+    /**
+     * Dump the collection.
+     *
+     * @return $this
+     */
+    public function dump();
+
+    /**
+     * Get the items that are not present in the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @return static
+     */
+    public function diff($items);
+
+    /**
+     * Get the items that are not present in the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @param  callable(TValue, TValue): int  $callback
+     * @return static
+     */
+    public function diffUsing($items, callable $callback);
+
+    /**
+     * Get the items whose keys and values are not present in the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function diffAssoc($items);
+
+    /**
+     * Get the items whose keys and values are not present in the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @param  callable(TKey, TKey): int  $callback
+     * @return static
+     */
+    public function diffAssocUsing($items, callable $callback);
+
+    /**
+     * Get the items whose keys are not present in the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function diffKeys($items);
+
+    /**
+     * Get the items whose keys are not present in the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @param  callable(TKey, TKey): int  $callback
+     * @return static
+     */
+    public function diffKeysUsing($items, callable $callback);
+
+    /**
+     * Retrieve duplicate items.
+     *
+     * @param  (callable(TValue): bool)|string|null  $callback
+     * @param  bool  $strict
+     * @return static
+     */
+    public function duplicates($callback = null, $strict = false);
+
+    /**
+     * Retrieve duplicate items using strict comparison.
+     *
+     * @param  (callable(TValue): bool)|string|null  $callback
+     * @return static
+     */
+    public function duplicatesStrict($callback = null);
+
+    /**
+     * Execute a callback over each item.
+     *
+     * @param  callable(TValue, TKey): mixed  $callback
+     * @return $this
+     */
+    public function each(callable $callback);
+
+    /**
+     * Execute a callback over each nested chunk of items.
+     *
+     * @param  callable  $callback
+     * @return static
+     */
+    public function eachSpread(callable $callback);
+
+    /**
+     * Determine if all items pass the given truth test.
+     *
+     * @param  (callable(TValue, TKey): bool)|TValue|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function every($key, $operator = null, $value = null);
+
+    /**
+     * Get all items except for those with the specified keys.
+     *
+     * @param  \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>  $keys
+     * @return static
+     */
+    public function except($keys);
+
+    /**
+     * Run a filter over each of the items.
+     *
+     * @param  (callable(TValue): bool)|null  $callback
+     * @return static
+     */
+    public function filter(?callable $callback = null);
+
+    /**
+     * Apply the callback if the given "value" is (or resolves to) truthy.
+     *
+     * @template TWhenReturnType as null
+     *
+     * @param  bool  $value
+     * @param  (callable($this): TWhenReturnType)|null  $callback
+     * @param  (callable($this): TWhenReturnType)|null  $default
+     * @return $this|TWhenReturnType
+     */
+    public function when($value, ?callable $callback = null, ?callable $default = null);
+
+    /**
+     * Apply the callback if the collection is empty.
+     *
+     * @template TWhenEmptyReturnType
+     *
+     * @param  (callable($this): TWhenEmptyReturnType)  $callback
+     * @param  (callable($this): TWhenEmptyReturnType)|null  $default
+     * @return $this|TWhenEmptyReturnType
+     */
+    public function whenEmpty(callable $callback, ?callable $default = null);
+
+    /**
+     * Apply the callback if the collection is not empty.
+     *
+     * @template TWhenNotEmptyReturnType
+     *
+     * @param  callable($this): TWhenNotEmptyReturnType  $callback
+     * @param  (callable($this): TWhenNotEmptyReturnType)|null  $default
+     * @return $this|TWhenNotEmptyReturnType
+     */
+    public function whenNotEmpty(callable $callback, ?callable $default = null);
+
+    /**
+     * Apply the callback if the given "value" is (or resolves to) truthy.
+     *
+     * @template TUnlessReturnType
+     *
+     * @param  bool  $value
+     * @param  (callable($this): TUnlessReturnType)  $callback
+     * @param  (callable($this): TUnlessReturnType)|null  $default
+     * @return $this|TUnlessReturnType
+     */
+    public function unless($value, callable $callback, ?callable $default = null);
+
+    /**
+     * Apply the callback unless the collection is empty.
+     *
+     * @template TUnlessEmptyReturnType
+     *
+     * @param  callable($this): TUnlessEmptyReturnType  $callback
+     * @param  (callable($this): TUnlessEmptyReturnType)|null  $default
+     * @return $this|TUnlessEmptyReturnType
+     */
+    public function unlessEmpty(callable $callback, ?callable $default = null);
+
+    /**
+     * Apply the callback unless the collection is not empty.
+     *
+     * @template TUnlessNotEmptyReturnType
+     *
+     * @param  callable($this): TUnlessNotEmptyReturnType  $callback
+     * @param  (callable($this): TUnlessNotEmptyReturnType)|null  $default
+     * @return $this|TUnlessNotEmptyReturnType
+     */
+    public function unlessNotEmpty(callable $callback, ?callable $default = null);
+
+    /**
+     * Filter items by the given key value pair.
+     *
+     * @param  string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return static
+     */
+    public function where($key, $operator = null, $value = null);
+
+    /**
+     * Filter items where the value for the given key is null.
+     *
+     * @param  string|null  $key
+     * @return static
+     */
+    public function whereNull($key = null);
+
+    /**
+     * Filter items where the value for the given key is not null.
+     *
+     * @param  string|null  $key
+     * @return static
+     */
+    public function whereNotNull($key = null);
+
+    /**
+     * Filter items by the given key value pair using strict comparison.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return static
+     */
+    public function whereStrict($key, $value);
+
+    /**
+     * Filter items by the given key value pair.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @param  bool  $strict
+     * @return static
+     */
+    public function whereIn($key, $values, $strict = false);
+
+    /**
+     * Filter items by the given key value pair using strict comparison.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @return static
+     */
+    public function whereInStrict($key, $values);
+
+    /**
+     * Filter items such that the value of the given key is between the given values.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @return static
+     */
+    public function whereBetween($key, $values);
+
+    /**
+     * Filter items such that the value of the given key is not between the given values.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @return static
+     */
+    public function whereNotBetween($key, $values);
+
+    /**
+     * Filter items by the given key value pair.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @param  bool  $strict
+     * @return static
+     */
+    public function whereNotIn($key, $values, $strict = false);
+
+    /**
+     * Filter items by the given key value pair using strict comparison.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @return static
+     */
+    public function whereNotInStrict($key, $values);
+
+    /**
+     * Filter the items, removing any items that don't match the given type(s).
+     *
+     * @template TWhereInstanceOf
+     *
+     * @param  class-string<TWhereInstanceOf>|array<array-key, class-string<TWhereInstanceOf>>  $type
+     * @return static<TKey, TWhereInstanceOf>
+     */
+    public function whereInstanceOf($type);
+
+    /**
+     * Get the first item from the enumerable passing the given truth test.
+     *
+     * @template TFirstDefault
+     *
+     * @param  (callable(TValue,TKey): bool)|null  $callback
+     * @param  TFirstDefault|(\Closure(): TFirstDefault)  $default
+     * @return TValue|TFirstDefault
+     */
+    public function first(?callable $callback = null, $default = null);
+
+    /**
+     * Get the first item by the given key value pair.
+     *
+     * @param  string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return TValue|null
+     */
+    public function firstWhere($key, $operator = null, $value = null);
+
+    /**
+     * Get a flattened array of the items in the collection.
+     *
+     * @param  int  $depth
+     * @return static
+     */
+    public function flatten($depth = INF);
+
+    /**
+     * Flip the values with their keys.
+     *
+     * @return static<TValue, TKey>
+     */
+    public function flip();
+
+    /**
+     * Get an item from the collection by key.
+     *
+     * @template TGetDefault
+     *
+     * @param  TKey  $key
+     * @param  TGetDefault|(\Closure(): TGetDefault)  $default
+     * @return TValue|TGetDefault
+     */
+    public function get($key, $default = null);
+
+    /**
+     * Group an associative array by a field or using a callback.
+     *
+     * @param  (callable(TValue, TKey): array-key)|array|string  $groupBy
+     * @param  bool  $preserveKeys
+     * @return static<array-key, static<array-key, TValue>>
+     */
+    public function groupBy($groupBy, $preserveKeys = false);
+
+    /**
+     * Key an associative array by a field or using a callback.
+     *
+     * @param  (callable(TValue, TKey): array-key)|array|string  $keyBy
+     * @return static<array-key, TValue>
+     */
+    public function keyBy($keyBy);
+
+    /**
+     * Determine if an item exists in the collection by key.
+     *
+     * @param  TKey|array<array-key, TKey>  $key
+     * @return bool
+     */
+    public function has($key);
+
+    /**
+     * Determine if any of the keys exist in the collection.
+     *
+     * @param  mixed  $key
+     * @return bool
+     */
+    public function hasAny($key);
+
+    /**
+     * Concatenate values of a given key as a string.
+     *
+     * @param  callable|string  $value
+     * @param  string|null  $glue
+     * @return string
+     */
+    public function implode($value, $glue = null);
+
+    /**
+     * Intersect the collection with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function intersect($items);
+
+    /**
+     * Intersect the collection with the given items by key.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function intersectByKeys($items);
+
+    /**
+     * Determine if the collection is empty or not.
+     *
+     * @return bool
+     */
+    public function isEmpty();
+
+    /**
+     * Determine if the collection is not empty.
+     *
+     * @return bool
+     */
+    public function isNotEmpty();
+
+    /**
+     * Determine if the collection contains a single item.
+     *
+     * @return bool
+     */
+    public function containsOneItem();
+
+    /**
+     * Join all items from the collection using a string. The final items can use a separate glue string.
+     *
+     * @param  string  $glue
+     * @param  string  $finalGlue
+     * @return string
+     */
+    public function join($glue, $finalGlue = '');
+
+    /**
+     * Get the keys of the collection items.
+     *
+     * @return static<int, TKey>
+     */
+    public function keys();
+
+    /**
+     * Get the last item from the collection.
+     *
+     * @template TLastDefault
+     *
+     * @param  (callable(TValue, TKey): bool)|null  $callback
+     * @param  TLastDefault|(\Closure(): TLastDefault)  $default
+     * @return TValue|TLastDefault
+     */
+    public function last(?callable $callback = null, $default = null);
+
+    /**
+     * Run a map over each of the items.
+     *
+     * @template TMapValue
+     *
+     * @param  callable(TValue, TKey): TMapValue  $callback
+     * @return static<TKey, TMapValue>
+     */
+    public function map(callable $callback);
+
+    /**
+     * Run a map over each nested chunk of items.
+     *
+     * @param  callable  $callback
+     * @return static
+     */
+    public function mapSpread(callable $callback);
+
+    /**
+     * Run a dictionary map over the items.
+     *
+     * The callback should return an associative array with a single key/value pair.
+     *
+     * @template TMapToDictionaryKey of array-key
+     * @template TMapToDictionaryValue
+     *
+     * @param  callable(TValue, TKey): array<TMapToDictionaryKey, TMapToDictionaryValue>  $callback
+     * @return static<TMapToDictionaryKey, array<int, TMapToDictionaryValue>>
+     */
+    public function mapToDictionary(callable $callback);
+
+    /**
+     * Run a grouping map over the items.
+     *
+     * The callback should return an associative array with a single key/value pair.
+     *
+     * @template TMapToGroupsKey of array-key
+     * @template TMapToGroupsValue
+     *
+     * @param  callable(TValue, TKey): array<TMapToGroupsKey, TMapToGroupsValue>  $callback
+     * @return static<TMapToGroupsKey, static<int, TMapToGroupsValue>>
+     */
+    public function mapToGroups(callable $callback);
+
+    /**
+     * Run an associative map over each of the items.
+     *
+     * The callback should return an associative array with a single key/value pair.
+     *
+     * @template TMapWithKeysKey of array-key
+     * @template TMapWithKeysValue
+     *
+     * @param  callable(TValue, TKey): array<TMapWithKeysKey, TMapWithKeysValue>  $callback
+     * @return static<TMapWithKeysKey, TMapWithKeysValue>
+     */
+    public function mapWithKeys(callable $callback);
+
+    /**
+     * Map a collection and flatten the result by a single level.
+     *
+     * @template TFlatMapKey of array-key
+     * @template TFlatMapValue
+     *
+     * @param  callable(TValue, TKey): (\Illuminate\Support\Collection<TFlatMapKey, TFlatMapValue>|array<TFlatMapKey, TFlatMapValue>)  $callback
+     * @return static<TFlatMapKey, TFlatMapValue>
+     */
+    public function flatMap(callable $callback);
+
+    /**
+     * Map the values into a new class.
+     *
+     * @template TMapIntoValue
+     *
+     * @param  class-string<TMapIntoValue>  $class
+     * @return static<TKey, TMapIntoValue>
+     */
+    public function mapInto($class);
+
+    /**
+     * Merge the collection with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function merge($items);
+
+    /**
+     * Recursively merge the collection with the given items.
+     *
+     * @template TMergeRecursiveValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TMergeRecursiveValue>|iterable<TKey, TMergeRecursiveValue>  $items
+     * @return static<TKey, TValue|TMergeRecursiveValue>
+     */
+    public function mergeRecursive($items);
+
+    /**
+     * Create a collection by using this collection for keys and another for its values.
+     *
+     * @template TCombineValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TCombineValue>|iterable<array-key, TCombineValue>  $values
+     * @return static<TValue, TCombineValue>
+     */
+    public function combine($values);
+
+    /**
+     * Union the collection with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function union($items);
+
+    /**
+     * Get the min value of a given key.
+     *
+     * @param  (callable(TValue):mixed)|string|null  $callback
+     * @return mixed
+     */
+    public function min($callback = null);
+
+    /**
+     * Get the max value of a given key.
+     *
+     * @param  (callable(TValue):mixed)|string|null  $callback
+     * @return mixed
+     */
+    public function max($callback = null);
+
+    /**
+     * Create a new collection consisting of every n-th element.
+     *
+     * @param  int  $step
+     * @param  int  $offset
+     * @return static
+     */
+    public function nth($step, $offset = 0);
+
+    /**
+     * Get the items with the specified keys.
+     *
+     * @param  \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>|string  $keys
+     * @return static
+     */
+    public function only($keys);
+
+    /**
+     * "Paginate" the collection by slicing it into a smaller collection.
+     *
+     * @param  int  $page
+     * @param  int  $perPage
+     * @return static
+     */
+    public function forPage($page, $perPage);
+
+    /**
+     * Partition the collection into two arrays using the given callback or key.
+     *
+     * @param  (callable(TValue, TKey): bool)|TValue|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return static<int<0, 1>, static<TKey, TValue>>
+     */
+    public function partition($key, $operator = null, $value = null);
+
+    /**
+     * Push all of the given items onto the collection.
+     *
+     * @template TConcatKey of array-key
+     * @template TConcatValue
+     *
+     * @param  iterable<TConcatKey, TConcatValue>  $source
+     * @return static<TKey|TConcatKey, TValue|TConcatValue>
+     */
+    public function concat($source);
+
+    /**
+     * Get one or a specified number of items randomly from the collection.
+     *
+     * @param  int|null  $number
+     * @return static<int, TValue>|TValue
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function random($number = null);
+
+    /**
+     * Reduce the collection to a single value.
+     *
+     * @template TReduceInitial
+     * @template TReduceReturnType
+     *
+     * @param  callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType  $callback
+     * @param  TReduceInitial  $initial
+     * @return TReduceReturnType
+     */
+    public function reduce(callable $callback, $initial = null);
+
+    /**
+     * Reduce the collection to multiple aggregate values.
+     *
+     * @param  callable  $callback
+     * @param  mixed  ...$initial
+     * @return array
+     *
+     * @throws \UnexpectedValueException
+     */
+    public function reduceSpread(callable $callback, ...$initial);
+
+    /**
+     * Replace the collection items with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function replace($items);
+
+    /**
+     * Recursively replace the collection items with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function replaceRecursive($items);
+
+    /**
+     * Reverse items order.
+     *
+     * @return static
+     */
+    public function reverse();
+
+    /**
+     * Search the collection for a given value and return the corresponding key if successful.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @param  bool  $strict
+     * @return TKey|bool
+     */
+    public function search($value, $strict = false);
+
+    /**
+     * Shuffle the items in the collection.
+     *
+     * @param  int|null  $seed
+     * @return static
+     */
+    public function shuffle($seed = null);
+
+    /**
+     * Create chunks representing a "sliding window" view of the items in the collection.
+     *
+     * @param  int  $size
+     * @param  int  $step
+     * @return static<int, static>
+     */
+    public function sliding($size = 2, $step = 1);
+
+    /**
+     * Skip the first {$count} items.
+     *
+     * @param  int  $count
+     * @return static
+     */
+    public function skip($count);
+
+    /**
+     * Skip items in the collection until the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function skipUntil($value);
+
+    /**
+     * Skip items in the collection while the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function skipWhile($value);
+
+    /**
+     * Get a slice of items from the enumerable.
+     *
+     * @param  int  $offset
+     * @param  int|null  $length
+     * @return static
+     */
+    public function slice($offset, $length = null);
+
+    /**
+     * Split a collection into a certain number of groups.
+     *
+     * @param  int  $numberOfGroups
+     * @return static<int, static>
+     */
+    public function split($numberOfGroups);
+
+    /**
+     * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.
+     *
+     * @param  (callable(TValue, TKey): bool)|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return TValue
+     *
+     * @throws \Illuminate\Support\ItemNotFoundException
+     * @throws \Illuminate\Support\MultipleItemsFoundException
+     */
+    public function sole($key = null, $operator = null, $value = null);
+
+    /**
+     * Get the first item in the collection but throw an exception if no matching items exist.
+     *
+     * @param  (callable(TValue, TKey): bool)|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return TValue
+     *
+     * @throws \Illuminate\Support\ItemNotFoundException
+     */
+    public function firstOrFail($key = null, $operator = null, $value = null);
+
+    /**
+     * Chunk the collection into chunks of the given size.
+     *
+     * @param  int  $size
+     * @return static<int, static>
+     */
+    public function chunk($size);
+
+    /**
+     * Chunk the collection into chunks with a callback.
+     *
+     * @param  callable(TValue, TKey, static<int, TValue>): bool  $callback
+     * @return static<int, static<int, TValue>>
+     */
+    public function chunkWhile(callable $callback);
+
+    /**
+     * Split a collection into a certain number of groups, and fill the first groups completely.
+     *
+     * @param  int  $numberOfGroups
+     * @return static<int, static>
+     */
+    public function splitIn($numberOfGroups);
+
+    /**
+     * Sort through each item with a callback.
+     *
+     * @param  (callable(TValue, TValue): int)|null|int  $callback
+     * @return static
+     */
+    public function sort($callback = null);
+
+    /**
+     * Sort items in descending order.
+     *
+     * @param  int  $options
+     * @return static
+     */
+    public function sortDesc($options = SORT_REGULAR);
+
+    /**
+     * Sort the collection using the given callback.
+     *
+     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback
+     * @param  int  $options
+     * @param  bool  $descending
+     * @return static
+     */
+    public function sortBy($callback, $options = SORT_REGULAR, $descending = false);
+
+    /**
+     * Sort the collection in descending order using the given callback.
+     *
+     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback
+     * @param  int  $options
+     * @return static
+     */
+    public function sortByDesc($callback, $options = SORT_REGULAR);
+
+    /**
+     * Sort the collection keys.
+     *
+     * @param  int  $options
+     * @param  bool  $descending
+     * @return static
+     */
+    public function sortKeys($options = SORT_REGULAR, $descending = false);
+
+    /**
+     * Sort the collection keys in descending order.
+     *
+     * @param  int  $options
+     * @return static
+     */
+    public function sortKeysDesc($options = SORT_REGULAR);
+
+    /**
+     * Sort the collection keys using a callback.
+     *
+     * @param  callable(TKey, TKey): int  $callback
+     * @return static
+     */
+    public function sortKeysUsing(callable $callback);
+
+    /**
+     * Get the sum of the given values.
+     *
+     * @param  (callable(TValue): mixed)|string|null  $callback
+     * @return mixed
+     */
+    public function sum($callback = null);
+
+    /**
+     * Take the first or last {$limit} items.
+     *
+     * @param  int  $limit
+     * @return static
+     */
+    public function take($limit);
+
+    /**
+     * Take items in the collection until the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function takeUntil($value);
+
+    /**
+     * Take items in the collection while the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function takeWhile($value);
+
+    /**
+     * Pass the collection to the given callback and then return it.
+     *
+     * @param  callable(TValue): mixed  $callback
+     * @return $this
+     */
+    public function tap(callable $callback);
+
+    /**
+     * Pass the enumerable to the given callback and return the result.
+     *
+     * @template TPipeReturnType
+     *
+     * @param  callable($this): TPipeReturnType  $callback
+     * @return TPipeReturnType
+     */
+    public function pipe(callable $callback);
+
+    /**
+     * Pass the collection into a new class.
+     *
+     * @template TPipeIntoValue
+     *
+     * @param  class-string<TPipeIntoValue>  $class
+     * @return TPipeIntoValue
+     */
+    public function pipeInto($class);
+
+    /**
+     * Pass the collection through a series of callable pipes and return the result.
+     *
+     * @param  array<callable>  $pipes
+     * @return mixed
+     */
+    public function pipeThrough($pipes);
+
+    /**
+     * Get the values of a given key.
+     *
+     * @param  string|array<array-key, string>  $value
+     * @param  string|null  $key
+     * @return static<int, mixed>
+     */
+    public function pluck($value, $key = null);
+
+    /**
+     * Create a collection of all elements that do not pass a given truth test.
+     *
+     * @param  (callable(TValue, TKey): bool)|bool|TValue  $callback
+     * @return static
+     */
+    public function reject($callback = true);
+
+    /**
+     * Convert a flatten "dot" notation array into an expanded array.
+     *
+     * @return static
+     */
+    public function undot();
+
+    /**
+     * Return only unique items from the collection array.
+     *
+     * @param  (callable(TValue, TKey): mixed)|string|null  $key
+     * @param  bool  $strict
+     * @return static
+     */
+    public function unique($key = null, $strict = false);
+
+    /**
+     * Return only unique items from the collection array using strict comparison.
+     *
+     * @param  (callable(TValue, TKey): mixed)|string|null  $key
+     * @return static
+     */
+    public function uniqueStrict($key = null);
+
+    /**
+     * Reset the keys on the underlying array.
+     *
+     * @return static<int, TValue>
+     */
+    public function values();
+
+    /**
+     * Pad collection to the specified length with a value.
+     *
+     * @template TPadValue
+     *
+     * @param  int  $size
+     * @param  TPadValue  $value
+     * @return static<int, TValue|TPadValue>
+     */
+    public function pad($size, $value);
+
+    /**
+     * Get the values iterator.
+     *
+     * @return \Traversable<TKey, TValue>
+     */
+    public function getIterator(): Traversable;
+
+    /**
+     * Count the number of items in the collection.
+     *
+     * @return int
+     */
+    public function count(): int;
+
+    /**
+     * Count the number of items in the collection by a field or using a callback.
+     *
+     * @param  (callable(TValue, TKey): array-key)|string|null  $countBy
+     * @return static<array-key, int>
+     */
+    public function countBy($countBy = null);
+
+    /**
+     * Zip the collection together with one or more arrays.
+     *
+     * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]);
+     *      => [[1, 4], [2, 5], [3, 6]]
+     *
+     * @template TZipValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TZipValue>|iterable<array-key, TZipValue>  ...$items
+     * @return static<int, static<int, TValue|TZipValue>>
+     */
+    public function zip($items);
+
+    /**
+     * Collect the values into a collection.
+     *
+     * @return \Illuminate\Support\Collection<TKey, TValue>
+     */
+    public function collect();
+
+    /**
+     * Get the collection of items as a plain array.
+     *
+     * @return array<TKey, mixed>
+     */
+    public function toArray();
+
+    /**
+     * Convert the object into something JSON serializable.
+     *
+     * @return mixed
+     */
+    public function jsonSerialize(): mixed;
+
+    /**
+     * Get the collection of items as JSON.
+     *
+     * @param  int  $options
+     * @return string
+     */
+    public function toJson($options = 0);
+
+    /**
+     * Get a CachingIterator instance.
+     *
+     * @param  int  $flags
+     * @return \CachingIterator
+     */
+    public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING);
+
+    /**
+     * Convert the collection to its string representation.
+     *
+     * @return string
+     */
+    public function __toString();
+
+    /**
+     * Indicate that the model's string representation should be escaped when __toString is invoked.
+     *
+     * @param  bool  $escape
+     * @return $this
+     */
+    public function escapeWhenCastingToString($escape = true);
+
+    /**
+     * Add a method to the list of proxied methods.
+     *
+     * @param  string  $method
+     * @return void
+     */
+    public static function proxy($method);
+
+    /**
+     * Dynamically access collection proxies.
+     *
+     * @param  string  $key
+     * @return mixed
+     *
+     * @throws \Exception
+     */
+    public function __get($key);
+}

+ 63 - 0
vendor/illuminate/collections/HigherOrderCollectionProxy.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace Illuminate\Support;
+
+/**
+ * @mixin \Illuminate\Support\Enumerable
+ */
+class HigherOrderCollectionProxy
+{
+    /**
+     * The collection being operated on.
+     *
+     * @var \Illuminate\Support\Enumerable
+     */
+    protected $collection;
+
+    /**
+     * The method being proxied.
+     *
+     * @var string
+     */
+    protected $method;
+
+    /**
+     * Create a new proxy instance.
+     *
+     * @param  \Illuminate\Support\Enumerable  $collection
+     * @param  string  $method
+     * @return void
+     */
+    public function __construct(Enumerable $collection, $method)
+    {
+        $this->method = $method;
+        $this->collection = $collection;
+    }
+
+    /**
+     * Proxy accessing an attribute onto the collection items.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function __get($key)
+    {
+        return $this->collection->{$this->method}(function ($value) use ($key) {
+            return is_array($value) ? $value[$key] : $value->{$key};
+        });
+    }
+
+    /**
+     * Proxy a method call onto the collection items.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        return $this->collection->{$this->method}(function ($value) use ($method, $parameters) {
+            return $value->{$method}(...$parameters);
+        });
+    }
+}

+ 9 - 0
vendor/illuminate/collections/ItemNotFoundException.php

@@ -0,0 +1,9 @@
+<?php
+
+namespace Illuminate\Support;
+
+use RuntimeException;
+
+class ItemNotFoundException extends RuntimeException
+{
+}

+ 21 - 0
vendor/illuminate/collections/LICENSE.md

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Taylor Otwell
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 1785 - 0
vendor/illuminate/collections/LazyCollection.php

@@ -0,0 +1,1785 @@
+<?php
+
+namespace Illuminate\Support;
+
+use ArrayIterator;
+use Closure;
+use DateTimeInterface;
+use Generator;
+use Illuminate\Contracts\Support\CanBeEscapedWhenCastToString;
+use Illuminate\Support\Traits\EnumeratesValues;
+use Illuminate\Support\Traits\Macroable;
+use InvalidArgumentException;
+use IteratorAggregate;
+use stdClass;
+use Traversable;
+
+/**
+ * @template TKey of array-key
+ *
+ * @template-covariant TValue
+ *
+ * @implements \Illuminate\Support\Enumerable<TKey, TValue>
+ */
+class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
+{
+    /**
+     * @use \Illuminate\Support\Traits\EnumeratesValues<TKey, TValue>
+     */
+    use EnumeratesValues, Macroable;
+
+    /**
+     * The source from which to generate items.
+     *
+     * @var (Closure(): \Generator<TKey, TValue, mixed, void>)|static|array<TKey, TValue>
+     */
+    public $source;
+
+    /**
+     * Create a new lazy collection instance.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>|(Closure(): \Generator<TKey, TValue, mixed, void>)|self<TKey, TValue>|array<TKey, TValue>|null  $source
+     * @return void
+     */
+    public function __construct($source = null)
+    {
+        if ($source instanceof Closure || $source instanceof self) {
+            $this->source = $source;
+        } elseif (is_null($source)) {
+            $this->source = static::empty();
+        } elseif ($source instanceof Generator) {
+            throw new InvalidArgumentException(
+                'Generators should not be passed directly to LazyCollection. Instead, pass a generator function.'
+            );
+        } else {
+            $this->source = $this->getArrayableItems($source);
+        }
+    }
+
+    /**
+     * Create a new collection instance if the value isn't one already.
+     *
+     * @template TMakeKey of array-key
+     * @template TMakeValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TMakeKey, TMakeValue>|iterable<TMakeKey, TMakeValue>|(Closure(): \Generator<TMakeKey, TMakeValue, mixed, void>)|self<TMakeKey, TMakeValue>|array<TMakeKey, TMakeValue>|null  $items
+     * @return static<TMakeKey, TMakeValue>
+     */
+    public static function make($items = [])
+    {
+        return new static($items);
+    }
+
+    /**
+     * Create a collection with the given range.
+     *
+     * @param  int  $from
+     * @param  int  $to
+     * @return static<int, int>
+     */
+    public static function range($from, $to)
+    {
+        return new static(function () use ($from, $to) {
+            if ($from <= $to) {
+                for (; $from <= $to; $from++) {
+                    yield $from;
+                }
+            } else {
+                for (; $from >= $to; $from--) {
+                    yield $from;
+                }
+            }
+        });
+    }
+
+    /**
+     * Get all items in the enumerable.
+     *
+     * @return array<TKey, TValue>
+     */
+    public function all()
+    {
+        if (is_array($this->source)) {
+            return $this->source;
+        }
+
+        return iterator_to_array($this->getIterator());
+    }
+
+    /**
+     * Eager load all items into a new lazy collection backed by an array.
+     *
+     * @return static
+     */
+    public function eager()
+    {
+        return new static($this->all());
+    }
+
+    /**
+     * Cache values as they're enumerated.
+     *
+     * @return static
+     */
+    public function remember()
+    {
+        $iterator = $this->getIterator();
+
+        $iteratorIndex = 0;
+
+        $cache = [];
+
+        return new static(function () use ($iterator, &$iteratorIndex, &$cache) {
+            for ($index = 0; true; $index++) {
+                if (array_key_exists($index, $cache)) {
+                    yield $cache[$index][0] => $cache[$index][1];
+
+                    continue;
+                }
+
+                if ($iteratorIndex < $index) {
+                    $iterator->next();
+
+                    $iteratorIndex++;
+                }
+
+                if (! $iterator->valid()) {
+                    break;
+                }
+
+                $cache[$index] = [$iterator->key(), $iterator->current()];
+
+                yield $cache[$index][0] => $cache[$index][1];
+            }
+        });
+    }
+
+    /**
+     * Get the average value of a given key.
+     *
+     * @param  (callable(TValue): float|int)|string|null  $callback
+     * @return float|int|null
+     */
+    public function avg($callback = null)
+    {
+        return $this->collect()->avg($callback);
+    }
+
+    /**
+     * Get the median of a given key.
+     *
+     * @param  string|array<array-key, string>|null  $key
+     * @return float|int|null
+     */
+    public function median($key = null)
+    {
+        return $this->collect()->median($key);
+    }
+
+    /**
+     * Get the mode of a given key.
+     *
+     * @param  string|array<string>|null  $key
+     * @return array<int, float|int>|null
+     */
+    public function mode($key = null)
+    {
+        return $this->collect()->mode($key);
+    }
+
+    /**
+     * Collapse the collection of items into a single array.
+     *
+     * @return static<int, mixed>
+     */
+    public function collapse()
+    {
+        return new static(function () {
+            foreach ($this as $values) {
+                if (is_array($values) || $values instanceof Enumerable) {
+                    foreach ($values as $value) {
+                        yield $value;
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * Determine if an item exists in the enumerable.
+     *
+     * @param  (callable(TValue, TKey): bool)|TValue|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function contains($key, $operator = null, $value = null)
+    {
+        if (func_num_args() === 1 && $this->useAsCallable($key)) {
+            $placeholder = new stdClass;
+
+            /** @var callable $key */
+            return $this->first($key, $placeholder) !== $placeholder;
+        }
+
+        if (func_num_args() === 1) {
+            $needle = $key;
+
+            foreach ($this as $value) {
+                if ($value == $needle) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        return $this->contains($this->operatorForWhere(...func_get_args()));
+    }
+
+    /**
+     * Determine if an item exists, using strict comparison.
+     *
+     * @param  (callable(TValue): bool)|TValue|array-key  $key
+     * @param  TValue|null  $value
+     * @return bool
+     */
+    public function containsStrict($key, $value = null)
+    {
+        if (func_num_args() === 2) {
+            return $this->contains(fn ($item) => data_get($item, $key) === $value);
+        }
+
+        if ($this->useAsCallable($key)) {
+            return ! is_null($this->first($key));
+        }
+
+        foreach ($this as $item) {
+            if ($item === $key) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Determine if an item is not contained in the enumerable.
+     *
+     * @param  mixed  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function doesntContain($key, $operator = null, $value = null)
+    {
+        return ! $this->contains(...func_get_args());
+    }
+
+    /**
+     * Cross join the given iterables, returning all possible permutations.
+     *
+     * @template TCrossJoinKey
+     * @template TCrossJoinValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TCrossJoinKey, TCrossJoinValue>|iterable<TCrossJoinKey, TCrossJoinValue>  ...$arrays
+     * @return static<int, array<int, TValue|TCrossJoinValue>>
+     */
+    public function crossJoin(...$arrays)
+    {
+        return $this->passthru('crossJoin', func_get_args());
+    }
+
+    /**
+     * Count the number of items in the collection by a field or using a callback.
+     *
+     * @param  (callable(TValue, TKey): array-key)|string|null  $countBy
+     * @return static<array-key, int>
+     */
+    public function countBy($countBy = null)
+    {
+        $countBy = is_null($countBy)
+            ? $this->identity()
+            : $this->valueRetriever($countBy);
+
+        return new static(function () use ($countBy) {
+            $counts = [];
+
+            foreach ($this as $key => $value) {
+                $group = $countBy($value, $key);
+
+                if (empty($counts[$group])) {
+                    $counts[$group] = 0;
+                }
+
+                $counts[$group]++;
+            }
+
+            yield from $counts;
+        });
+    }
+
+    /**
+     * Get the items that are not present in the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @return static
+     */
+    public function diff($items)
+    {
+        return $this->passthru('diff', func_get_args());
+    }
+
+    /**
+     * Get the items that are not present in the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @param  callable(TValue, TValue): int  $callback
+     * @return static
+     */
+    public function diffUsing($items, callable $callback)
+    {
+        return $this->passthru('diffUsing', func_get_args());
+    }
+
+    /**
+     * Get the items whose keys and values are not present in the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function diffAssoc($items)
+    {
+        return $this->passthru('diffAssoc', func_get_args());
+    }
+
+    /**
+     * Get the items whose keys and values are not present in the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @param  callable(TKey, TKey): int  $callback
+     * @return static
+     */
+    public function diffAssocUsing($items, callable $callback)
+    {
+        return $this->passthru('diffAssocUsing', func_get_args());
+    }
+
+    /**
+     * Get the items whose keys are not present in the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function diffKeys($items)
+    {
+        return $this->passthru('diffKeys', func_get_args());
+    }
+
+    /**
+     * Get the items whose keys are not present in the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @param  callable(TKey, TKey): int  $callback
+     * @return static
+     */
+    public function diffKeysUsing($items, callable $callback)
+    {
+        return $this->passthru('diffKeysUsing', func_get_args());
+    }
+
+    /**
+     * Retrieve duplicate items.
+     *
+     * @param  (callable(TValue): bool)|string|null  $callback
+     * @param  bool  $strict
+     * @return static
+     */
+    public function duplicates($callback = null, $strict = false)
+    {
+        return $this->passthru('duplicates', func_get_args());
+    }
+
+    /**
+     * Retrieve duplicate items using strict comparison.
+     *
+     * @param  (callable(TValue): bool)|string|null  $callback
+     * @return static
+     */
+    public function duplicatesStrict($callback = null)
+    {
+        return $this->passthru('duplicatesStrict', func_get_args());
+    }
+
+    /**
+     * Get all items except for those with the specified keys.
+     *
+     * @param  \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>  $keys
+     * @return static
+     */
+    public function except($keys)
+    {
+        return $this->passthru('except', func_get_args());
+    }
+
+    /**
+     * Run a filter over each of the items.
+     *
+     * @param  (callable(TValue, TKey): bool)|null  $callback
+     * @return static
+     */
+    public function filter(?callable $callback = null)
+    {
+        if (is_null($callback)) {
+            $callback = fn ($value) => (bool) $value;
+        }
+
+        return new static(function () use ($callback) {
+            foreach ($this as $key => $value) {
+                if ($callback($value, $key)) {
+                    yield $key => $value;
+                }
+            }
+        });
+    }
+
+    /**
+     * Get the first item from the enumerable passing the given truth test.
+     *
+     * @template TFirstDefault
+     *
+     * @param  (callable(TValue): bool)|null  $callback
+     * @param  TFirstDefault|(\Closure(): TFirstDefault)  $default
+     * @return TValue|TFirstDefault
+     */
+    public function first(?callable $callback = null, $default = null)
+    {
+        $iterator = $this->getIterator();
+
+        if (is_null($callback)) {
+            if (! $iterator->valid()) {
+                return value($default);
+            }
+
+            return $iterator->current();
+        }
+
+        foreach ($iterator as $key => $value) {
+            if ($callback($value, $key)) {
+                return $value;
+            }
+        }
+
+        return value($default);
+    }
+
+    /**
+     * Get a flattened list of the items in the collection.
+     *
+     * @param  int  $depth
+     * @return static<int, mixed>
+     */
+    public function flatten($depth = INF)
+    {
+        $instance = new static(function () use ($depth) {
+            foreach ($this as $item) {
+                if (! is_array($item) && ! $item instanceof Enumerable) {
+                    yield $item;
+                } elseif ($depth === 1) {
+                    yield from $item;
+                } else {
+                    yield from (new static($item))->flatten($depth - 1);
+                }
+            }
+        });
+
+        return $instance->values();
+    }
+
+    /**
+     * Flip the items in the collection.
+     *
+     * @return static<TValue, TKey>
+     */
+    public function flip()
+    {
+        return new static(function () {
+            foreach ($this as $key => $value) {
+                yield $value => $key;
+            }
+        });
+    }
+
+    /**
+     * Get an item by key.
+     *
+     * @template TGetDefault
+     *
+     * @param  TKey|null  $key
+     * @param  TGetDefault|(\Closure(): TGetDefault)  $default
+     * @return TValue|TGetDefault
+     */
+    public function get($key, $default = null)
+    {
+        if (is_null($key)) {
+            return;
+        }
+
+        foreach ($this as $outerKey => $outerValue) {
+            if ($outerKey == $key) {
+                return $outerValue;
+            }
+        }
+
+        return value($default);
+    }
+
+    /**
+     * Group an associative array by a field or using a callback.
+     *
+     * @param  (callable(TValue, TKey): array-key)|array|string  $groupBy
+     * @param  bool  $preserveKeys
+     * @return static<array-key, static<array-key, TValue>>
+     */
+    public function groupBy($groupBy, $preserveKeys = false)
+    {
+        return $this->passthru('groupBy', func_get_args());
+    }
+
+    /**
+     * Key an associative array by a field or using a callback.
+     *
+     * @param  (callable(TValue, TKey): array-key)|array|string  $keyBy
+     * @return static<array-key, TValue>
+     */
+    public function keyBy($keyBy)
+    {
+        return new static(function () use ($keyBy) {
+            $keyBy = $this->valueRetriever($keyBy);
+
+            foreach ($this as $key => $item) {
+                $resolvedKey = $keyBy($item, $key);
+
+                if (is_object($resolvedKey)) {
+                    $resolvedKey = (string) $resolvedKey;
+                }
+
+                yield $resolvedKey => $item;
+            }
+        });
+    }
+
+    /**
+     * Determine if an item exists in the collection by key.
+     *
+     * @param  mixed  $key
+     * @return bool
+     */
+    public function has($key)
+    {
+        $keys = array_flip(is_array($key) ? $key : func_get_args());
+        $count = count($keys);
+
+        foreach ($this as $key => $value) {
+            if (array_key_exists($key, $keys) && --$count == 0) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Determine if any of the keys exist in the collection.
+     *
+     * @param  mixed  $key
+     * @return bool
+     */
+    public function hasAny($key)
+    {
+        $keys = array_flip(is_array($key) ? $key : func_get_args());
+
+        foreach ($this as $key => $value) {
+            if (array_key_exists($key, $keys)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Concatenate values of a given key as a string.
+     *
+     * @param  callable|string  $value
+     * @param  string|null  $glue
+     * @return string
+     */
+    public function implode($value, $glue = null)
+    {
+        return $this->collect()->implode(...func_get_args());
+    }
+
+    /**
+     * Intersect the collection with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function intersect($items)
+    {
+        return $this->passthru('intersect', func_get_args());
+    }
+
+    /**
+     * Intersect the collection with the given items, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @param  callable(TValue, TValue): int  $callback
+     * @return static
+     */
+    public function intersectUsing()
+    {
+        return $this->passthru('intersectUsing', func_get_args());
+    }
+
+    /**
+     * Intersect the collection with the given items with additional index check.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function intersectAssoc($items)
+    {
+        return $this->passthru('intersectAssoc', func_get_args());
+    }
+
+    /**
+     * Intersect the collection with the given items with additional index check, using the callback.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TValue>|iterable<array-key, TValue>  $items
+     * @param  callable(TValue, TValue): int  $callback
+     * @return static
+     */
+    public function intersectAssocUsing($items, callable $callback)
+    {
+        return $this->passthru('intersectAssocUsing', func_get_args());
+    }
+
+    /**
+     * Intersect the collection with the given items by key.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function intersectByKeys($items)
+    {
+        return $this->passthru('intersectByKeys', func_get_args());
+    }
+
+    /**
+     * Determine if the items are empty or not.
+     *
+     * @return bool
+     */
+    public function isEmpty()
+    {
+        return ! $this->getIterator()->valid();
+    }
+
+    /**
+     * Determine if the collection contains a single item.
+     *
+     * @return bool
+     */
+    public function containsOneItem()
+    {
+        return $this->take(2)->count() === 1;
+    }
+
+    /**
+     * Join all items from the collection using a string. The final items can use a separate glue string.
+     *
+     * @param  string  $glue
+     * @param  string  $finalGlue
+     * @return string
+     */
+    public function join($glue, $finalGlue = '')
+    {
+        return $this->collect()->join(...func_get_args());
+    }
+
+    /**
+     * Get the keys of the collection items.
+     *
+     * @return static<int, TKey>
+     */
+    public function keys()
+    {
+        return new static(function () {
+            foreach ($this as $key => $value) {
+                yield $key;
+            }
+        });
+    }
+
+    /**
+     * Get the last item from the collection.
+     *
+     * @template TLastDefault
+     *
+     * @param  (callable(TValue, TKey): bool)|null  $callback
+     * @param  TLastDefault|(\Closure(): TLastDefault)  $default
+     * @return TValue|TLastDefault
+     */
+    public function last(?callable $callback = null, $default = null)
+    {
+        $needle = $placeholder = new stdClass;
+
+        foreach ($this as $key => $value) {
+            if (is_null($callback) || $callback($value, $key)) {
+                $needle = $value;
+            }
+        }
+
+        return $needle === $placeholder ? value($default) : $needle;
+    }
+
+    /**
+     * Get the values of a given key.
+     *
+     * @param  string|array<array-key, string>  $value
+     * @param  string|null  $key
+     * @return static<int, mixed>
+     */
+    public function pluck($value, $key = null)
+    {
+        return new static(function () use ($value, $key) {
+            [$value, $key] = $this->explodePluckParameters($value, $key);
+
+            foreach ($this as $item) {
+                $itemValue = data_get($item, $value);
+
+                if (is_null($key)) {
+                    yield $itemValue;
+                } else {
+                    $itemKey = data_get($item, $key);
+
+                    if (is_object($itemKey) && method_exists($itemKey, '__toString')) {
+                        $itemKey = (string) $itemKey;
+                    }
+
+                    yield $itemKey => $itemValue;
+                }
+            }
+        });
+    }
+
+    /**
+     * Run a map over each of the items.
+     *
+     * @template TMapValue
+     *
+     * @param  callable(TValue, TKey): TMapValue  $callback
+     * @return static<TKey, TMapValue>
+     */
+    public function map(callable $callback)
+    {
+        return new static(function () use ($callback) {
+            foreach ($this as $key => $value) {
+                yield $key => $callback($value, $key);
+            }
+        });
+    }
+
+    /**
+     * Run a dictionary map over the items.
+     *
+     * The callback should return an associative array with a single key/value pair.
+     *
+     * @template TMapToDictionaryKey of array-key
+     * @template TMapToDictionaryValue
+     *
+     * @param  callable(TValue, TKey): array<TMapToDictionaryKey, TMapToDictionaryValue>  $callback
+     * @return static<TMapToDictionaryKey, array<int, TMapToDictionaryValue>>
+     */
+    public function mapToDictionary(callable $callback)
+    {
+        return $this->passthru('mapToDictionary', func_get_args());
+    }
+
+    /**
+     * Run an associative map over each of the items.
+     *
+     * The callback should return an associative array with a single key/value pair.
+     *
+     * @template TMapWithKeysKey of array-key
+     * @template TMapWithKeysValue
+     *
+     * @param  callable(TValue, TKey): array<TMapWithKeysKey, TMapWithKeysValue>  $callback
+     * @return static<TMapWithKeysKey, TMapWithKeysValue>
+     */
+    public function mapWithKeys(callable $callback)
+    {
+        return new static(function () use ($callback) {
+            foreach ($this as $key => $value) {
+                yield from $callback($value, $key);
+            }
+        });
+    }
+
+    /**
+     * Merge the collection with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function merge($items)
+    {
+        return $this->passthru('merge', func_get_args());
+    }
+
+    /**
+     * Recursively merge the collection with the given items.
+     *
+     * @template TMergeRecursiveValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TMergeRecursiveValue>|iterable<TKey, TMergeRecursiveValue>  $items
+     * @return static<TKey, TValue|TMergeRecursiveValue>
+     */
+    public function mergeRecursive($items)
+    {
+        return $this->passthru('mergeRecursive', func_get_args());
+    }
+
+    /**
+     * Create a collection by using this collection for keys and another for its values.
+     *
+     * @template TCombineValue
+     *
+     * @param  \IteratorAggregate<array-key, TCombineValue>|array<array-key, TCombineValue>|(callable(): \Generator<array-key, TCombineValue>)  $values
+     * @return static<TValue, TCombineValue>
+     */
+    public function combine($values)
+    {
+        return new static(function () use ($values) {
+            $values = $this->makeIterator($values);
+
+            $errorMessage = 'Both parameters should have an equal number of elements';
+
+            foreach ($this as $key) {
+                if (! $values->valid()) {
+                    trigger_error($errorMessage, E_USER_WARNING);
+
+                    break;
+                }
+
+                yield $key => $values->current();
+
+                $values->next();
+            }
+
+            if ($values->valid()) {
+                trigger_error($errorMessage, E_USER_WARNING);
+            }
+        });
+    }
+
+    /**
+     * Union the collection with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function union($items)
+    {
+        return $this->passthru('union', func_get_args());
+    }
+
+    /**
+     * Create a new collection consisting of every n-th element.
+     *
+     * @param  int  $step
+     * @param  int  $offset
+     * @return static
+     */
+    public function nth($step, $offset = 0)
+    {
+        return new static(function () use ($step, $offset) {
+            $position = 0;
+
+            foreach ($this->slice($offset) as $item) {
+                if ($position % $step === 0) {
+                    yield $item;
+                }
+
+                $position++;
+            }
+        });
+    }
+
+    /**
+     * Get the items with the specified keys.
+     *
+     * @param  \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>|string  $keys
+     * @return static
+     */
+    public function only($keys)
+    {
+        if ($keys instanceof Enumerable) {
+            $keys = $keys->all();
+        } elseif (! is_null($keys)) {
+            $keys = is_array($keys) ? $keys : func_get_args();
+        }
+
+        return new static(function () use ($keys) {
+            if (is_null($keys)) {
+                yield from $this;
+            } else {
+                $keys = array_flip($keys);
+
+                foreach ($this as $key => $value) {
+                    if (array_key_exists($key, $keys)) {
+                        yield $key => $value;
+
+                        unset($keys[$key]);
+
+                        if (empty($keys)) {
+                            break;
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * Select specific values from the items within the collection.
+     *
+     * @param  \Illuminate\Support\Enumerable<array-key, TKey>|array<array-key, TKey>|string  $keys
+     * @return static
+     */
+    public function select($keys)
+    {
+        if ($keys instanceof Enumerable) {
+            $keys = $keys->all();
+        } elseif (! is_null($keys)) {
+            $keys = is_array($keys) ? $keys : func_get_args();
+        }
+
+        return new static(function () use ($keys) {
+            if (is_null($keys)) {
+                yield from $this;
+            } else {
+                foreach ($this as $item) {
+                    $result = [];
+
+                    foreach ($keys as $key) {
+                        if (Arr::accessible($item) && Arr::exists($item, $key)) {
+                            $result[$key] = $item[$key];
+                        } elseif (is_object($item) && isset($item->{$key})) {
+                            $result[$key] = $item->{$key};
+                        }
+                    }
+
+                    yield $result;
+                }
+            }
+        });
+    }
+
+    /**
+     * Push all of the given items onto the collection.
+     *
+     * @template TConcatKey of array-key
+     * @template TConcatValue
+     *
+     * @param  iterable<TConcatKey, TConcatValue>  $source
+     * @return static<TKey|TConcatKey, TValue|TConcatValue>
+     */
+    public function concat($source)
+    {
+        return (new static(function () use ($source) {
+            yield from $this;
+            yield from $source;
+        }))->values();
+    }
+
+    /**
+     * Get one or a specified number of items randomly from the collection.
+     *
+     * @param  int|null  $number
+     * @return static<int, TValue>|TValue
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function random($number = null)
+    {
+        $result = $this->collect()->random(...func_get_args());
+
+        return is_null($number) ? $result : new static($result);
+    }
+
+    /**
+     * Replace the collection items with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function replace($items)
+    {
+        return new static(function () use ($items) {
+            $items = $this->getArrayableItems($items);
+
+            foreach ($this as $key => $value) {
+                if (array_key_exists($key, $items)) {
+                    yield $key => $items[$key];
+
+                    unset($items[$key]);
+                } else {
+                    yield $key => $value;
+                }
+            }
+
+            foreach ($items as $key => $value) {
+                yield $key => $value;
+            }
+        });
+    }
+
+    /**
+     * Recursively replace the collection items with the given items.
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>  $items
+     * @return static
+     */
+    public function replaceRecursive($items)
+    {
+        return $this->passthru('replaceRecursive', func_get_args());
+    }
+
+    /**
+     * Reverse items order.
+     *
+     * @return static
+     */
+    public function reverse()
+    {
+        return $this->passthru('reverse', func_get_args());
+    }
+
+    /**
+     * Search the collection for a given value and return the corresponding key if successful.
+     *
+     * @param  TValue|(callable(TValue,TKey): bool)  $value
+     * @param  bool  $strict
+     * @return TKey|false
+     */
+    public function search($value, $strict = false)
+    {
+        /** @var (callable(TValue,TKey): bool) $predicate */
+        $predicate = $this->useAsCallable($value)
+            ? $value
+            : function ($item) use ($value, $strict) {
+                return $strict ? $item === $value : $item == $value;
+            };
+
+        foreach ($this as $key => $item) {
+            if ($predicate($item, $key)) {
+                return $key;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Shuffle the items in the collection.
+     *
+     * @param  int|null  $seed
+     * @return static
+     */
+    public function shuffle($seed = null)
+    {
+        return $this->passthru('shuffle', func_get_args());
+    }
+
+    /**
+     * Create chunks representing a "sliding window" view of the items in the collection.
+     *
+     * @param  int  $size
+     * @param  int  $step
+     * @return static<int, static>
+     */
+    public function sliding($size = 2, $step = 1)
+    {
+        return new static(function () use ($size, $step) {
+            $iterator = $this->getIterator();
+
+            $chunk = [];
+
+            while ($iterator->valid()) {
+                $chunk[$iterator->key()] = $iterator->current();
+
+                if (count($chunk) == $size) {
+                    yield (new static($chunk))->tap(function () use (&$chunk, $step) {
+                        $chunk = array_slice($chunk, $step, null, true);
+                    });
+
+                    // If the $step between chunks is bigger than each chunk's $size
+                    // we will skip the extra items (which should never be in any
+                    // chunk) before we continue to the next chunk in the loop.
+                    if ($step > $size) {
+                        $skip = $step - $size;
+
+                        for ($i = 0; $i < $skip && $iterator->valid(); $i++) {
+                            $iterator->next();
+                        }
+                    }
+                }
+
+                $iterator->next();
+            }
+        });
+    }
+
+    /**
+     * Skip the first {$count} items.
+     *
+     * @param  int  $count
+     * @return static
+     */
+    public function skip($count)
+    {
+        return new static(function () use ($count) {
+            $iterator = $this->getIterator();
+
+            while ($iterator->valid() && $count--) {
+                $iterator->next();
+            }
+
+            while ($iterator->valid()) {
+                yield $iterator->key() => $iterator->current();
+
+                $iterator->next();
+            }
+        });
+    }
+
+    /**
+     * Skip items in the collection until the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function skipUntil($value)
+    {
+        $callback = $this->useAsCallable($value) ? $value : $this->equality($value);
+
+        return $this->skipWhile($this->negate($callback));
+    }
+
+    /**
+     * Skip items in the collection while the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function skipWhile($value)
+    {
+        $callback = $this->useAsCallable($value) ? $value : $this->equality($value);
+
+        return new static(function () use ($callback) {
+            $iterator = $this->getIterator();
+
+            while ($iterator->valid() && $callback($iterator->current(), $iterator->key())) {
+                $iterator->next();
+            }
+
+            while ($iterator->valid()) {
+                yield $iterator->key() => $iterator->current();
+
+                $iterator->next();
+            }
+        });
+    }
+
+    /**
+     * Get a slice of items from the enumerable.
+     *
+     * @param  int  $offset
+     * @param  int|null  $length
+     * @return static
+     */
+    public function slice($offset, $length = null)
+    {
+        if ($offset < 0 || $length < 0) {
+            return $this->passthru('slice', func_get_args());
+        }
+
+        $instance = $this->skip($offset);
+
+        return is_null($length) ? $instance : $instance->take($length);
+    }
+
+    /**
+     * Split a collection into a certain number of groups.
+     *
+     * @param  int  $numberOfGroups
+     * @return static<int, static>
+     */
+    public function split($numberOfGroups)
+    {
+        return $this->passthru('split', func_get_args());
+    }
+
+    /**
+     * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.
+     *
+     * @param  (callable(TValue, TKey): bool)|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return TValue
+     *
+     * @throws \Illuminate\Support\ItemNotFoundException
+     * @throws \Illuminate\Support\MultipleItemsFoundException
+     */
+    public function sole($key = null, $operator = null, $value = null)
+    {
+        $filter = func_num_args() > 1
+            ? $this->operatorForWhere(...func_get_args())
+            : $key;
+
+        return $this
+            ->unless($filter == null)
+            ->filter($filter)
+            ->take(2)
+            ->collect()
+            ->sole();
+    }
+
+    /**
+     * Get the first item in the collection but throw an exception if no matching items exist.
+     *
+     * @param  (callable(TValue, TKey): bool)|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return TValue
+     *
+     * @throws \Illuminate\Support\ItemNotFoundException
+     */
+    public function firstOrFail($key = null, $operator = null, $value = null)
+    {
+        $filter = func_num_args() > 1
+            ? $this->operatorForWhere(...func_get_args())
+            : $key;
+
+        return $this
+            ->unless($filter == null)
+            ->filter($filter)
+            ->take(1)
+            ->collect()
+            ->firstOrFail();
+    }
+
+    /**
+     * Chunk the collection into chunks of the given size.
+     *
+     * @param  int  $size
+     * @return static<int, static>
+     */
+    public function chunk($size)
+    {
+        if ($size <= 0) {
+            return static::empty();
+        }
+
+        return new static(function () use ($size) {
+            $iterator = $this->getIterator();
+
+            while ($iterator->valid()) {
+                $chunk = [];
+
+                while (true) {
+                    $chunk[$iterator->key()] = $iterator->current();
+
+                    if (count($chunk) < $size) {
+                        $iterator->next();
+
+                        if (! $iterator->valid()) {
+                            break;
+                        }
+                    } else {
+                        break;
+                    }
+                }
+
+                yield new static($chunk);
+
+                $iterator->next();
+            }
+        });
+    }
+
+    /**
+     * Split a collection into a certain number of groups, and fill the first groups completely.
+     *
+     * @param  int  $numberOfGroups
+     * @return static<int, static>
+     */
+    public function splitIn($numberOfGroups)
+    {
+        return $this->chunk(ceil($this->count() / $numberOfGroups));
+    }
+
+    /**
+     * Chunk the collection into chunks with a callback.
+     *
+     * @param  callable(TValue, TKey, Collection<TKey, TValue>): bool  $callback
+     * @return static<int, static<int, TValue>>
+     */
+    public function chunkWhile(callable $callback)
+    {
+        return new static(function () use ($callback) {
+            $iterator = $this->getIterator();
+
+            $chunk = new Collection;
+
+            if ($iterator->valid()) {
+                $chunk[$iterator->key()] = $iterator->current();
+
+                $iterator->next();
+            }
+
+            while ($iterator->valid()) {
+                if (! $callback($iterator->current(), $iterator->key(), $chunk)) {
+                    yield new static($chunk);
+
+                    $chunk = new Collection;
+                }
+
+                $chunk[$iterator->key()] = $iterator->current();
+
+                $iterator->next();
+            }
+
+            if ($chunk->isNotEmpty()) {
+                yield new static($chunk);
+            }
+        });
+    }
+
+    /**
+     * Sort through each item with a callback.
+     *
+     * @param  (callable(TValue, TValue): int)|null|int  $callback
+     * @return static
+     */
+    public function sort($callback = null)
+    {
+        return $this->passthru('sort', func_get_args());
+    }
+
+    /**
+     * Sort items in descending order.
+     *
+     * @param  int  $options
+     * @return static
+     */
+    public function sortDesc($options = SORT_REGULAR)
+    {
+        return $this->passthru('sortDesc', func_get_args());
+    }
+
+    /**
+     * Sort the collection using the given callback.
+     *
+     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback
+     * @param  int  $options
+     * @param  bool  $descending
+     * @return static
+     */
+    public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
+    {
+        return $this->passthru('sortBy', func_get_args());
+    }
+
+    /**
+     * Sort the collection in descending order using the given callback.
+     *
+     * @param  array<array-key, (callable(TValue, TValue): mixed)|(callable(TValue, TKey): mixed)|string|array{string, string}>|(callable(TValue, TKey): mixed)|string  $callback
+     * @param  int  $options
+     * @return static
+     */
+    public function sortByDesc($callback, $options = SORT_REGULAR)
+    {
+        return $this->passthru('sortByDesc', func_get_args());
+    }
+
+    /**
+     * Sort the collection keys.
+     *
+     * @param  int  $options
+     * @param  bool  $descending
+     * @return static
+     */
+    public function sortKeys($options = SORT_REGULAR, $descending = false)
+    {
+        return $this->passthru('sortKeys', func_get_args());
+    }
+
+    /**
+     * Sort the collection keys in descending order.
+     *
+     * @param  int  $options
+     * @return static
+     */
+    public function sortKeysDesc($options = SORT_REGULAR)
+    {
+        return $this->passthru('sortKeysDesc', func_get_args());
+    }
+
+    /**
+     * Sort the collection keys using a callback.
+     *
+     * @param  callable(TKey, TKey): int  $callback
+     * @return static
+     */
+    public function sortKeysUsing(callable $callback)
+    {
+        return $this->passthru('sortKeysUsing', func_get_args());
+    }
+
+    /**
+     * Take the first or last {$limit} items.
+     *
+     * @param  int  $limit
+     * @return static
+     */
+    public function take($limit)
+    {
+        if ($limit < 0) {
+            return new static(function () use ($limit) {
+                $limit = abs($limit);
+                $ringBuffer = [];
+                $position = 0;
+
+                foreach ($this as $key => $value) {
+                    $ringBuffer[$position] = [$key, $value];
+                    $position = ($position + 1) % $limit;
+                }
+
+                for ($i = 0, $end = min($limit, count($ringBuffer)); $i < $end; $i++) {
+                    $pointer = ($position + $i) % $limit;
+                    yield $ringBuffer[$pointer][0] => $ringBuffer[$pointer][1];
+                }
+            });
+        }
+
+        return new static(function () use ($limit) {
+            $iterator = $this->getIterator();
+
+            while ($limit--) {
+                if (! $iterator->valid()) {
+                    break;
+                }
+
+                yield $iterator->key() => $iterator->current();
+
+                if ($limit) {
+                    $iterator->next();
+                }
+            }
+        });
+    }
+
+    /**
+     * Take items in the collection until the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function takeUntil($value)
+    {
+        /** @var callable(TValue, TKey): bool $callback */
+        $callback = $this->useAsCallable($value) ? $value : $this->equality($value);
+
+        return new static(function () use ($callback) {
+            foreach ($this as $key => $item) {
+                if ($callback($item, $key)) {
+                    break;
+                }
+
+                yield $key => $item;
+            }
+        });
+    }
+
+    /**
+     * Take items in the collection until a given point in time.
+     *
+     * @param  \DateTimeInterface  $timeout
+     * @return static
+     */
+    public function takeUntilTimeout(DateTimeInterface $timeout)
+    {
+        $timeout = $timeout->getTimestamp();
+
+        return new static(function () use ($timeout) {
+            if ($this->now() >= $timeout) {
+                return;
+            }
+
+            foreach ($this as $key => $value) {
+                yield $key => $value;
+
+                if ($this->now() >= $timeout) {
+                    break;
+                }
+            }
+        });
+    }
+
+    /**
+     * Take items in the collection while the given condition is met.
+     *
+     * @param  TValue|callable(TValue,TKey): bool  $value
+     * @return static
+     */
+    public function takeWhile($value)
+    {
+        /** @var callable(TValue, TKey): bool $callback */
+        $callback = $this->useAsCallable($value) ? $value : $this->equality($value);
+
+        return $this->takeUntil(fn ($item, $key) => ! $callback($item, $key));
+    }
+
+    /**
+     * Pass each item in the collection to the given callback, lazily.
+     *
+     * @param  callable(TValue, TKey): mixed  $callback
+     * @return static
+     */
+    public function tapEach(callable $callback)
+    {
+        return new static(function () use ($callback) {
+            foreach ($this as $key => $value) {
+                $callback($value, $key);
+
+                yield $key => $value;
+            }
+        });
+    }
+
+    /**
+     * Flatten a multi-dimensional associative array with dots.
+     *
+     * @return static
+     */
+    public function dot()
+    {
+        return $this->passthru('dot', []);
+    }
+
+    /**
+     * Convert a flatten "dot" notation array into an expanded array.
+     *
+     * @return static
+     */
+    public function undot()
+    {
+        return $this->passthru('undot', []);
+    }
+
+    /**
+     * Return only unique items from the collection array.
+     *
+     * @param  (callable(TValue, TKey): mixed)|string|null  $key
+     * @param  bool  $strict
+     * @return static
+     */
+    public function unique($key = null, $strict = false)
+    {
+        $callback = $this->valueRetriever($key);
+
+        return new static(function () use ($callback, $strict) {
+            $exists = [];
+
+            foreach ($this as $key => $item) {
+                if (! in_array($id = $callback($item, $key), $exists, $strict)) {
+                    yield $key => $item;
+
+                    $exists[] = $id;
+                }
+            }
+        });
+    }
+
+    /**
+     * Reset the keys on the underlying array.
+     *
+     * @return static<int, TValue>
+     */
+    public function values()
+    {
+        return new static(function () {
+            foreach ($this as $item) {
+                yield $item;
+            }
+        });
+    }
+
+    /**
+     * Zip the collection together with one or more arrays.
+     *
+     * e.g. new LazyCollection([1, 2, 3])->zip([4, 5, 6]);
+     *      => [[1, 4], [2, 5], [3, 6]]
+     *
+     * @template TZipValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<array-key, TZipValue>|iterable<array-key, TZipValue>  ...$items
+     * @return static<int, static<int, TValue|TZipValue>>
+     */
+    public function zip($items)
+    {
+        $iterables = func_get_args();
+
+        return new static(function () use ($iterables) {
+            $iterators = Collection::make($iterables)->map(function ($iterable) {
+                return $this->makeIterator($iterable);
+            })->prepend($this->getIterator());
+
+            while ($iterators->contains->valid()) {
+                yield new static($iterators->map->current());
+
+                $iterators->each->next();
+            }
+        });
+    }
+
+    /**
+     * Pad collection to the specified length with a value.
+     *
+     * @template TPadValue
+     *
+     * @param  int  $size
+     * @param  TPadValue  $value
+     * @return static<int, TValue|TPadValue>
+     */
+    public function pad($size, $value)
+    {
+        if ($size < 0) {
+            return $this->passthru('pad', func_get_args());
+        }
+
+        return new static(function () use ($size, $value) {
+            $yielded = 0;
+
+            foreach ($this as $index => $item) {
+                yield $index => $item;
+
+                $yielded++;
+            }
+
+            while ($yielded++ < $size) {
+                yield $value;
+            }
+        });
+    }
+
+    /**
+     * Get the values iterator.
+     *
+     * @return \Traversable<TKey, TValue>
+     */
+    public function getIterator(): Traversable
+    {
+        return $this->makeIterator($this->source);
+    }
+
+    /**
+     * Count the number of items in the collection.
+     *
+     * @return int
+     */
+    public function count(): int
+    {
+        if (is_array($this->source)) {
+            return count($this->source);
+        }
+
+        return iterator_count($this->getIterator());
+    }
+
+    /**
+     * Make an iterator from the given source.
+     *
+     * @template TIteratorKey of array-key
+     * @template TIteratorValue
+     *
+     * @param  \IteratorAggregate<TIteratorKey, TIteratorValue>|array<TIteratorKey, TIteratorValue>|(callable(): \Generator<TIteratorKey, TIteratorValue>)  $source
+     * @return \Traversable<TIteratorKey, TIteratorValue>
+     */
+    protected function makeIterator($source)
+    {
+        if ($source instanceof IteratorAggregate) {
+            return $source->getIterator();
+        }
+
+        if (is_array($source)) {
+            return new ArrayIterator($source);
+        }
+
+        if (is_callable($source)) {
+            $maybeTraversable = $source();
+
+            return $maybeTraversable instanceof Traversable
+                ? $maybeTraversable
+                : new ArrayIterator(Arr::wrap($maybeTraversable));
+        }
+
+        return new ArrayIterator((array) $source);
+    }
+
+    /**
+     * Explode the "value" and "key" arguments passed to "pluck".
+     *
+     * @param  string|string[]  $value
+     * @param  string|string[]|null  $key
+     * @return array{string[],string[]|null}
+     */
+    protected function explodePluckParameters($value, $key)
+    {
+        $value = is_string($value) ? explode('.', $value) : $value;
+
+        $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
+
+        return [$value, $key];
+    }
+
+    /**
+     * Pass this lazy collection through a method on the collection class.
+     *
+     * @param  string  $method
+     * @param  array<mixed>  $params
+     * @return static
+     */
+    protected function passthru($method, array $params)
+    {
+        return new static(function () use ($method, $params) {
+            yield from $this->collect()->$method(...$params);
+        });
+    }
+
+    /**
+     * Get the current time.
+     *
+     * @return int
+     */
+    protected function now()
+    {
+        return class_exists(Carbon::class)
+            ? Carbon::now()->timestamp
+            : time();
+    }
+}

+ 40 - 0
vendor/illuminate/collections/MultipleItemsFoundException.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace Illuminate\Support;
+
+use RuntimeException;
+
+class MultipleItemsFoundException extends RuntimeException
+{
+    /**
+     * The number of items found.
+     *
+     * @var int
+     */
+    public $count;
+
+    /**
+     * Create a new exception instance.
+     *
+     * @param  int  $count
+     * @param  int  $code
+     * @param  \Throwable|null  $previous
+     * @return void
+     */
+    public function __construct($count, $code = 0, $previous = null)
+    {
+        $this->count = $count;
+
+        parent::__construct("$count items were found.", $code, $previous);
+    }
+
+    /**
+     * Get the number of items found.
+     *
+     * @return int
+     */
+    public function getCount()
+    {
+        return $this->count;
+    }
+}

+ 1152 - 0
vendor/illuminate/collections/Traits/EnumeratesValues.php

@@ -0,0 +1,1152 @@
+<?php
+
+namespace Illuminate\Support\Traits;
+
+use CachingIterator;
+use Closure;
+use Exception;
+use Illuminate\Contracts\Support\Arrayable;
+use Illuminate\Contracts\Support\Jsonable;
+use Illuminate\Support\Arr;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Enumerable;
+use Illuminate\Support\HigherOrderCollectionProxy;
+use InvalidArgumentException;
+use JsonSerializable;
+use Symfony\Component\VarDumper\VarDumper;
+use Traversable;
+use UnexpectedValueException;
+use UnitEnum;
+use WeakMap;
+
+/**
+ * @template TKey of array-key
+ *
+ * @template-covariant TValue
+ *
+ * @property-read HigherOrderCollectionProxy $average
+ * @property-read HigherOrderCollectionProxy $avg
+ * @property-read HigherOrderCollectionProxy $contains
+ * @property-read HigherOrderCollectionProxy $doesntContain
+ * @property-read HigherOrderCollectionProxy $each
+ * @property-read HigherOrderCollectionProxy $every
+ * @property-read HigherOrderCollectionProxy $filter
+ * @property-read HigherOrderCollectionProxy $first
+ * @property-read HigherOrderCollectionProxy $flatMap
+ * @property-read HigherOrderCollectionProxy $groupBy
+ * @property-read HigherOrderCollectionProxy $keyBy
+ * @property-read HigherOrderCollectionProxy $map
+ * @property-read HigherOrderCollectionProxy $max
+ * @property-read HigherOrderCollectionProxy $min
+ * @property-read HigherOrderCollectionProxy $partition
+ * @property-read HigherOrderCollectionProxy $percentage
+ * @property-read HigherOrderCollectionProxy $reject
+ * @property-read HigherOrderCollectionProxy $skipUntil
+ * @property-read HigherOrderCollectionProxy $skipWhile
+ * @property-read HigherOrderCollectionProxy $some
+ * @property-read HigherOrderCollectionProxy $sortBy
+ * @property-read HigherOrderCollectionProxy $sortByDesc
+ * @property-read HigherOrderCollectionProxy $sum
+ * @property-read HigherOrderCollectionProxy $takeUntil
+ * @property-read HigherOrderCollectionProxy $takeWhile
+ * @property-read HigherOrderCollectionProxy $unique
+ * @property-read HigherOrderCollectionProxy $unless
+ * @property-read HigherOrderCollectionProxy $until
+ * @property-read HigherOrderCollectionProxy $when
+ */
+trait EnumeratesValues
+{
+    use Conditionable;
+
+    /**
+     * Indicates that the object's string representation should be escaped when __toString is invoked.
+     *
+     * @var bool
+     */
+    protected $escapeWhenCastingToString = false;
+
+    /**
+     * The methods that can be proxied.
+     *
+     * @var array<int, string>
+     */
+    protected static $proxies = [
+        'average',
+        'avg',
+        'contains',
+        'doesntContain',
+        'each',
+        'every',
+        'filter',
+        'first',
+        'flatMap',
+        'groupBy',
+        'keyBy',
+        'map',
+        'max',
+        'min',
+        'partition',
+        'percentage',
+        'reject',
+        'skipUntil',
+        'skipWhile',
+        'some',
+        'sortBy',
+        'sortByDesc',
+        'sum',
+        'takeUntil',
+        'takeWhile',
+        'unique',
+        'unless',
+        'until',
+        'when',
+    ];
+
+    /**
+     * Create a new collection instance if the value isn't one already.
+     *
+     * @template TMakeKey of array-key
+     * @template TMakeValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TMakeKey, TMakeValue>|iterable<TMakeKey, TMakeValue>|null  $items
+     * @return static<TMakeKey, TMakeValue>
+     */
+    public static function make($items = [])
+    {
+        return new static($items);
+    }
+
+    /**
+     * Wrap the given value in a collection if applicable.
+     *
+     * @template TWrapValue
+     *
+     * @param  iterable<array-key, TWrapValue>|TWrapValue  $value
+     * @return static<array-key, TWrapValue>
+     */
+    public static function wrap($value)
+    {
+        return $value instanceof Enumerable
+            ? new static($value)
+            : new static(Arr::wrap($value));
+    }
+
+    /**
+     * Get the underlying items from the given collection if applicable.
+     *
+     * @template TUnwrapKey of array-key
+     * @template TUnwrapValue
+     *
+     * @param  array<TUnwrapKey, TUnwrapValue>|static<TUnwrapKey, TUnwrapValue>  $value
+     * @return array<TUnwrapKey, TUnwrapValue>
+     */
+    public static function unwrap($value)
+    {
+        return $value instanceof Enumerable ? $value->all() : $value;
+    }
+
+    /**
+     * Create a new instance with no items.
+     *
+     * @return static
+     */
+    public static function empty()
+    {
+        return new static([]);
+    }
+
+    /**
+     * Create a new collection by invoking the callback a given amount of times.
+     *
+     * @template TTimesValue
+     *
+     * @param  int  $number
+     * @param  (callable(int): TTimesValue)|null  $callback
+     * @return static<int, TTimesValue>
+     */
+    public static function times($number, ?callable $callback = null)
+    {
+        if ($number < 1) {
+            return new static;
+        }
+
+        return static::range(1, $number)
+            ->unless($callback == null)
+            ->map($callback);
+    }
+
+    /**
+     * Alias for the "avg" method.
+     *
+     * @param  (callable(TValue): float|int)|string|null  $callback
+     * @return float|int|null
+     */
+    public function average($callback = null)
+    {
+        return $this->avg($callback);
+    }
+
+    /**
+     * Alias for the "contains" method.
+     *
+     * @param  (callable(TValue, TKey): bool)|TValue|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function some($key, $operator = null, $value = null)
+    {
+        return $this->contains(...func_get_args());
+    }
+
+    /**
+     * Dump the items and end the script.
+     *
+     * @param  mixed  ...$args
+     * @return never
+     */
+    public function dd(...$args)
+    {
+        $this->dump(...$args);
+
+        exit(1);
+    }
+
+    /**
+     * Dump the items.
+     *
+     * @return $this
+     */
+    public function dump()
+    {
+        (new Collection(func_get_args()))
+            ->push($this->all())
+            ->each(function ($item) {
+                VarDumper::dump($item);
+            });
+
+        return $this;
+    }
+
+    /**
+     * Execute a callback over each item.
+     *
+     * @param  callable(TValue, TKey): mixed  $callback
+     * @return $this
+     */
+    public function each(callable $callback)
+    {
+        foreach ($this as $key => $item) {
+            if ($callback($item, $key) === false) {
+                break;
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Execute a callback over each nested chunk of items.
+     *
+     * @param  callable(...mixed): mixed  $callback
+     * @return static
+     */
+    public function eachSpread(callable $callback)
+    {
+        return $this->each(function ($chunk, $key) use ($callback) {
+            $chunk[] = $key;
+
+            return $callback(...$chunk);
+        });
+    }
+
+    /**
+     * Determine if all items pass the given truth test.
+     *
+     * @param  (callable(TValue, TKey): bool)|TValue|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return bool
+     */
+    public function every($key, $operator = null, $value = null)
+    {
+        if (func_num_args() === 1) {
+            $callback = $this->valueRetriever($key);
+
+            foreach ($this as $k => $v) {
+                if (! $callback($v, $k)) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        return $this->every($this->operatorForWhere(...func_get_args()));
+    }
+
+    /**
+     * Get the first item by the given key value pair.
+     *
+     * @param  callable|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return TValue|null
+     */
+    public function firstWhere($key, $operator = null, $value = null)
+    {
+        return $this->first($this->operatorForWhere(...func_get_args()));
+    }
+
+    /**
+     * Get a single key's value from the first matching item in the collection.
+     *
+     * @template TValueDefault
+     *
+     * @param  string  $key
+     * @param  TValueDefault|(\Closure(): TValueDefault)  $default
+     * @return TValue|TValueDefault
+     */
+    public function value($key, $default = null)
+    {
+        if ($value = $this->firstWhere($key)) {
+            return data_get($value, $key, $default);
+        }
+
+        return value($default);
+    }
+
+    /**
+     * Ensure that every item in the collection is of the expected type.
+     *
+     * @template TEnsureOfType
+     *
+     * @param  class-string<TEnsureOfType>|array<array-key, class-string<TEnsureOfType>>  $type
+     * @return static<TKey, TEnsureOfType>
+     *
+     * @throws \UnexpectedValueException
+     */
+    public function ensure($type)
+    {
+        $allowedTypes = is_array($type) ? $type : [$type];
+
+        return $this->each(function ($item) use ($allowedTypes) {
+            $itemType = get_debug_type($item);
+
+            foreach ($allowedTypes as $allowedType) {
+                if ($itemType === $allowedType || $item instanceof $allowedType) {
+                    return true;
+                }
+            }
+
+            throw new UnexpectedValueException(
+                sprintf("Collection should only include [%s] items, but '%s' found.", implode(', ', $allowedTypes), $itemType)
+            );
+        });
+    }
+
+    /**
+     * Determine if the collection is not empty.
+     *
+     * @return bool
+     */
+    public function isNotEmpty()
+    {
+        return ! $this->isEmpty();
+    }
+
+    /**
+     * Run a map over each nested chunk of items.
+     *
+     * @template TMapSpreadValue
+     *
+     * @param  callable(mixed...): TMapSpreadValue  $callback
+     * @return static<TKey, TMapSpreadValue>
+     */
+    public function mapSpread(callable $callback)
+    {
+        return $this->map(function ($chunk, $key) use ($callback) {
+            $chunk[] = $key;
+
+            return $callback(...$chunk);
+        });
+    }
+
+    /**
+     * Run a grouping map over the items.
+     *
+     * The callback should return an associative array with a single key/value pair.
+     *
+     * @template TMapToGroupsKey of array-key
+     * @template TMapToGroupsValue
+     *
+     * @param  callable(TValue, TKey): array<TMapToGroupsKey, TMapToGroupsValue>  $callback
+     * @return static<TMapToGroupsKey, static<int, TMapToGroupsValue>>
+     */
+    public function mapToGroups(callable $callback)
+    {
+        $groups = $this->mapToDictionary($callback);
+
+        return $groups->map([$this, 'make']);
+    }
+
+    /**
+     * Map a collection and flatten the result by a single level.
+     *
+     * @template TFlatMapKey of array-key
+     * @template TFlatMapValue
+     *
+     * @param  callable(TValue, TKey): (\Illuminate\Support\Collection<TFlatMapKey, TFlatMapValue>|array<TFlatMapKey, TFlatMapValue>)  $callback
+     * @return static<TFlatMapKey, TFlatMapValue>
+     */
+    public function flatMap(callable $callback)
+    {
+        return $this->map($callback)->collapse();
+    }
+
+    /**
+     * Map the values into a new class.
+     *
+     * @template TMapIntoValue
+     *
+     * @param  class-string<TMapIntoValue>  $class
+     * @return static<TKey, TMapIntoValue>
+     */
+    public function mapInto($class)
+    {
+        return $this->map(fn ($value, $key) => new $class($value, $key));
+    }
+
+    /**
+     * Get the min value of a given key.
+     *
+     * @param  (callable(TValue):mixed)|string|null  $callback
+     * @return mixed
+     */
+    public function min($callback = null)
+    {
+        $callback = $this->valueRetriever($callback);
+
+        return $this->map(fn ($value) => $callback($value))
+            ->filter(fn ($value) => ! is_null($value))
+            ->reduce(fn ($result, $value) => is_null($result) || $value < $result ? $value : $result);
+    }
+
+    /**
+     * Get the max value of a given key.
+     *
+     * @param  (callable(TValue):mixed)|string|null  $callback
+     * @return mixed
+     */
+    public function max($callback = null)
+    {
+        $callback = $this->valueRetriever($callback);
+
+        return $this->filter(fn ($value) => ! is_null($value))->reduce(function ($result, $item) use ($callback) {
+            $value = $callback($item);
+
+            return is_null($result) || $value > $result ? $value : $result;
+        });
+    }
+
+    /**
+     * "Paginate" the collection by slicing it into a smaller collection.
+     *
+     * @param  int  $page
+     * @param  int  $perPage
+     * @return static
+     */
+    public function forPage($page, $perPage)
+    {
+        $offset = max(0, ($page - 1) * $perPage);
+
+        return $this->slice($offset, $perPage);
+    }
+
+    /**
+     * Partition the collection into two arrays using the given callback or key.
+     *
+     * @param  (callable(TValue, TKey): bool)|TValue|string  $key
+     * @param  TValue|string|null  $operator
+     * @param  TValue|null  $value
+     * @return static<int<0, 1>, static<TKey, TValue>>
+     */
+    public function partition($key, $operator = null, $value = null)
+    {
+        $passed = [];
+        $failed = [];
+
+        $callback = func_num_args() === 1
+                ? $this->valueRetriever($key)
+                : $this->operatorForWhere(...func_get_args());
+
+        foreach ($this as $key => $item) {
+            if ($callback($item, $key)) {
+                $passed[$key] = $item;
+            } else {
+                $failed[$key] = $item;
+            }
+        }
+
+        return new static([new static($passed), new static($failed)]);
+    }
+
+    /**
+     * Calculate the percentage of items that pass a given truth test.
+     *
+     * @param  (callable(TValue, TKey): bool)  $callback
+     * @param  int  $precision
+     * @return float|null
+     */
+    public function percentage(callable $callback, int $precision = 2)
+    {
+        if ($this->isEmpty()) {
+            return null;
+        }
+
+        return round(
+            $this->filter($callback)->count() / $this->count() * 100,
+            $precision
+        );
+    }
+
+    /**
+     * Get the sum of the given values.
+     *
+     * @param  (callable(TValue): mixed)|string|null  $callback
+     * @return mixed
+     */
+    public function sum($callback = null)
+    {
+        $callback = is_null($callback)
+            ? $this->identity()
+            : $this->valueRetriever($callback);
+
+        return $this->reduce(fn ($result, $item) => $result + $callback($item), 0);
+    }
+
+    /**
+     * Apply the callback if the collection is empty.
+     *
+     * @template TWhenEmptyReturnType
+     *
+     * @param  (callable($this): TWhenEmptyReturnType)  $callback
+     * @param  (callable($this): TWhenEmptyReturnType)|null  $default
+     * @return $this|TWhenEmptyReturnType
+     */
+    public function whenEmpty(callable $callback, ?callable $default = null)
+    {
+        return $this->when($this->isEmpty(), $callback, $default);
+    }
+
+    /**
+     * Apply the callback if the collection is not empty.
+     *
+     * @template TWhenNotEmptyReturnType
+     *
+     * @param  callable($this): TWhenNotEmptyReturnType  $callback
+     * @param  (callable($this): TWhenNotEmptyReturnType)|null  $default
+     * @return $this|TWhenNotEmptyReturnType
+     */
+    public function whenNotEmpty(callable $callback, ?callable $default = null)
+    {
+        return $this->when($this->isNotEmpty(), $callback, $default);
+    }
+
+    /**
+     * Apply the callback unless the collection is empty.
+     *
+     * @template TUnlessEmptyReturnType
+     *
+     * @param  callable($this): TUnlessEmptyReturnType  $callback
+     * @param  (callable($this): TUnlessEmptyReturnType)|null  $default
+     * @return $this|TUnlessEmptyReturnType
+     */
+    public function unlessEmpty(callable $callback, ?callable $default = null)
+    {
+        return $this->whenNotEmpty($callback, $default);
+    }
+
+    /**
+     * Apply the callback unless the collection is not empty.
+     *
+     * @template TUnlessNotEmptyReturnType
+     *
+     * @param  callable($this): TUnlessNotEmptyReturnType  $callback
+     * @param  (callable($this): TUnlessNotEmptyReturnType)|null  $default
+     * @return $this|TUnlessNotEmptyReturnType
+     */
+    public function unlessNotEmpty(callable $callback, ?callable $default = null)
+    {
+        return $this->whenEmpty($callback, $default);
+    }
+
+    /**
+     * Filter items by the given key value pair.
+     *
+     * @param  callable|string  $key
+     * @param  mixed  $operator
+     * @param  mixed  $value
+     * @return static
+     */
+    public function where($key, $operator = null, $value = null)
+    {
+        return $this->filter($this->operatorForWhere(...func_get_args()));
+    }
+
+    /**
+     * Filter items where the value for the given key is null.
+     *
+     * @param  string|null  $key
+     * @return static
+     */
+    public function whereNull($key = null)
+    {
+        return $this->whereStrict($key, null);
+    }
+
+    /**
+     * Filter items where the value for the given key is not null.
+     *
+     * @param  string|null  $key
+     * @return static
+     */
+    public function whereNotNull($key = null)
+    {
+        return $this->where($key, '!==', null);
+    }
+
+    /**
+     * Filter items by the given key value pair using strict comparison.
+     *
+     * @param  string  $key
+     * @param  mixed  $value
+     * @return static
+     */
+    public function whereStrict($key, $value)
+    {
+        return $this->where($key, '===', $value);
+    }
+
+    /**
+     * Filter items by the given key value pair.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @param  bool  $strict
+     * @return static
+     */
+    public function whereIn($key, $values, $strict = false)
+    {
+        $values = $this->getArrayableItems($values);
+
+        return $this->filter(fn ($item) => in_array(data_get($item, $key), $values, $strict));
+    }
+
+    /**
+     * Filter items by the given key value pair using strict comparison.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @return static
+     */
+    public function whereInStrict($key, $values)
+    {
+        return $this->whereIn($key, $values, true);
+    }
+
+    /**
+     * Filter items such that the value of the given key is between the given values.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @return static
+     */
+    public function whereBetween($key, $values)
+    {
+        return $this->where($key, '>=', reset($values))->where($key, '<=', end($values));
+    }
+
+    /**
+     * Filter items such that the value of the given key is not between the given values.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @return static
+     */
+    public function whereNotBetween($key, $values)
+    {
+        return $this->filter(
+            fn ($item) => data_get($item, $key) < reset($values) || data_get($item, $key) > end($values)
+        );
+    }
+
+    /**
+     * Filter items by the given key value pair.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @param  bool  $strict
+     * @return static
+     */
+    public function whereNotIn($key, $values, $strict = false)
+    {
+        $values = $this->getArrayableItems($values);
+
+        return $this->reject(fn ($item) => in_array(data_get($item, $key), $values, $strict));
+    }
+
+    /**
+     * Filter items by the given key value pair using strict comparison.
+     *
+     * @param  string  $key
+     * @param  \Illuminate\Contracts\Support\Arrayable|iterable  $values
+     * @return static
+     */
+    public function whereNotInStrict($key, $values)
+    {
+        return $this->whereNotIn($key, $values, true);
+    }
+
+    /**
+     * Filter the items, removing any items that don't match the given type(s).
+     *
+     * @template TWhereInstanceOf
+     *
+     * @param  class-string<TWhereInstanceOf>|array<array-key, class-string<TWhereInstanceOf>>  $type
+     * @return static<TKey, TWhereInstanceOf>
+     */
+    public function whereInstanceOf($type)
+    {
+        return $this->filter(function ($value) use ($type) {
+            if (is_array($type)) {
+                foreach ($type as $classType) {
+                    if ($value instanceof $classType) {
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+
+            return $value instanceof $type;
+        });
+    }
+
+    /**
+     * Pass the collection to the given callback and return the result.
+     *
+     * @template TPipeReturnType
+     *
+     * @param  callable($this): TPipeReturnType  $callback
+     * @return TPipeReturnType
+     */
+    public function pipe(callable $callback)
+    {
+        return $callback($this);
+    }
+
+    /**
+     * Pass the collection into a new class.
+     *
+     * @template TPipeIntoValue
+     *
+     * @param  class-string<TPipeIntoValue>  $class
+     * @return TPipeIntoValue
+     */
+    public function pipeInto($class)
+    {
+        return new $class($this);
+    }
+
+    /**
+     * Pass the collection through a series of callable pipes and return the result.
+     *
+     * @param  array<callable>  $callbacks
+     * @return mixed
+     */
+    public function pipeThrough($callbacks)
+    {
+        return Collection::make($callbacks)->reduce(
+            fn ($carry, $callback) => $callback($carry),
+            $this,
+        );
+    }
+
+    /**
+     * Reduce the collection to a single value.
+     *
+     * @template TReduceInitial
+     * @template TReduceReturnType
+     *
+     * @param  callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType  $callback
+     * @param  TReduceInitial  $initial
+     * @return TReduceReturnType
+     */
+    public function reduce(callable $callback, $initial = null)
+    {
+        $result = $initial;
+
+        foreach ($this as $key => $value) {
+            $result = $callback($result, $value, $key);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Reduce the collection to multiple aggregate values.
+     *
+     * @param  callable  $callback
+     * @param  mixed  ...$initial
+     * @return array
+     *
+     * @throws \UnexpectedValueException
+     */
+    public function reduceSpread(callable $callback, ...$initial)
+    {
+        $result = $initial;
+
+        foreach ($this as $key => $value) {
+            $result = call_user_func_array($callback, array_merge($result, [$value, $key]));
+
+            if (! is_array($result)) {
+                throw new UnexpectedValueException(sprintf(
+                    "%s::reduceSpread expects reducer to return an array, but got a '%s' instead.",
+                    class_basename(static::class), gettype($result)
+                ));
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Reduce an associative collection to a single value.
+     *
+     * @template TReduceWithKeysInitial
+     * @template TReduceWithKeysReturnType
+     *
+     * @param  callable(TReduceWithKeysInitial|TReduceWithKeysReturnType, TValue, TKey): TReduceWithKeysReturnType  $callback
+     * @param  TReduceWithKeysInitial  $initial
+     * @return TReduceWithKeysReturnType
+     */
+    public function reduceWithKeys(callable $callback, $initial = null)
+    {
+        return $this->reduce($callback, $initial);
+    }
+
+    /**
+     * Create a collection of all elements that do not pass a given truth test.
+     *
+     * @param  (callable(TValue, TKey): bool)|bool|TValue  $callback
+     * @return static
+     */
+    public function reject($callback = true)
+    {
+        $useAsCallable = $this->useAsCallable($callback);
+
+        return $this->filter(function ($value, $key) use ($callback, $useAsCallable) {
+            return $useAsCallable
+                ? ! $callback($value, $key)
+                : $value != $callback;
+        });
+    }
+
+    /**
+     * Pass the collection to the given callback and then return it.
+     *
+     * @param  callable($this): mixed  $callback
+     * @return $this
+     */
+    public function tap(callable $callback)
+    {
+        $callback($this);
+
+        return $this;
+    }
+
+    /**
+     * Return only unique items from the collection array.
+     *
+     * @param  (callable(TValue, TKey): mixed)|string|null  $key
+     * @param  bool  $strict
+     * @return static
+     */
+    public function unique($key = null, $strict = false)
+    {
+        $callback = $this->valueRetriever($key);
+
+        $exists = [];
+
+        return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {
+            if (in_array($id = $callback($item, $key), $exists, $strict)) {
+                return true;
+            }
+
+            $exists[] = $id;
+        });
+    }
+
+    /**
+     * Return only unique items from the collection array using strict comparison.
+     *
+     * @param  (callable(TValue, TKey): mixed)|string|null  $key
+     * @return static
+     */
+    public function uniqueStrict($key = null)
+    {
+        return $this->unique($key, true);
+    }
+
+    /**
+     * Collect the values into a collection.
+     *
+     * @return \Illuminate\Support\Collection<TKey, TValue>
+     */
+    public function collect()
+    {
+        return new Collection($this->all());
+    }
+
+    /**
+     * Get the collection of items as a plain array.
+     *
+     * @return array<TKey, mixed>
+     */
+    public function toArray()
+    {
+        return $this->map(fn ($value) => $value instanceof Arrayable ? $value->toArray() : $value)->all();
+    }
+
+    /**
+     * Convert the object into something JSON serializable.
+     *
+     * @return array<TKey, mixed>
+     */
+    public function jsonSerialize(): array
+    {
+        return array_map(function ($value) {
+            if ($value instanceof JsonSerializable) {
+                return $value->jsonSerialize();
+            } elseif ($value instanceof Jsonable) {
+                return json_decode($value->toJson(), true);
+            } elseif ($value instanceof Arrayable) {
+                return $value->toArray();
+            }
+
+            return $value;
+        }, $this->all());
+    }
+
+    /**
+     * Get the collection of items as JSON.
+     *
+     * @param  int  $options
+     * @return string
+     */
+    public function toJson($options = 0)
+    {
+        return json_encode($this->jsonSerialize(), $options);
+    }
+
+    /**
+     * Get a CachingIterator instance.
+     *
+     * @param  int  $flags
+     * @return \CachingIterator
+     */
+    public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING)
+    {
+        return new CachingIterator($this->getIterator(), $flags);
+    }
+
+    /**
+     * Convert the collection to its string representation.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->escapeWhenCastingToString
+                    ? e($this->toJson())
+                    : $this->toJson();
+    }
+
+    /**
+     * Indicate that the model's string representation should be escaped when __toString is invoked.
+     *
+     * @param  bool  $escape
+     * @return $this
+     */
+    public function escapeWhenCastingToString($escape = true)
+    {
+        $this->escapeWhenCastingToString = $escape;
+
+        return $this;
+    }
+
+    /**
+     * Add a method to the list of proxied methods.
+     *
+     * @param  string  $method
+     * @return void
+     */
+    public static function proxy($method)
+    {
+        static::$proxies[] = $method;
+    }
+
+    /**
+     * Dynamically access collection proxies.
+     *
+     * @param  string  $key
+     * @return mixed
+     *
+     * @throws \Exception
+     */
+    public function __get($key)
+    {
+        if (! in_array($key, static::$proxies)) {
+            throw new Exception("Property [{$key}] does not exist on this collection instance.");
+        }
+
+        return new HigherOrderCollectionProxy($this, $key);
+    }
+
+    /**
+     * Results array of items from Collection or Arrayable.
+     *
+     * @param  mixed  $items
+     * @return array<TKey, TValue>
+     */
+    protected function getArrayableItems($items)
+    {
+        if (is_array($items)) {
+            return $items;
+        }
+
+        return match (true) {
+            $items instanceof WeakMap => throw new InvalidArgumentException('Collections can not be created using instances of WeakMap.'),
+            $items instanceof Enumerable => $items->all(),
+            $items instanceof Arrayable => $items->toArray(),
+            $items instanceof Traversable => iterator_to_array($items),
+            $items instanceof Jsonable => json_decode($items->toJson(), true),
+            $items instanceof JsonSerializable => (array) $items->jsonSerialize(),
+            $items instanceof UnitEnum => [$items],
+            default => (array) $items,
+        };
+    }
+
+    /**
+     * Get an operator checker callback.
+     *
+     * @param  callable|string  $key
+     * @param  string|null  $operator
+     * @param  mixed  $value
+     * @return \Closure
+     */
+    protected function operatorForWhere($key, $operator = null, $value = null)
+    {
+        if ($this->useAsCallable($key)) {
+            return $key;
+        }
+
+        if (func_num_args() === 1) {
+            $value = true;
+
+            $operator = '=';
+        }
+
+        if (func_num_args() === 2) {
+            $value = $operator;
+
+            $operator = '=';
+        }
+
+        return function ($item) use ($key, $operator, $value) {
+            $retrieved = data_get($item, $key);
+
+            $strings = array_filter([$retrieved, $value], function ($value) {
+                return is_string($value) || (is_object($value) && method_exists($value, '__toString'));
+            });
+
+            if (count($strings) < 2 && count(array_filter([$retrieved, $value], 'is_object')) == 1) {
+                return in_array($operator, ['!=', '<>', '!==']);
+            }
+
+            switch ($operator) {
+                default:
+                case '=':
+                case '==':  return $retrieved == $value;
+                case '!=':
+                case '<>':  return $retrieved != $value;
+                case '<':   return $retrieved < $value;
+                case '>':   return $retrieved > $value;
+                case '<=':  return $retrieved <= $value;
+                case '>=':  return $retrieved >= $value;
+                case '===': return $retrieved === $value;
+                case '!==': return $retrieved !== $value;
+                case '<=>': return $retrieved <=> $value;
+            }
+        };
+    }
+
+    /**
+     * Determine if the given value is callable, but not a string.
+     *
+     * @param  mixed  $value
+     * @return bool
+     */
+    protected function useAsCallable($value)
+    {
+        return ! is_string($value) && is_callable($value);
+    }
+
+    /**
+     * Get a value retrieving callback.
+     *
+     * @param  callable|string|null  $value
+     * @return callable
+     */
+    protected function valueRetriever($value)
+    {
+        if ($this->useAsCallable($value)) {
+            return $value;
+        }
+
+        return fn ($item) => data_get($item, $value);
+    }
+
+    /**
+     * Make a function to check an item's equality.
+     *
+     * @param  mixed  $value
+     * @return \Closure(mixed): bool
+     */
+    protected function equality($value)
+    {
+        return fn ($item) => $item === $value;
+    }
+
+    /**
+     * Make a function using another function, by negating its result.
+     *
+     * @param  \Closure  $callback
+     * @return \Closure
+     */
+    protected function negate(Closure $callback)
+    {
+        return fn (...$params) => ! $callback(...$params);
+    }
+
+    /**
+     * Make a function that returns what's passed to it.
+     *
+     * @return \Closure(TValue): TValue
+     */
+    protected function identity()
+    {
+        return fn ($value) => $value;
+    }
+}

+ 42 - 0
vendor/illuminate/collections/composer.json

@@ -0,0 +1,42 @@
+{
+    "name": "illuminate/collections",
+    "description": "The Illuminate Collections package.",
+    "license": "MIT",
+    "homepage": "https://laravel.com",
+    "support": {
+        "issues": "https://github.com/laravel/framework/issues",
+        "source": "https://github.com/laravel/framework"
+    },
+    "authors": [
+        {
+            "name": "Taylor Otwell",
+            "email": "taylor@laravel.com"
+        }
+    ],
+    "require": {
+        "php": "^8.1",
+        "illuminate/conditionable": "^10.0",
+        "illuminate/contracts": "^10.0",
+        "illuminate/macroable": "^10.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Illuminate\\Support\\": ""
+        },
+        "files": [
+            "helpers.php"
+        ]
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "10.x-dev"
+        }
+    },
+    "suggest": {
+        "symfony/var-dumper": "Required to use the dump method (^6.2)."
+    },
+    "config": {
+        "sort-packages": true
+    },
+    "minimum-stability": "dev"
+}

+ 226 - 0
vendor/illuminate/collections/helpers.php

@@ -0,0 +1,226 @@
+<?php
+
+use Illuminate\Support\Arr;
+use Illuminate\Support\Collection;
+
+if (! function_exists('collect')) {
+    /**
+     * Create a collection from the given value.
+     *
+     * @template TKey of array-key
+     * @template TValue
+     *
+     * @param  \Illuminate\Contracts\Support\Arrayable<TKey, TValue>|iterable<TKey, TValue>|null  $value
+     * @return \Illuminate\Support\Collection<TKey, TValue>
+     */
+    function collect($value = [])
+    {
+        return new Collection($value);
+    }
+}
+
+if (! function_exists('data_fill')) {
+    /**
+     * Fill in data where it's missing.
+     *
+     * @param  mixed  $target
+     * @param  string|array  $key
+     * @param  mixed  $value
+     * @return mixed
+     */
+    function data_fill(&$target, $key, $value)
+    {
+        return data_set($target, $key, $value, false);
+    }
+}
+
+if (! function_exists('data_get')) {
+    /**
+     * Get an item from an array or object using "dot" notation.
+     *
+     * @param  mixed  $target
+     * @param  string|array|int|null  $key
+     * @param  mixed  $default
+     * @return mixed
+     */
+    function data_get($target, $key, $default = null)
+    {
+        if (is_null($key)) {
+            return $target;
+        }
+
+        $key = is_array($key) ? $key : explode('.', $key);
+
+        foreach ($key as $i => $segment) {
+            unset($key[$i]);
+
+            if (is_null($segment)) {
+                return $target;
+            }
+
+            if ($segment === '*') {
+                if ($target instanceof Collection) {
+                    $target = $target->all();
+                } elseif (! is_iterable($target)) {
+                    return value($default);
+                }
+
+                $result = [];
+
+                foreach ($target as $item) {
+                    $result[] = data_get($item, $key);
+                }
+
+                return in_array('*', $key) ? Arr::collapse($result) : $result;
+            }
+
+            if (Arr::accessible($target) && Arr::exists($target, $segment)) {
+                $target = $target[$segment];
+            } elseif (is_object($target) && isset($target->{$segment})) {
+                $target = $target->{$segment};
+            } else {
+                return value($default);
+            }
+        }
+
+        return $target;
+    }
+}
+
+if (! function_exists('data_set')) {
+    /**
+     * Set an item on an array or object using dot notation.
+     *
+     * @param  mixed  $target
+     * @param  string|array  $key
+     * @param  mixed  $value
+     * @param  bool  $overwrite
+     * @return mixed
+     */
+    function data_set(&$target, $key, $value, $overwrite = true)
+    {
+        $segments = is_array($key) ? $key : explode('.', $key);
+
+        if (($segment = array_shift($segments)) === '*') {
+            if (! Arr::accessible($target)) {
+                $target = [];
+            }
+
+            if ($segments) {
+                foreach ($target as &$inner) {
+                    data_set($inner, $segments, $value, $overwrite);
+                }
+            } elseif ($overwrite) {
+                foreach ($target as &$inner) {
+                    $inner = $value;
+                }
+            }
+        } elseif (Arr::accessible($target)) {
+            if ($segments) {
+                if (! Arr::exists($target, $segment)) {
+                    $target[$segment] = [];
+                }
+
+                data_set($target[$segment], $segments, $value, $overwrite);
+            } elseif ($overwrite || ! Arr::exists($target, $segment)) {
+                $target[$segment] = $value;
+            }
+        } elseif (is_object($target)) {
+            if ($segments) {
+                if (! isset($target->{$segment})) {
+                    $target->{$segment} = [];
+                }
+
+                data_set($target->{$segment}, $segments, $value, $overwrite);
+            } elseif ($overwrite || ! isset($target->{$segment})) {
+                $target->{$segment} = $value;
+            }
+        } else {
+            $target = [];
+
+            if ($segments) {
+                data_set($target[$segment], $segments, $value, $overwrite);
+            } elseif ($overwrite) {
+                $target[$segment] = $value;
+            }
+        }
+
+        return $target;
+    }
+}
+
+if (! function_exists('data_forget')) {
+    /**
+     * Remove / unset an item from an array or object using "dot" notation.
+     *
+     * @param  mixed  $target
+     * @param  string|array|int|null  $key
+     * @return mixed
+     */
+    function data_forget(&$target, $key)
+    {
+        $segments = is_array($key) ? $key : explode('.', $key);
+
+        if (($segment = array_shift($segments)) === '*' && Arr::accessible($target)) {
+            if ($segments) {
+                foreach ($target as &$inner) {
+                    data_forget($inner, $segments);
+                }
+            }
+        } elseif (Arr::accessible($target)) {
+            if ($segments && Arr::exists($target, $segment)) {
+                data_forget($target[$segment], $segments);
+            } else {
+                Arr::forget($target, $segment);
+            }
+        } elseif (is_object($target)) {
+            if ($segments && isset($target->{$segment})) {
+                data_forget($target->{$segment}, $segments);
+            } elseif (isset($target->{$segment})) {
+                unset($target->{$segment});
+            }
+        }
+
+        return $target;
+    }
+}
+
+if (! function_exists('head')) {
+    /**
+     * Get the first element of an array. Useful for method chaining.
+     *
+     * @param  array  $array
+     * @return mixed
+     */
+    function head($array)
+    {
+        return reset($array);
+    }
+}
+
+if (! function_exists('last')) {
+    /**
+     * Get the last element from an array.
+     *
+     * @param  array  $array
+     * @return mixed
+     */
+    function last($array)
+    {
+        return end($array);
+    }
+}
+
+if (! function_exists('value')) {
+    /**
+     * Return the default value of the given value.
+     *
+     * @param  mixed  $value
+     * @param  mixed  ...$args
+     * @return mixed
+     */
+    function value($value, ...$args)
+    {
+        return $value instanceof Closure ? $value(...$args) : $value;
+    }
+}

+ 109 - 0
vendor/illuminate/conditionable/HigherOrderWhenProxy.php

@@ -0,0 +1,109 @@
+<?php
+
+namespace Illuminate\Support;
+
+class HigherOrderWhenProxy
+{
+    /**
+     * The target being conditionally operated on.
+     *
+     * @var mixed
+     */
+    protected $target;
+
+    /**
+     * The condition for proxying.
+     *
+     * @var bool
+     */
+    protected $condition;
+
+    /**
+     * Indicates whether the proxy has a condition.
+     *
+     * @var bool
+     */
+    protected $hasCondition = false;
+
+    /**
+     * Determine whether the condition should be negated.
+     *
+     * @var bool
+     */
+    protected $negateConditionOnCapture;
+
+    /**
+     * Create a new proxy instance.
+     *
+     * @param  mixed  $target
+     * @return void
+     */
+    public function __construct($target)
+    {
+        $this->target = $target;
+    }
+
+    /**
+     * Set the condition on the proxy.
+     *
+     * @param  bool  $condition
+     * @return $this
+     */
+    public function condition($condition)
+    {
+        [$this->condition, $this->hasCondition] = [$condition, true];
+
+        return $this;
+    }
+
+    /**
+     * Indicate that the condition should be negated.
+     *
+     * @return $this
+     */
+    public function negateConditionOnCapture()
+    {
+        $this->negateConditionOnCapture = true;
+
+        return $this;
+    }
+
+    /**
+     * Proxy accessing an attribute onto the target.
+     *
+     * @param  string  $key
+     * @return mixed
+     */
+    public function __get($key)
+    {
+        if (! $this->hasCondition) {
+            $condition = $this->target->{$key};
+
+            return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition);
+        }
+
+        return $this->condition
+            ? $this->target->{$key}
+            : $this->target;
+    }
+
+    /**
+     * Proxy a method call on the target.
+     *
+     * @param  string  $method
+     * @param  array  $parameters
+     * @return mixed
+     */
+    public function __call($method, $parameters)
+    {
+        if (! $this->hasCondition) {
+            $condition = $this->target->{$method}(...$parameters);
+
+            return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition);
+        }
+
+        return $this->condition
+            ? $this->target->{$method}(...$parameters)
+            : $this->target;
+    }
+}

+ 21 - 0
vendor/illuminate/conditionable/LICENSE.md

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Taylor Otwell
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 73 - 0
vendor/illuminate/conditionable/Traits/Conditionable.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace Illuminate\Support\Traits;
+
+use Closure;
+use Illuminate\Support\HigherOrderWhenProxy;
+
+trait Conditionable
+{
+    /**
+     * Apply the callback if the given "value" is (or resolves to) truthy.
+     *
+     * @template TWhenParameter
+     * @template TWhenReturnType
+     *
+     * @param  (\Closure($this): TWhenParameter)|TWhenParameter|null  $value
+     * @param  (callable($this, TWhenParameter): TWhenReturnType)|null  $callback
+     * @param  (callable($this, TWhenParameter): TWhenReturnType)|null  $default
+     * @return $this|TWhenReturnType
+     */
+    public function when($value = null, ?callable $callback = null, ?callable $default = null)
+    {
+        $value = $value instanceof Closure ? $value($this) : $value;
+
+        if (func_num_args() === 0) {
+            return new HigherOrderWhenProxy($this);
+        }
+
+        if (func_num_args() === 1) {
+            return (new HigherOrderWhenProxy($this))->condition($value);
+        }
+
+        if ($value) {
+            return $callback($this, $value) ?? $this;
+        } elseif ($default) {
+            return $default($this, $value) ?? $this;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Apply the callback if the given "value" is (or resolves to) falsy.
+     *
+     * @template TUnlessParameter
+     * @template TUnlessReturnType
+     *
+     * @param  (\Closure($this): TUnlessParameter)|TUnlessParameter|null  $value
+     * @param  (callable($this, TUnlessParameter): TUnlessReturnType)|null  $callback
+     * @param  (callable($this, TUnlessParameter): TUnlessReturnType)|null  $default
+     * @return $this|TUnlessReturnType
+     */
+    public function unless($value = null, ?callable $callback = null, ?callable $default = null)
+    {
+        $value = $value instanceof Closure ? $value($this) : $value;
+
+        if (func_num_args() === 0) {
+            return (new HigherOrderWhenProxy($this))->negateConditionOnCapture();
+        }
+
+        if (func_num_args() === 1) {
+            return (new HigherOrderWhenProxy($this))->condition(! $value);
+        }
+
+        if (! $value) {
+            return $callback($this, $value) ?? $this;
+        } elseif ($default) {
+            return $default($this, $value) ?? $this;
+        }
+
+        return $this;
+    }
+}

+ 33 - 0
vendor/illuminate/conditionable/composer.json

@@ -0,0 +1,33 @@
+{
+    "name": "illuminate/conditionable",
+    "description": "The Illuminate Conditionable package.",
+    "license": "MIT",
+    "homepage": "https://laravel.com",
+    "support": {
+        "issues": "https://github.com/laravel/framework/issues",
+        "source": "https://github.com/laravel/framework"
+    },
+    "authors": [
+        {
+            "name": "Taylor Otwell",
+            "email": "taylor@laravel.com"
+        }
+    ],
+    "require": {
+        "php": "^8.0.2"
+    },
+    "autoload": {
+        "psr-4": {
+            "Illuminate\\Support\\": ""
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "10.x-dev"
+        }
+    },
+    "config": {
+        "sort-packages": true
+    },
+    "minimum-stability": "dev"
+}

+ 15 - 0
vendor/illuminate/contracts/Auth/Access/Authorizable.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace Illuminate\Contracts\Auth\Access;
+
+interface Authorizable
+{
+    /**
+     * Determine if the entity has a given ability.
+     *
+     * @param  iterable|string  $abilities
+     * @param  array|mixed  $arguments
+     * @return bool
+     */
+    public function can($abilities, $arguments = []);
+}

+ 150 - 0
vendor/illuminate/contracts/Auth/Access/Gate.php

@@ -0,0 +1,150 @@
+<?php
+
+namespace Illuminate\Contracts\Auth\Access;
+
+interface Gate
+{
+    /**
+     * Determine if a given ability has been defined.
+     *
+     * @param  string  $ability
+     * @return bool
+     */
+    public function has($ability);
+
+    /**
+     * Define a new ability.
+     *
+     * @param  string  $ability
+     * @param  callable|string  $callback
+     * @return $this
+     */
+    public function define($ability, $callback);
+
+    /**
+     * Define abilities for a resource.
+     *
+     * @param  string  $name
+     * @param  string  $class
+     * @param  array|null  $abilities
+     * @return $this
+     */
+    public function resource($name, $class, ?array $abilities = null);
+
+    /**
+     * Define a policy class for a given class type.
+     *
+     * @param  string  $class
+     * @param  string  $policy
+     * @return $this
+     */
+    public function policy($class, $policy);
+
+    /**
+     * Register a callback to run before all Gate checks.
+     *
+     * @param  callable  $callback
+     * @return $this
+     */
+    public function before(callable $callback);
+
+    /**
+     * Register a callback to run after all Gate checks.
+     *
+     * @param  callable  $callback
+     * @return $this
+     */
+    public function after(callable $callback);
+
+    /**
+     * Determine if all of the given abilities should be granted for the current user.
+     *
+     * @param  iterable|string  $ability
+     * @param  array|mixed  $arguments
+     * @return bool
+     */
+    public function allows($ability, $arguments = []);
+
+    /**
+     * Determine if any of the given abilities should be denied for the current user.
+     *
+     * @param  iterable|string  $ability
+     * @param  array|mixed  $arguments
+     * @return bool
+     */
+    public function denies($ability, $arguments = []);
+
+    /**
+     * Determine if all of the given abilities should be granted for the current user.
+     *
+     * @param  iterable|string  $abilities
+     * @param  array|mixed  $arguments
+     * @return bool
+     */
+    public function check($abilities, $arguments = []);
+
+    /**
+     * Determine if any one of the given abilities should be granted for the current user.
+     *
+     * @param  iterable|string  $abilities
+     * @param  array|mixed  $arguments
+     * @return bool
+     */
+    public function any($abilities, $arguments = []);
+
+    /**
+     * Determine if the given ability should be granted for the current user.
+     *
+     * @param  string  $ability
+     * @param  array|mixed  $arguments
+     * @return \Illuminate\Auth\Access\Response
+     *
+     * @throws \Illuminate\Auth\Access\AuthorizationException
+     */
+    public function authorize($ability, $arguments = []);
+
+    /**
+     * Inspect the user for the given ability.
+     *
+     * @param  string  $ability
+     * @param  array|mixed  $arguments
+     * @return \Illuminate\Auth\Access\Response
+     */
+    public function inspect($ability, $arguments = []);
+
+    /**
+     * Get the raw result from the authorization callback.
+     *
+     * @param  string  $ability
+     * @param  array|mixed  $arguments
+     * @return mixed
+     *
+     * @throws \Illuminate\Auth\Access\AuthorizationException
+     */
+    public function raw($ability, $arguments = []);
+
+    /**
+     * Get a policy instance for a given class.
+     *
+     * @param  object|string  $class
+     * @return mixed
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function getPolicyFor($class);
+
+    /**
+     * Get a guard instance for the given user.
+     *
+     * @param  \Illuminate\Contracts\Auth\Authenticatable|mixed  $user
+     * @return static
+     */
+    public function forUser($user);
+
+    /**
+     * Get all of the defined abilities.
+     *
+     * @return array
+     */
+    public function abilities();
+}

+ 49 - 0
vendor/illuminate/contracts/Auth/Authenticatable.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+interface Authenticatable
+{
+    /**
+     * Get the name of the unique identifier for the user.
+     *
+     * @return string
+     */
+    public function getAuthIdentifierName();
+
+    /**
+     * Get the unique identifier for the user.
+     *
+     * @return mixed
+     */
+    public function getAuthIdentifier();
+
+    /**
+     * Get the password for the user.
+     *
+     * @return string
+     */
+    public function getAuthPassword();
+
+    /**
+     * Get the token value for the "remember me" session.
+     *
+     * @return string
+     */
+    public function getRememberToken();
+
+    /**
+     * Set the token value for the "remember me" session.
+     *
+     * @param  string  $value
+     * @return void
+     */
+    public function setRememberToken($value);
+
+    /**
+     * Get the column name for the "remember me" token.
+     *
+     * @return string
+     */
+    public function getRememberTokenName();
+}

+ 21 - 0
vendor/illuminate/contracts/Auth/CanResetPassword.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+interface CanResetPassword
+{
+    /**
+     * Get the e-mail address where password reset links are sent.
+     *
+     * @return string
+     */
+    public function getEmailForPasswordReset();
+
+    /**
+     * Send the password reset notification.
+     *
+     * @param  string  $token
+     * @return void
+     */
+    public function sendPasswordResetNotification($token);
+}

+ 22 - 0
vendor/illuminate/contracts/Auth/Factory.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+interface Factory
+{
+    /**
+     * Get a guard instance by name.
+     *
+     * @param  string|null  $name
+     * @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
+     */
+    public function guard($name = null);
+
+    /**
+     * Set the default guard the factory should serve.
+     *
+     * @param  string  $name
+     * @return void
+     */
+    public function shouldUse($name);
+}

+ 57 - 0
vendor/illuminate/contracts/Auth/Guard.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+interface Guard
+{
+    /**
+     * Determine if the current user is authenticated.
+     *
+     * @return bool
+     */
+    public function check();
+
+    /**
+     * Determine if the current user is a guest.
+     *
+     * @return bool
+     */
+    public function guest();
+
+    /**
+     * Get the currently authenticated user.
+     *
+     * @return \Illuminate\Contracts\Auth\Authenticatable|null
+     */
+    public function user();
+
+    /**
+     * Get the ID for the currently authenticated user.
+     *
+     * @return int|string|null
+     */
+    public function id();
+
+    /**
+     * Validate a user's credentials.
+     *
+     * @param  array  $credentials
+     * @return bool
+     */
+    public function validate(array $credentials = []);
+
+    /**
+     * Determine if the guard has a user instance.
+     *
+     * @return bool
+     */
+    public function hasUser();
+
+    /**
+     * Set the current user.
+     *
+     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
+     * @return void
+     */
+    public function setUser(Authenticatable $user);
+}

+ 8 - 0
vendor/illuminate/contracts/Auth/Middleware/AuthenticatesRequests.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace Illuminate\Contracts\Auth\Middleware;
+
+interface AuthenticatesRequests
+{
+    //
+}

+ 34 - 0
vendor/illuminate/contracts/Auth/MustVerifyEmail.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+interface MustVerifyEmail
+{
+    /**
+     * Determine if the user has verified their email address.
+     *
+     * @return bool
+     */
+    public function hasVerifiedEmail();
+
+    /**
+     * Mark the given user's email as verified.
+     *
+     * @return bool
+     */
+    public function markEmailAsVerified();
+
+    /**
+     * Send the email verification notification.
+     *
+     * @return void
+     */
+    public function sendEmailVerificationNotification();
+
+    /**
+     * Get the email address that should be used for verification.
+     *
+     * @return string
+     */
+    public function getEmailForVerification();
+}

+ 61 - 0
vendor/illuminate/contracts/Auth/PasswordBroker.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+use Closure;
+
+interface PasswordBroker
+{
+    /**
+     * Constant representing a successfully sent reminder.
+     *
+     * @var string
+     */
+    const RESET_LINK_SENT = 'passwords.sent';
+
+    /**
+     * Constant representing a successfully reset password.
+     *
+     * @var string
+     */
+    const PASSWORD_RESET = 'passwords.reset';
+
+    /**
+     * Constant representing the user not found response.
+     *
+     * @var string
+     */
+    const INVALID_USER = 'passwords.user';
+
+    /**
+     * Constant representing an invalid token.
+     *
+     * @var string
+     */
+    const INVALID_TOKEN = 'passwords.token';
+
+    /**
+     * Constant representing a throttled reset attempt.
+     *
+     * @var string
+     */
+    const RESET_THROTTLED = 'passwords.throttled';
+
+    /**
+     * Send a password reset link to a user.
+     *
+     * @param  array  $credentials
+     * @param  \Closure|null  $callback
+     * @return string
+     */
+    public function sendResetLink(array $credentials, ?Closure $callback = null);
+
+    /**
+     * Reset the password for the given token.
+     *
+     * @param  array  $credentials
+     * @param  \Closure  $callback
+     * @return mixed
+     */
+    public function reset(array $credentials, Closure $callback);
+}

+ 14 - 0
vendor/illuminate/contracts/Auth/PasswordBrokerFactory.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+interface PasswordBrokerFactory
+{
+    /**
+     * Get a password broker instance by name.
+     *
+     * @param  string|null  $name
+     * @return \Illuminate\Contracts\Auth\PasswordBroker
+     */
+    public function broker($name = null);
+}

+ 63 - 0
vendor/illuminate/contracts/Auth/StatefulGuard.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+interface StatefulGuard extends Guard
+{
+    /**
+     * Attempt to authenticate a user using the given credentials.
+     *
+     * @param  array  $credentials
+     * @param  bool  $remember
+     * @return bool
+     */
+    public function attempt(array $credentials = [], $remember = false);
+
+    /**
+     * Log a user into the application without sessions or cookies.
+     *
+     * @param  array  $credentials
+     * @return bool
+     */
+    public function once(array $credentials = []);
+
+    /**
+     * Log a user into the application.
+     *
+     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
+     * @param  bool  $remember
+     * @return void
+     */
+    public function login(Authenticatable $user, $remember = false);
+
+    /**
+     * Log the given user ID into the application.
+     *
+     * @param  mixed  $id
+     * @param  bool  $remember
+     * @return \Illuminate\Contracts\Auth\Authenticatable|bool
+     */
+    public function loginUsingId($id, $remember = false);
+
+    /**
+     * Log the given user ID into the application without sessions or cookies.
+     *
+     * @param  mixed  $id
+     * @return \Illuminate\Contracts\Auth\Authenticatable|bool
+     */
+    public function onceUsingId($id);
+
+    /**
+     * Determine if the user was authenticated via "remember me" cookie.
+     *
+     * @return bool
+     */
+    public function viaRemember();
+
+    /**
+     * Log the user out of the application.
+     *
+     * @return void
+     */
+    public function logout();
+}

+ 24 - 0
vendor/illuminate/contracts/Auth/SupportsBasicAuth.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+interface SupportsBasicAuth
+{
+    /**
+     * Attempt to authenticate using HTTP Basic Auth.
+     *
+     * @param  string  $field
+     * @param  array  $extraConditions
+     * @return \Symfony\Component\HttpFoundation\Response|null
+     */
+    public function basic($field = 'email', $extraConditions = []);
+
+    /**
+     * Perform a stateless HTTP Basic login attempt.
+     *
+     * @param  string  $field
+     * @param  array  $extraConditions
+     * @return \Symfony\Component\HttpFoundation\Response|null
+     */
+    public function onceBasic($field = 'email', $extraConditions = []);
+}

+ 49 - 0
vendor/illuminate/contracts/Auth/UserProvider.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace Illuminate\Contracts\Auth;
+
+interface UserProvider
+{
+    /**
+     * Retrieve a user by their unique identifier.
+     *
+     * @param  mixed  $identifier
+     * @return \Illuminate\Contracts\Auth\Authenticatable|null
+     */
+    public function retrieveById($identifier);
+
+    /**
+     * Retrieve a user by their unique identifier and "remember me" token.
+     *
+     * @param  mixed  $identifier
+     * @param  string  $token
+     * @return \Illuminate\Contracts\Auth\Authenticatable|null
+     */
+    public function retrieveByToken($identifier, $token);
+
+    /**
+     * Update the "remember me" token for the given user in storage.
+     *
+     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
+     * @param  string  $token
+     * @return void
+     */
+    public function updateRememberToken(Authenticatable $user, $token);
+
+    /**
+     * Retrieve a user by the given credentials.
+     *
+     * @param  array  $credentials
+     * @return \Illuminate\Contracts\Auth\Authenticatable|null
+     */
+    public function retrieveByCredentials(array $credentials);
+
+    /**
+     * Validate a user against the given credentials.
+     *
+     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
+     * @param  array  $credentials
+     * @return bool
+     */
+    public function validateCredentials(Authenticatable $user, array $credentials);
+}

+ 35 - 0
vendor/illuminate/contracts/Broadcasting/Broadcaster.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace Illuminate\Contracts\Broadcasting;
+
+interface Broadcaster
+{
+    /**
+     * Authenticate the incoming request for a given channel.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return mixed
+     */
+    public function auth($request);
+
+    /**
+     * Return the valid authentication response.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  mixed  $result
+     * @return mixed
+     */
+    public function validAuthenticationResponse($request, $result);
+
+    /**
+     * Broadcast the given event.
+     *
+     * @param  array  $channels
+     * @param  string  $event
+     * @param  array  $payload
+     * @return void
+     *
+     * @throws \Illuminate\Broadcasting\BroadcastException
+     */
+    public function broadcast(array $channels, $event, array $payload = []);
+}

+ 14 - 0
vendor/illuminate/contracts/Broadcasting/Factory.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace Illuminate\Contracts\Broadcasting;
+
+interface Factory
+{
+    /**
+     * Get a broadcaster implementation by name.
+     *
+     * @param  string|null  $name
+     * @return \Illuminate\Contracts\Broadcasting\Broadcaster
+     */
+    public function connection($name = null);
+}

+ 20 - 0
vendor/illuminate/contracts/Broadcasting/HasBroadcastChannel.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace Illuminate\Contracts\Broadcasting;
+
+interface HasBroadcastChannel
+{
+    /**
+     * Get the broadcast channel route definition that is associated with the given entity.
+     *
+     * @return string
+     */
+    public function broadcastChannelRoute();
+
+    /**
+     * Get the broadcast channel name that is associated with the given entity.
+     *
+     * @return string
+     */
+    public function broadcastChannel();
+}

+ 8 - 0
vendor/illuminate/contracts/Broadcasting/ShouldBeUnique.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace Illuminate\Contracts\Broadcasting;
+
+interface ShouldBeUnique
+{
+    //
+}

+ 13 - 0
vendor/illuminate/contracts/Broadcasting/ShouldBroadcast.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace Illuminate\Contracts\Broadcasting;
+
+interface ShouldBroadcast
+{
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|\Illuminate\Broadcasting\Channel[]|string[]|string
+     */
+    public function broadcastOn();
+}

+ 8 - 0
vendor/illuminate/contracts/Broadcasting/ShouldBroadcastNow.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace Illuminate\Contracts\Broadcasting;
+
+interface ShouldBroadcastNow extends ShouldBroadcast
+{
+    //
+}

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác