diff --git a/CHANGELOG.md b/CHANGELOG.md
index 57551cd5c..fbedba16c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -86,6 +86,8 @@
- Updated StatusService, add getMastodon method for mastoapi compatibility. ([36a129fe](https://github.com/pixelfed/pixelfed/commit/36a129fe))
- Updated PublicApiController, fix accountStatuses pagination operator. ([85fc9dd0](https://github.com/pixelfed/pixelfed/commit/85fc9dd0))
- Updated PublicApiController, enforce only_media on accountStatuses method. Fixes #3105. ([861a2d36](https://github.com/pixelfed/pixelfed/commit/861a2d36))
+- Updated ApiV1Controller, add mastoapi strict mode. ([46485426](https://github.com/pixelfed/pixelfed/commit/46485426))
+- Updated AccountController, refresh RelationshipService on mute/block. ([6f1b0245](https://github.com/pixelfed/pixelfed/commit/6f1b0245))
- ([](https://github.com/pixelfed/pixelfed/commit/))
## [v0.11.1 (2021-09-07)](https://github.com/pixelfed/pixelfed/compare/v0.11.0...v0.11.1)
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index edbf6a4cc..073bbfa81 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -28,6 +28,7 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use App\Transformer\Api\Mastodon\v1\AccountTransformer;
use App\Services\AccountService;
use App\Services\UserFilterService;
+use App\Services\RelationshipService;
class AccountController extends Controller
{
@@ -184,6 +185,7 @@ class AccountController extends Controller
Cache::forget("user:filter:list:$pid");
Cache::forget("feature:discover:posts:$pid");
Cache::forget("api:local:exp:rec:$pid");
+ RelationshipService::refresh($pid, $profile->id);
return redirect()->back();
}
@@ -234,6 +236,7 @@ class AccountController extends Controller
Cache::forget("user:filter:list:$pid");
Cache::forget("feature:discover:posts:$pid");
Cache::forget("api:local:exp:rec:$pid");
+ RelationshipService::refresh($pid, $profile->id);
if($request->wantsJson()) {
return response()->json([200]);
@@ -288,6 +291,7 @@ class AccountController extends Controller
$pid = $user->id;
Cache::forget("user:filter:list:$pid");
Cache::forget("api:local:exp:rec:$pid");
+ RelationshipService::refresh($pid, $profile->id);
return redirect()->back();
}
@@ -338,6 +342,7 @@ class AccountController extends Controller
Cache::forget("user:filter:list:$pid");
Cache::forget("feature:discover:posts:$pid");
Cache::forget("api:local:exp:rec:$pid");
+ RelationshipService::refresh($pid, $profile->id);
return redirect()->back();
}
diff --git a/app/Http/Controllers/Admin/AdminSettingsController.php b/app/Http/Controllers/Admin/AdminSettingsController.php
index c033b769b..a245997d8 100644
--- a/app/Http/Controllers/Admin/AdminSettingsController.php
+++ b/app/Http/Controllers/Admin/AdminSettingsController.php
@@ -170,6 +170,8 @@ trait AdminSettingsController
$json[] = $val;
ConfigCacheService::put('app.rules', json_encode(array_values($json)));
}
+ Cache::forget('api:v1:instance-data:rules');
+ Cache::forget('api:v1:instance-data-response');
}
if($request->filled('account_autofollow_usernames')) {
diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php
index b4cc51e93..b27cb2fd1 100644
--- a/app/Http/Controllers/Api/ApiV1Controller.php
+++ b/app/Http/Controllers/Api/ApiV1Controller.php
@@ -16,6 +16,7 @@ use App\{
Follower,
FollowRequest,
Hashtag,
+ Instance,
Like,
Media,
Notification,
@@ -64,7 +65,6 @@ use App\Services\{
NotificationService,
MediaPathService,
PublicTimelineService,
- ProfileService,
RelationshipService,
SearchApiV2Service,
StatusService,
@@ -142,15 +142,15 @@ class ApiV1Controller extends Controller
$id = $request->user()->profile_id;
- $res = ProfileService::get($id);
+ $res = AccountService::getMastodon($id);
- $res['source'] = [
- 'privacy' => $res['locked'] ? 'private' : 'public',
- 'sensitive' => false,
- 'language' => null,
- 'note' => '',
- 'fields' => []
- ];
+ // $res['source'] = [
+ // 'privacy' => $res['locked'] ? 'private' : 'public',
+ // 'sensitive' => false,
+ // 'language' => null,
+ // 'note' => '',
+ // 'fields' => []
+ // ];
return response()->json($res);
}
@@ -164,10 +164,10 @@ class ApiV1Controller extends Controller
*/
public function accountById(Request $request, $id)
{
- $profile = Profile::whereNull('status')->findOrFail($id);
- $resource = new Fractal\Resource\Item($profile, new AccountTransformer());
- $res = $this->fractal->createData($resource)->toArray();
-
+ $res = AccountService::getMastodon($id, true);
+ if(!$res) {
+ return response()->json(['error' => 'Record not found'], 404);
+ }
return response()->json($res);
}
@@ -394,7 +394,7 @@ class ApiV1Controller extends Controller
MediaSyncLicensePipeline::dispatch($user->id, $request->input('license'));
}
- $res = AccountService::get($user->profile_id);
+ $res = AccountService::getMastodon($user->profile_id);
$res['bio'] = strip_tags($res['note']);
$res = array_merge($res, $other);
@@ -508,7 +508,7 @@ class ApiV1Controller extends Controller
'limit' => 'nullable|integer|min:1|max:80'
]);
- $profile = AccountService::get($id);
+ $profile = AccountService::getMastodon($id);
abort_if(!$profile, 404);
$limit = $request->limit ?? 20;
@@ -534,17 +534,12 @@ class ApiV1Controller extends Controller
if($pid == $profile['id']) {
$visibility = ['public', 'unlisted', 'private'];
} else if($profile['locked']) {
- $following = Cache::remember('profile:following:'.$pid, now()->addMinutes(1440), function() use($pid) {
- $following = Follower::whereProfileId($pid)->pluck('following_id');
- return $following->push($pid)->toArray();
- });
- $visibility = true == in_array($profile['id'], $following) ? ['public', 'unlisted', 'private'] : [];
+ $following = FollowerService::follows($pid, $profile['id']);
+ abort_unless($following, 403);
+ $visibility = ['public', 'unlisted', 'private'];
} else {
- $following = Cache::remember('profile:following:'.$pid, now()->addMinutes(1440), function() use($pid) {
- $following = Follower::whereProfileId($pid)->pluck('following_id');
- return $following->push($pid)->toArray();
- });
- $visibility = true == in_array($profile['id'], $following) ? ['public', 'unlisted', 'private'] : ['public', 'unlisted'];
+ $following = FollowerService::follows($pid, $profile['id']);
+ $visibility = $following ? ['public', 'unlisted', 'private'] : ['public', 'unlisted'];
}
$dir = $min_id ? '>' : '<';
@@ -560,7 +555,7 @@ class ApiV1Controller extends Controller
->get()
->map(function($s) use($user) {
try {
- $status = StatusService::get($s->id, false);
+ $status = StatusService::getMastodon($s->id, false);
} catch (\Exception $e) {
$status = false;
}
@@ -968,7 +963,7 @@ class ApiV1Controller extends Controller
->limit($limit)
->get()
->map(function($like) {
- $status = StatusService::get($like['status_id'], false);
+ $status = StatusService::getMastodon($like['status_id'], false);
$status['like_id'] = $like->id;
$status['liked_at'] = $like->created_at->format('c');
return $status;
@@ -1172,49 +1167,53 @@ class ApiV1Controller extends Controller
*/
public function instance(Request $request)
{
- $res = Cache::remember('api:v1:instance-data', now()->addMinutes(15), function () {
- $rules = config_cache('app.rules') ? collect(json_decode(config_cache('app.rules'), true))
- ->map(function($rule, $key) {
- $id = $key + 1;
- return [
- 'id' => "{$id}",
- 'text' => $rule
- ];
- })
- ->toArray() : [];
- $res = [
- 'approval_required' => false,
- 'contact_account' => null,
- 'description' => config_cache('app.description'),
- 'email' => config('instance.email'),
- 'invites_enabled' => false,
- 'rules' => $rules,
- 'short_description' => 'Pixelfed - Photo sharing for everyone',
- 'languages' => ['en'],
- 'max_toot_chars' => (int) config('pixelfed.max_caption_length'),
- 'registrations' => (bool) config_cache('pixelfed.open_registration'),
- 'stats' => [
- 'user_count' => 0,
- 'status_count' => 0,
- 'domain_count' => 0
- ],
- 'thumbnail' => config('app.url') . '/img/pixelfed-icon-color.png',
- 'title' => config_cache('app.name'),
- 'uri' => config('pixelfed.domain.app'),
- 'urls' => [],
- 'version' => '2.7.2 (compatible; Pixelfed ' . config('pixelfed.version') . ')',
- 'environment' => [
- 'max_photo_size' => (int) config_cache('pixelfed.max_photo_size'),
- 'max_avatar_size' => (int) config('pixelfed.max_avatar_size'),
- 'max_caption_length' => (int) config('pixelfed.max_caption_length'),
- 'max_bio_length' => (int) config('pixelfed.max_bio_length'),
- 'max_album_length' => (int) config_cache('pixelfed.max_album_length'),
- 'mobile_apis' => (bool) config_cache('pixelfed.oauth_enabled')
+ $res = Cache::remember('api:v1:instance-data-response', 900, function () {
+ $contact = Cache::remember('api:v1:instance-data:contact', 604800, function () {
+ $admin = User::whereIsAdmin(true)->first();
+ return $admin && isset($admin->profile_id) ?
+ AccountService::getMastodon($admin->profile_id, true) :
+ null;
+ });
- ]
+ $stats = Cache::remember('api:v1:instance-data:stats', 43200, function () {
+ return [
+ 'user_count' => User::count(),
+ 'status_count' => Status::whereNull('uri')->count(),
+ 'domain_count' => Instance::count(),
+ ];
+ });
+
+ $rules = Cache::remember('api:v1:instance-data:rules', 604800, function () {
+ return config_cache('app.rules') ?
+ collect(json_decode(config_cache('app.rules'), true))
+ ->map(function($rule, $key) {
+ $id = $key + 1;
+ return [
+ 'id' => "{$id}",
+ 'text' => $rule
+ ];
+ })
+ ->toArray() : [];
+ });
+
+ return [
+ 'uri' => config('pixelfed.domain.app'),
+ 'title' => config('app.name'),
+ 'short_description' => 'Pixelfed is an image sharing platform, an ethical alternative to centralized platforms',
+ 'description' => 'Pixelfed is an image sharing platform, an ethical alternative to centralized platforms',
+ 'email' => config('instance.email'),
+ 'version' => config('pixelfed.version'),
+ 'urls' => [],
+ 'stats' => $stats,
+ 'thumbnail' => url('headers/default.jpg'),
+ 'languages' => ['en'],
+ 'registrations' => (bool) config('pixelfed.open_registration'),
+ 'approval_required' => false,
+ 'contact_account' => $contact,
+ 'rules' => $rules
];
- return $res;
});
+
return response()->json($res);
}
@@ -1731,7 +1730,7 @@ class ApiV1Controller extends Controller
'id' => $dm->id,
'unread' => false,
'accounts' => [
- AccountService::get($from)
+ AccountService::getMastodon($from)
],
'last_status' => StatusService::getDirectMessage($dm->status_id)
];
@@ -1784,7 +1783,7 @@ class ApiV1Controller extends Controller
$res = collect($feed)
->map(function($k) use($user) {
- $status = StatusService::get($k);
+ $status = StatusService::getMastodon($k);
if($user) {
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $k);
$status['relationship'] = RelationshipService::get($user->profile_id, $status['account']['id']);
@@ -1811,7 +1810,7 @@ class ApiV1Controller extends Controller
$user = $request->user();
- $res = StatusService::get($id, false);
+ $res = StatusService::getMastodon($id, false);
if(!$res || !isset($res['visibility'])) {
abort(404);
}
@@ -2000,7 +1999,7 @@ class ApiV1Controller extends Controller
->limit($limit)
->get()
->map(function($like) {
- $account = AccountService::get($like->profile_id);
+ $account = AccountService::getMastodon($like->profile_id);
$account['follows'] = isset($like->created_at);
return $account;
})
@@ -2314,10 +2313,10 @@ class ApiV1Controller extends Controller
->limit($limit)
->pluck('status_id')
->filter(function($i) {
- return StatusService::get($i);
+ return StatusService::getMastodon($i);
})
->map(function ($i) {
- return StatusService::get($i);
+ return StatusService::getMastodon($i);
})
->filter()
->values()
@@ -2367,7 +2366,7 @@ class ApiV1Controller extends Controller
$res = [];
foreach($bookmarks as $id) {
- $res[] = \App\Services\StatusService::get($id);
+ $res[] = \App\Services\StatusService::getMastodon($id);
}
return $res;
}
@@ -2470,7 +2469,7 @@ class ApiV1Controller extends Controller
$filters = UserFilterService::filters($pid);
$forYou = DiscoverService::getForYou();
$posts = $forYou->take(50)->map(function($post) {
- return StatusService::get($post);
+ return StatusService::getMastodon($post);
})
->filter(function($post) use($filters) {
return $post &&
@@ -2500,7 +2499,7 @@ class ApiV1Controller extends Controller
$limit = $request->input('limit', 3);
$pid = $request->user()->profile_id;
- $status = StatusService::get($id);
+ $status = StatusService::getMastodon($id);
abort_if(!$status || !in_array($status['visibility'], ['public', 'unlisted']), 404);
@@ -2533,7 +2532,7 @@ class ApiV1Controller extends Controller
}
$data = $ids->map(function($post) use($pid) {
- $status = StatusService::get($post->id);
+ $status = StatusService::getMastodon($post->id);
if(!$status || !isset($status['id'])) {
return false;
@@ -2591,7 +2590,7 @@ class ApiV1Controller extends Controller
->get();
$ids = $ids->map(function($profile) {
- return AccountService::get($profile->id);
+ return AccountService::getMastodon($profile->id);
})
->filter(function($profile) use($pid) {
return $profile &&
diff --git a/app/Services/AccountService.php b/app/Services/AccountService.php
index 0410f8f64..62996a838 100644
--- a/app/Services/AccountService.php
+++ b/app/Services/AccountService.php
@@ -40,6 +40,10 @@ class AccountService
return null;
}
+ if(config('exp.emc') == false) {
+ return $account;
+ }
+
unset(
$account['header_bg'],
$account['is_admin'],
diff --git a/app/Services/StatusService.php b/app/Services/StatusService.php
index 3532c8733..7d72ccbe0 100644
--- a/app/Services/StatusService.php
+++ b/app/Services/StatusService.php
@@ -46,6 +46,11 @@ class StatusService
if(!$status) {
return null;
}
+
+ if(config('exp.emc') == false) {
+ return $status;
+ }
+
$status['replies_count'] = $status['reply_count'];
unset(
$status['_v'],
diff --git a/app/Util/Lexer/RestrictedNames.php b/app/Util/Lexer/RestrictedNames.php
index e2968036f..059f5bf00 100644
--- a/app/Util/Lexer/RestrictedNames.php
+++ b/app/Util/Lexer/RestrictedNames.php
@@ -178,6 +178,8 @@ class RestrictedNames
'group',
'groups',
'h',
+ 'header',
+ 'headers',
'home',
'help',
'helpcenter',
diff --git a/config/exp.php b/config/exp.php
index c52614f96..181c49f47 100644
--- a/config/exp.php
+++ b/config/exp.php
@@ -1,13 +1,37 @@
env('EXP_LC', false),
+
+ // Recommendations (deprecated)
'rec' => false,
+
+ // Loops feature (deprecated)
'loops' => false,
+
+ // Text only posts (alpha)
'top' => env('EXP_TOP', false),
+
+ // Poll statuses (alpha)
'polls' => env('EXP_POLLS', false),
+
+ // Cached public timeline for larger instances (beta)
'cached_public_timeline' => env('EXP_CPT', false),
+
+ // Groups (unreleased)
'gps' => env('EXP_GPS', false),
+
+ // Single page application (beta)
'spa' => true,
+
+ // Enforce Mastoapi Compatibility (alpha)
+ // Note: this may break 3rd party apps who use non-mastodon compliant fields
+ 'emc' => env('EXP_EMC', false),
];
diff --git a/public/css/spa.css b/public/css/spa.css
index daebf88a3..5013f20b2 100644
--- a/public/css/spa.css
+++ b/public/css/spa.css
@@ -1 +1 @@
-@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhdzeFaxOedfTDw.woff2) format("woff2");unicode-range:U+0460-052f,U+1c80-1c88,U+20b4,U+2de0-2dff,U+a640-a69f,U+fe2e-fe2f}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhdXeFaxOedfTDw.woff2) format("woff2");unicode-range:U+0400-045f,U+0490-0491,U+04b0-04b1,U+2116}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhdLeFaxOedfTDw.woff2) format("woff2");unicode-range:U+0370-03ff}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhd7eFaxOedfTDw.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01a0-01a1,U+01af-01b0,U+1ea0-1ef9,U+20ab}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhd_eFaxOedfTDw.woff2) format("woff2");unicode-range:U+0100-024f,U+0259,U+1e??,U+2020,U+20a0-20ab,U+20ad-20cf,U+2113,U+2c60-2c7f,U+a720-a7ff}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhdHeFaxOedc.woff2) format("woff2");unicode-range:U+00??,U+0131,U+0152-0153,U+02bb-02bc,U+02c6,U+02da,U+02dc,U+2000-206f,U+2074,U+20ac,U+2122,U+2191,U+2193,U+2212,U+2215,U+feff,U+fffd}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AIxsdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0460-052f,U+1c80-1c88,U+20b4,U+2de0-2dff,U+a640-a69f,U+fe2e-fe2f}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AIVsdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0400-045f,U+0490-0491,U+04b0-04b1,U+2116}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AIJsdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0370-03ff}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AI5sdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01a0-01a1,U+01af-01b0,U+1ea0-1ef9,U+20ab}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AI9sdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0100-024f,U+0259,U+1e??,U+2020,U+20a0-20ab,U+20ad-20cf,U+2113,U+2c60-2c7f,U+a720-a7ff}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AIFsdP3pBms.woff2) format("woff2");unicode-range:U+00??,U+0131,U+0152-0153,U+02bb-02bc,U+02c6,U+02da,U+02dc,U+2000-206f,U+2074,U+20ac,U+2122,U+2191,U+2193,U+2212,U+2215,U+feff,U+fffd}body{background:#f3f4f6;font-family:IBM Plex Sans,sans-serif}.primary{color:#3b82f6}.web-wrapper{margin-bottom:10rem}.jumbotron{border-radius:18px}.doc-body p:last-child{margin-bottom:0}.sticky-top{z-index:2}.container-fluid{max-width:1440px!important}.text-lighter{color:#94a3b8!important}
\ No newline at end of file
+@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhdzeFaxOedfTDw.woff2) format("woff2");unicode-range:U+0460-052f,U+1c80-1c88,U+20b4,U+2de0-2dff,U+a640-a69f,U+fe2e-fe2f}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhdXeFaxOedfTDw.woff2) format("woff2");unicode-range:U+0400-045f,U+0490-0491,U+04b0-04b1,U+2116}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhdLeFaxOedfTDw.woff2) format("woff2");unicode-range:U+0370-03ff}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhd7eFaxOedfTDw.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01a0-01a1,U+01af-01b0,U+1ea0-1ef9,U+20ab}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhd_eFaxOedfTDw.woff2) format("woff2");unicode-range:U+0100-024f,U+0259,U+1e??,U+2020,U+20a0-20ab,U+20ad-20cf,U+2113,U+2c60-2c7f,U+a720-a7ff}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/zYXgKVElMYYaJe8bpLHnCwDKhdHeFaxOedc.woff2) format("woff2");unicode-range:U+00??,U+0131,U+0152-0153,U+02bb-02bc,U+02c6,U+02da,U+02dc,U+2000-206f,U+2074,U+20ac,U+2122,U+2191,U+2193,U+2212,U+2215,U+feff,U+fffd}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AIxsdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0460-052f,U+1c80-1c88,U+20b4,U+2de0-2dff,U+a640-a69f,U+fe2e-fe2f}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AIVsdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0400-045f,U+0490-0491,U+04b0-04b1,U+2116}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AIJsdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0370-03ff}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AI5sdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01a0-01a1,U+01af-01b0,U+1ea0-1ef9,U+20ab}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AI9sdP3pBmtF8A.woff2) format("woff2");unicode-range:U+0100-024f,U+0259,U+1e??,U+2020,U+20a0-20ab,U+20ad-20cf,U+2113,U+2c60-2c7f,U+a720-a7ff}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/zYX9KVElMYYaJe8bpLHnCwDKjQ76AIFsdP3pBms.woff2) format("woff2");unicode-range:U+00??,U+0131,U+0152-0153,U+02bb-02bc,U+02c6,U+02da,U+02dc,U+2000-206f,U+2074,U+20ac,U+2122,U+2191,U+2193,U+2212,U+2215,U+feff,U+fffd}body{background:#f3f4f6;font-family:IBM Plex Sans,sans-serif}.primary{color:#3b82f6}.web-wrapper{margin-bottom:10rem}.jumbotron{border-radius:18px}.doc-body p:last-child{margin-bottom:0}.sticky-top{z-index:2}.container-fluid{max-width:1440px!important}.text-lighter{color:#94a3b8!important}.badge-primary{background-color:#3b82f6}
\ No newline at end of file
diff --git a/public/js/spa.js b/public/js/spa.js
index d50699ab9..4d205c564 100644
--- a/public/js/spa.js
+++ b/public/js/spa.js
@@ -1 +1 @@
-(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{"+/TA":function(t,e,n){"use strict";n("eKim")},"+3PN":function(t,e,n){var i=n("eWeD");"string"==typeof i&&(i=[[t.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n("aET+")(i,o);i.locals&&(t.exports=i.locals)},"+VHp":function(t,e,n){"use strict";n("V8Te")},"+uhv":function(t,e,n){"use strict";n("M24V")},"/RaH":function(t,e,n){var i=n("iTP3");"string"==typeof i&&(i=[[t.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n("aET+")(i,o);i.locals&&(t.exports=i.locals)},"/Y1X":function(t,e,n){"use strict";n("KOWi")},"/jad":function(t,e,n){"use strict";var i=n("1gDp"),o=n("ngXG"),a={props:{status:{type:Object},recommended:{type:Boolean,default:!1},reactionBar:{type:Boolean,default:!0},hasTopBorder:{type:Boolean,default:!1},size:{type:String,validator:function(t){return["regular","small"].includes(t)},default:"regular"}},components:{"context-menu":i.a,"poll-card":o.a},data:function(){return{config:window.App.config,profile:{},loading:!0,replies:[],replyId:null,lightboxMedia:!1,showSuggestions:!0,showReadMore:!0,replyStatus:{},replyText:"",replyNsfw:!1,emoji:window.App.util.emoji}},mounted:function(){this.profile=window._sharedData.curUser},methods:{formatCount:function(t){return App.util.format.count(t)},statusUrl:function(t){return 1==t.local?t.url:"/i/web/post/_/"+t.account.id+"/"+t.id},profileUrl:function(t){return 1==t.local?t.account.url:"/i/web/profile/_/"+t.account.id},timestampFormat:function(t){var e=new Date(t);return e.toDateString()+" "+e.toLocaleTimeString()},shortTimestamp:function(t){return window.App.util.format.timeAgo(t)},statusCardUsernameFormat:function(t){if(1==t.account.local)return t.account.username;var e=window.App.config.username.remote.format,n=window.App.config.username.remote.custom,i=t.account.username,o=document.createElement("a");switch(o.href=t.account.url,o=o.hostname,e){case"@":return i+'@'+o+"";case"from":return i+' from '+o+"";case"custom":return i+' '+n+" "+o+"";default:return i+'@'+o+""}},lightbox:function(t){window.location.href=t.media_attachments[0].url},labelRedirect:function(t){var e="/i/redirect?url="+encodeURI(this.config.features.label.covid.url);window.location.href=e},likeStatus:function(t,e){if(0!=$("body").hasClass("loggedIn")){var n=t.favourites_count;t.favourited=!t.favourited,axios.post("/i/like",{item:t.id}).then((function(e){t.favourites_count=e.data.count,t.favourited=!!t.favourited})).catch((function(e){t.favourited=!!t.favourited,t.favourites_count=n,swal("Error","Something went wrong, please try again later.","error")})),window.navigator.vibrate(200),t.favourited&&setTimeout((function(){e.target.classList.add("animate__animated","animate__bounce")}),100)}},commentFocus:function(t,e){this.$emit("comment-focus",t)},commentSubmit:function(t,e){var n=this;this.replySending=!0;var i=t.id,o=this.replyText,a=this.config.uploader.max_caption_length;if(o.length>a)return this.replySending=!1,void swal("Comment Too Long","Please make sure your comment is "+a+" characters or less.","error");axios.post("/i/comment",{item:i,comment:o,sensitive:this.replyNsfw}).then((function(t){n.replyText="",n.replies.push(t.data.entity),n.$refs.replyModal.hide()})),this.replySending=!1},owner:function(t){return this.profile.id===t.account.id},admin:function(){return 1==this.profile.is_admin},ownerOrAdmin:function(t){return this.owner(t)||this.admin()},ctxMenu:function(){this.$refs.contextMenu.open()},timeAgo:function(t){return App.util.format.timeAgo(t)},statusDeleted:function(t){this.$emit("status-delete",t)},canFollow:function(t){return!!t.hasOwnProperty("relationship")&&(!(!t.hasOwnProperty("account")||!t.account.hasOwnProperty("id"))&&(t.account.id!=this.profile.id&&!t.relationship.following))},follow:function(t){var e=this;event.currentTarget.blur(),axios.post("/i/follow",{item:t}).then((function(n){e.status.relationship.following=!0,e.$emit("followed",t)})).catch((function(t){t.response.data.message&&swal("Error",t.response.data.message,"error")}))},unfollow:function(t){var e=this;event.currentTarget.blur(),axios.post("/i/follow",{item:t}).then((function(n){e.status.relationship.following=!1,e.$emit("unfollowed",t)})).catch((function(t){t.response.data.message&&swal("Error",t.response.data.message,"error")}))}}},r=(n("RePV"),n("KHd+")),s=Object(r.a)(a,(function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"status-card-component",class:{"status-card-sm":"small"===t.size}},["text"===t.status.pf_type?n("div",{staticClass:"card shadow-none border rounded-0",class:{"border-top-0":!t.hasTopBorder}},[n("div",{staticClass:"card-body"},[n("div",{staticClass:"media"},[n("img",{staticClass:"rounded-circle box-shadow mr-2",attrs:{src:t.status.account.avatar,width:"32px",height:"32px",onerror:"this.onerror=null;this.src='/storage/avatars/default.png?v=2'",alt:"avatar"}}),t._v(" "),n("div",{staticClass:"media-body"},[n("div",{staticClass:"pl-2 d-flex align-items-top"},[n("a",{staticClass:"username font-weight-bold text-dark text-decoration-none text-break",attrs:{href:t.profileUrl(t.status)},domProps:{innerHTML:t._s(t.statusCardUsernameFormat(t.status))}},[t._v("\n\t\t\t\t\t\t\tLoading...\n\t\t\t\t\t\t")]),t._v(" "),n("span",{staticClass:"px-1 text-lighter"},[t._v("\n\t\t\t\t\t\t\t·\n\t\t\t\t\t\t")]),t._v(" "),n("a",{staticClass:"font-weight-bold text-lighter",attrs:{href:t.statusUrl(t.status)}},[t._v("\n\t\t\t\t\t\t\t"+t._s(t.shortTimestamp(t.status.created_at))+"\n\t\t\t\t\t\t")]),t._v(" "),n("span",{staticClass:"text-right",staticStyle:{"flex-grow":"1"}},[n("button",{staticClass:"btn btn-link text-dark py-0",attrs:{type:"button"},on:{click:function(e){return t.ctxMenu()}}},[n("span",{staticClass:"fas fa-ellipsis-h text-lighter"}),t._v(" "),n("span",{staticClass:"sr-only"},[t._v("Post Menu")])])])]),t._v(" "),n("div",{staticClass:"pl-2"},[t.status.sensitive?n("details",[n("summary",{staticClass:"mb-2 font-weight-bold text-muted"},[t._v("Content Warning")]),t._v(" "),n("p",{staticClass:"pt-2 text-break status-content",domProps:{innerHTML:t._s(t.status.content)}})]):n("p",{staticClass:"pt-2 text-break status-content",domProps:{innerHTML:t._s(t.status.content)}}),t._v(" "),n("p",{staticClass:"mb-0"},[n("i",{staticClass:"fa-heart fa-lg cursor-pointer mr-3",class:{"far text-muted":!t.status.favourited,"fas text-danger":t.status.favourited},on:{click:function(e){return t.likeStatus(t.status,e)}}}),t._v(" "),n("i",{staticClass:"far fa-comment cursor-pointer text-muted fa-lg mr-3",on:{click:function(e){return t.commentFocus(t.status,e)}}})])])])])])]):"poll"===t.status.pf_type?n("div",[n("poll-card",{attrs:{status:t.status,profile:t.profile},on:{"status-delete":t.statusDeleted}})],1):n("div",{staticClass:"card rounded-0 border-top-0 status-card card-md-rounded-0 shadow-none border"},[t.status?n("div",{staticClass:"card-header d-inline-flex align-items-center bg-white"},[n("div",[n("img",{staticClass:"rounded-circle box-shadow",attrs:{src:t.status.account.avatar,width:"32px",height:"32px",onerror:"this.onerror=null;this.src='/storage/avatars/default.png?v=2'",alt:"avatar"}})]),t._v(" "),n("div",{staticClass:"pl-2"},[n("a",{staticClass:"username font-weight-bold text-dark text-decoration-none text-break",attrs:{href:t.profileUrl(t.status)},domProps:{innerHTML:t._s(t.statusCardUsernameFormat(t.status))}},[t._v("\n\t\t\t\t\tLoading...\n\t\t\t\t")]),t._v(" "),t.status.account.is_admin?n("span",{staticClass:"fa-stack",staticStyle:{height:"1em","line-height":"1em","max-width":"19px"},attrs:{title:"Admin Account","data-toggle":"tooltip"}},[n("i",{staticClass:"fas fa-certificate text-danger fa-stack-1x"}),t._v(" "),n("i",{staticClass:"fas fa-crown text-white fa-sm fa-stack-1x",staticStyle:{"font-size":"7px"}})]):t._e(),t._v(" "),n("div",{staticClass:"d-flex align-items-center"},[t.status.place?n("a",{staticClass:"small text-decoration-none text-muted",attrs:{href:"/discover/places/"+t.status.place.id+"/"+t.status.place.slug,title:"Location","data-toggle":"tooltip"}},[n("i",{staticClass:"fas fa-map-marked-alt"}),t._v(" "+t._s(t.status.place.name)+", "+t._s(t.status.place.country))]):t._e()])]),t._v(" "),t.canFollow(t.status)?n("div",[n("span",{staticClass:"px-2"}),t._v(" "),n("button",{staticClass:"btn btn-primary btn-sm font-weight-bold py-1 px-3 rounded-lg",on:{click:function(e){return t.follow(t.status.account.id)}}},[n("i",{staticClass:"far fa-user-plus mr-1"}),t._v(" Follow")])]):t._e(),t._v(" "),t.status.hasOwnProperty("relationship")&&t.status.relationship.hasOwnProperty("following")&&t.status.relationship.following?n("div",[n("span",{staticClass:"px-2"}),t._v(" "),n("button",{staticClass:"btn btn-outline-primary btn-sm font-weight-bold py-1 px-3 rounded-lg",on:{click:function(e){return t.unfollow(t.status.account.id)}}},[n("i",{staticClass:"far fa-user-check mr-1"}),t._v(" Following")])]):t._e(),t._v(" "),n("div",{staticClass:"text-right",staticStyle:{"flex-grow":"1"}},[n("button",{staticClass:"btn btn-link text-dark py-0",attrs:{type:"button"},on:{click:function(e){return t.ctxMenu()}}},[n("span",{staticClass:"fas fa-ellipsis-h text-lighter"}),t._v(" "),n("span",{staticClass:"sr-only"},[t._v("Post Menu")])])])]):t._e(),t._v(" "),n("div",{staticClass:"postPresenterContainer",staticStyle:{background:"#000"}},["photo"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("photo-presenter",{attrs:{status:t.status},on:{lightbox:t.lightbox,togglecw:function(e){t.status.sensitive=!1}}})],1):"video"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("video-presenter",{attrs:{status:t.status},on:{togglecw:function(e){t.status.sensitive=!1}}})],1):"photo:album"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("photo-album-presenter",{attrs:{status:t.status},on:{lightbox:t.lightbox,togglecw:function(e){t.status.sensitive=!1}}})],1):"video:album"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("video-album-presenter",{attrs:{status:t.status},on:{togglecw:function(e){t.status.sensitive=!1}}})],1):"photo:video:album"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("mixed-album-presenter",{attrs:{status:t.status},on:{lightbox:t.lightbox,togglecw:function(e){t.status.sensitive=!1}}})],1):n("div",{staticClass:"w-100"},[n("p",{staticClass:"text-center p-0 font-weight-bold text-white"},[t._v("Error: Problem rendering preview.")])])]),t._v(" "),t.config.features.label.covid.enabled&&t.status.label&&1==t.status.label.covid?n("div",{staticClass:"card-body border-top border-bottom py-2 cursor-pointer pr-2",on:{click:function(e){return t.labelRedirect()}}},[n("p",{staticClass:"font-weight-bold d-flex justify-content-between align-items-center mb-0"},[n("span",[n("i",{staticClass:"fas fa-info-circle mr-2"}),t._v("\n\t\t\t\t\tFor information about COVID-19, "+t._s(t.config.features.label.covid.org)+"\n\t\t\t\t")]),t._v(" "),t._m(0)])]):t._e(),t._v(" "),n("div",{staticClass:"card-body"},[t.reactionBar?n("div",{staticClass:"reactions my-1 pb-2"},[t.status.favourited?n("h3",{staticClass:"fas fa-heart text-danger pr-3 m-0 cursor-pointer",attrs:{title:"Like"},on:{click:function(e){return t.likeStatus(t.status,e)}}}):n("h3",{staticClass:"fal fa-heart pr-3 m-0 like-btn text-dark cursor-pointer",attrs:{title:"Like"},on:{click:function(e){return t.likeStatus(t.status,e)}}}),t._v(" "),t.status.comments_disabled?t._e():n("h3",{staticClass:"fal fa-comment text-dark pr-3 m-0 cursor-pointer",attrs:{title:"Comment"},on:{click:function(e){return t.commentFocus(t.status,e)}}}),t._v(" "),t.status.taggedPeople.length?n("span",{staticClass:"float-right"},[n("span",{staticClass:"font-weight-light small",staticStyle:{color:"#718096"}},[n("i",{staticClass:"far fa-user",attrs:{"data-toggle":"tooltip",title:"Tagged People"}}),t._v(" "),t._l(t.status.taggedPeople,(function(t,e){return n("span",{staticClass:"mr-n2"},[n("a",{attrs:{href:"/"+t.username}},[n("img",{staticClass:"border rounded-circle",attrs:{src:t.avatar,width:"20px",height:"20px","data-toggle":"tooltip",title:"@"+t.username,alt:"Avatar"}})])])}))],2)]):t._e()]):t._e(),t._v(" "),t.status.liked_by.username&&t.status.liked_by.username!==t.profile.username?n("div",{staticClass:"likes mb-1"},[n("span",{staticClass:"like-count"},[t._v("Liked by\n\t\t\t\t\t"),n("a",{staticClass:"font-weight-bold text-dark",attrs:{href:t.status.liked_by.url}},[t._v(t._s(t.status.liked_by.username))]),t._v(" "),1==t.status.liked_by.others?n("span",[t._v("\n\t\t\t\t\t\tand "),t.status.liked_by.total_count_pretty?n("span",{staticClass:"font-weight-bold"},[t._v(t._s(t.status.liked_by.total_count_pretty))]):t._e(),t._v(" "),n("span",{staticClass:"font-weight-bold"},[t._v("others")])]):t._e()])]):t._e(),t._v(" "),"text"!=t.status.pf_type?n("div",{staticClass:"caption"},[t.status.sensitive?t._e():n("p",{staticClass:"mb-2 read-more",staticStyle:{overflow:"hidden"}},[n("span",{staticClass:"username font-weight-bold"},[n("bdi",[n("a",{staticClass:"text-dark",attrs:{href:t.profileUrl(t.status)}},[t._v(t._s(t.status.account.username))])])]),t._v(" "),n("span",{staticClass:"status-content",domProps:{innerHTML:t._s(t.status.content)}})])]):t._e(),t._v(" "),n("div",{staticClass:"timestamp mt-2"},[n("p",{staticClass:"small mb-0"},["archived"!=t.status.visibility?n("a",{staticClass:"text-muted text-uppercase",attrs:{href:t.statusUrl(t.status)}},[n("timeago",{directives:[{name:"b-tooltip",rawName:"v-b-tooltip.hover.bottom",modifiers:{hover:!0,bottom:!0}}],attrs:{datetime:t.status.created_at,"auto-update":60,"converter-options":{includeSeconds:!0},title:t.timestampFormat(t.status.created_at)}})],1):n("span",{staticClass:"text-muted text-uppercase"},[t._v("\n\t\t\t\t\t\tPosted "),n("timeago",{directives:[{name:"b-tooltip",rawName:"v-b-tooltip.hover.bottom",modifiers:{hover:!0,bottom:!0}}],attrs:{datetime:t.status.created_at,"auto-update":60,"converter-options":{includeSeconds:!0},title:t.timestampFormat(t.status.created_at)}})],1),t._v(" "),t.recommended?n("span",[n("span",{staticClass:"px-1"},[t._v("·")]),t._v(" "),n("span",{staticClass:"text-muted"},[t._v("Based on popular and trending content")])]):t._e()])])])]),t._v(" "),n("context-menu",{ref:"contextMenu",attrs:{status:t.status,profile:t.profile},on:{"status-delete":t.statusDeleted}})],1)}),[function(){var t=this.$createElement,e=this._self._c||t;return e("span",[e("i",{staticClass:"fas fa-chevron-right text-lighter"})])}],!1,null,null,null);e.a=s.exports},"0SFe":function(t,e,n){"use strict";n("SZ2H")},"0Z5r":function(t,e,n){var i=n("UudS");"string"==typeof i&&(i=[[t.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n("aET+")(i,o);i.locals&&(t.exports=i.locals)},"0dhX":function(t,e,n){(t.exports=n("I1BE")(!1)).push([t.i,".account-bookmarks-component .form-check[data-v-25a4c79a] {\n margin-left: 1rem;\n}\n.account-bookmarks-component .form-check .media-body[data-v-25a4c79a] {\n margin-left: 1rem;\n}\n.account-bookmarks-component .media-image-placeholder[data-v-25a4c79a] {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 50px;\n height: 50px;\n background-color: #f8f9fa !important;\n border-radius: 5px;\n margin-right: 1rem;\n}",""])},"0ox+":function(t,e,n){(t.exports=n("I1BE")(!1)).push([t.i,'.autocomplete-input{border:1px solid #eee;border-radius:8px;width:100%;padding:12px 12px 12px 48px;box-sizing:border-box;position:relative;font-size:16px;line-height:1.5;flex:1;background-color:#eee;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNjY2IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iOCIvPjxwYXRoIGQ9Ik0yMSAyMWwtNC00Ii8+PC9zdmc+");background-repeat:no-repeat;background-position:12px}.autocomplete-input:focus,.autocomplete-input[aria-expanded=true]{border-color:rgba(0,0,0,.12);background-color:#fff;outline:none;box-shadow:0 2px 2px rgba(0,0,0,.16)}[data-position=below] .autocomplete-input[aria-expanded=true]{border-bottom-color:transparent;border-radius:8px 8px 0 0}[data-position=above] .autocomplete-input[aria-expanded=true]{border-top-color:transparent;border-radius:0 0 8px 8px;z-index:2}.autocomplete[data-loading=true]:after{content:"";border:3px solid rgba(0,0,0,.12);border-right-color:rgba(0,0,0,.48);border-radius:100%;width:20px;height:20px;position:absolute;right:12px;top:50%;transform:translateY(-50%);-webkit-animation:rotate 1s linear infinite;animation:rotate 1s linear infinite}.autocomplete-result-list{margin:0;border:1px solid rgba(0,0,0,.12);padding:0;box-sizing:border-box;max-height:296px;overflow-y:auto;background:#fff;list-style:none;box-shadow:0 2px 2px rgba(0,0,0,.16)}[data-position=below] .autocomplete-result-list{margin-top:-1px;border-top-color:transparent;border-radius:0 0 8px 8px;padding-bottom:8px}[data-position=above] .autocomplete-result-list{margin-bottom:-1px;border-bottom-color:transparent;border-radius:8px 8px 0 0;padding-top:8px}.autocomplete-result{cursor:default;padding:12px 12px 12px 48px;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjY2NjIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iOCIvPjxwYXRoIGQ9Ik0yMSAyMWwtNC00Ii8+PC9zdmc+");background-repeat:no-repeat;background-position:12px}.autocomplete-result:hover,.autocomplete-result[aria-selected=true]{background-color:rgba(0,0,0,.06)}@-webkit-keyframes rotate{0%{transform:translateY(-50%) rotate(0deg)}to{transform:translateY(-50%) rotate(359deg)}}@keyframes rotate{0%{transform:translateY(-50%) rotate(0deg)}to{transform:translateY(-50%) rotate(359deg)}}',""])},"1PLf":function(t,e,n){t.exports=function(t){var e={};function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(i,o,function(e){return t[e]}.bind(null,o));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s="fb15")}({"00ee":function(t,e,n){var i={};i[n("b622")("toStringTag")]="z",t.exports="[object z]"===String(i)},"0366":function(t,e,n){var i=n("1c0b");t.exports=function(t,e,n){if(i(t),void 0===e)return t;switch(n){case 0:return function(){return t.call(e)};case 1:return function(n){return t.call(e,n)};case 2:return function(n,i){return t.call(e,n,i)};case 3:return function(n,i,o){return t.call(e,n,i,o)}}return function(){return t.apply(e,arguments)}}},"0538":function(t,e,n){"use strict";var i=n("1c0b"),o=n("861d"),a=[].slice,r={},s=function(t,e,n){if(!(e in r)){for(var i=[],o=0;o0;(a>>>=1)&&(e+=e))1&a&&(n+=e);return n}},"19aa":function(t,e){t.exports=function(t,e,n){if(!(t instanceof e))throw TypeError("Incorrect "+(n?n+" ":"")+"invocation");return t}},"1be4":function(t,e,n){var i=n("d066");t.exports=i("document","documentElement")},"1c0b":function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(String(t)+" is not a function");return t}},"1c7e":function(t,e,n){var i=n("b622")("iterator"),o=!1;try{var a=0,r={next:function(){return{done:!!a++}},return:function(){o=!0}};r[i]=function(){return this},Array.from(r,(function(){throw 2}))}catch(t){}t.exports=function(t,e){if(!e&&!o)return!1;var n=!1;try{var a={};a[i]=function(){return{next:function(){return{done:n=!0}}}},t(a)}catch(t){}return n}},"1cdc":function(t,e,n){var i=n("342f");t.exports=/(iphone|ipod|ipad).*applewebkit/i.test(i)},"1d80":function(t,e){t.exports=function(t){if(null==t)throw TypeError("Can't call method on "+t);return t}},2266:function(t,e,n){var i=n("825a"),o=n("e95a"),a=n("50c4"),r=n("0366"),s=n("35a1"),l=n("9bdd"),c=function(t,e){this.stopped=t,this.result=e};(t.exports=function(t,e,n,u,d){var p,h,f,m,v,g,b,y=r(e,n,u?2:1);if(d)p=t;else{if("function"!=typeof(h=s(t)))throw TypeError("Target is not iterable");if(o(h)){for(f=0,m=a(t.length);m>f;f++)if((v=u?y(i(b=t[f])[0],b[1]):y(t[f]))&&v instanceof c)return v;return new c(!1)}p=h.call(t)}for(g=p.next;!(b=g.call(p)).done;)if("object"==typeof(v=l(p,y,b.value,u))&&v&&v instanceof c)return v;return new c(!1)}).stop=function(t){return new c(!0,t)}},"23cb":function(t,e,n){var i=n("a691"),o=Math.max,a=Math.min;t.exports=function(t,e){var n=i(t);return n<0?o(n+e,0):a(n,e)}},"23e7":function(t,e,n){var i=n("da84"),o=n("06cf").f,a=n("9112"),r=n("6eeb"),s=n("ce4e"),l=n("e893"),c=n("94ca");t.exports=function(t,e){var n,u,d,p,h,f=t.target,m=t.global,v=t.stat;if(n=m?i:v?i[f]||s(f,{}):(i[f]||{}).prototype)for(u in e){if(p=e[u],d=t.noTargetGet?(h=o(n,u))&&h.value:n[u],!c(m?u:f+(v?".":"#")+u,t.forced)&&void 0!==d){if(typeof p==typeof d)continue;l(p,d)}(t.sham||d&&d.sham)&&a(p,"sham",!0),r(n,u,p,t)}}},"241c":function(t,e,n){var i=n("ca84"),o=n("7839").concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return i(t,o)}},"25f0":function(t,e,n){"use strict";var i=n("6eeb"),o=n("825a"),a=n("d039"),r=n("ad6d"),s=RegExp.prototype,l=s.toString,c=a((function(){return"/a/b"!=l.call({source:"a",flags:"b"})})),u="toString"!=l.name;(c||u)&&i(RegExp.prototype,"toString",(function(){var t=o(this),e=String(t.source),n=t.flags;return"/"+e+"/"+String(void 0===n&&t instanceof RegExp&&!("flags"in s)?r.call(t):n)}),{unsafe:!0})},2626:function(t,e,n){"use strict";var i=n("d066"),o=n("9bf2"),a=n("b622"),r=n("83ab"),s=a("species");t.exports=function(t){var e=i(t),n=o.f;r&&e&&!e[s]&&n(e,s,{configurable:!0,get:function(){return this}})}},2994:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n("49d8"),o=n("3054"),a=n("aacc");e.default=function(t,e,n,r,s){if(r<1||r>9||s<1||s>9)throw new a.ValidationError("BlurHash must have between 1 and 9 components");if(e*n*4!==t.length)throw new a.ValidationError("Width and height must match the pixels array");for(var l=[],c=function(i){for(var a=function(a){var r=0==a&&0==i?1:2,s=function(t,e,n,i){for(var a=0,r=0,s=0,l=4*e,c=0;c0){var g=Math.max.apply(Math,f.map((function(t){return Math.max.apply(Math,t)}))),b=Math.floor(Math.max(0,Math.min(82,Math.floor(166*g-.5))));d=(b+1)/166,m+=i.encode83(b,1)}else d=1,m+=i.encode83(0,1);return m+=i.encode83((p=h,(o.linearTosRGB(p[0])<<16)+(o.linearTosRGB(p[1])<<8)+o.linearTosRGB(p[2])),4),f.forEach((function(t){m+=i.encode83(function(t,e){return 19*Math.floor(Math.max(0,Math.min(18,Math.floor(9*o.signPow(t[0]/e,.5)+9.5))))*19+19*Math.floor(Math.max(0,Math.min(18,Math.floor(9*o.signPow(t[1]/e,.5)+9.5))))+Math.floor(Math.max(0,Math.min(18,Math.floor(9*o.signPow(t[2]/e,.5)+9.5))))}(t,d),2)})),m}},"2cf4":function(t,e,n){var i,o,a,r=n("da84"),s=n("d039"),l=n("c6b6"),c=n("0366"),u=n("1be4"),d=n("cc12"),p=n("1cdc"),h=r.location,f=r.setImmediate,m=r.clearImmediate,v=r.process,g=r.MessageChannel,b=r.Dispatch,y=0,w={},_=function(t){if(w.hasOwnProperty(t)){var e=w[t];delete w[t],e()}},x=function(t){return function(){_(t)}},C=function(t){_(t.data)},k=function(t){r.postMessage(t+"",h.protocol+"//"+h.host)};f&&m||(f=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return w[++y]=function(){("function"==typeof t?t:Function(t)).apply(void 0,e)},i(y),y},m=function(t){delete w[t]},"process"==l(v)?i=function(t){v.nextTick(x(t))}:b&&b.now?i=function(t){b.now(x(t))}:g&&!p?(a=(o=new g).port2,o.port1.onmessage=C,i=c(a.postMessage,a,1)):!r.addEventListener||"function"!=typeof postMessage||r.importScripts||s(k)||"file:"===h.protocol?i="onreadystatechange"in d("script")?function(t){u.appendChild(d("script")).onreadystatechange=function(){u.removeChild(this),_(t)}}:function(t){setTimeout(x(t),0)}:(i=k,r.addEventListener("message",C,!1))),t.exports={set:f,clear:m}},"2d00":function(t,e,n){var i,o,a=n("da84"),r=n("342f"),s=a.process,l=s&&s.versions,c=l&&l.v8;c?o=(i=c.split("."))[0]+i[1]:r&&(!(i=r.match(/Edge\/(\d+)/))||i[1]>=74)&&(i=r.match(/Chrome\/(\d+)/))&&(o=i[1]),t.exports=o&&+o},3054:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.sRGBToLinear=function(t){var e=t/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)},e.linearTosRGB=function(t){var e=Math.max(0,Math.min(1,t));return e<=.0031308?Math.round(12.92*e*255+.5):Math.round(255*(1.055*Math.pow(e,1/2.4)-.055)+.5)},e.sign=function(t){return t<0?-1:1},e.signPow=function(t,n){return e.sign(t)*Math.pow(Math.abs(t),n)}},3410:function(t,e,n){var i=n("23e7"),o=n("d039"),a=n("7b0b"),r=n("e163"),s=n("e177");i({target:"Object",stat:!0,forced:o((function(){r(1)})),sham:!s},{getPrototypeOf:function(t){return r(a(t))}})},"342f":function(t,e,n){var i=n("d066");t.exports=i("navigator","userAgent")||""},"35a1":function(t,e,n){var i=n("f5df"),o=n("3f8c"),a=n("b622")("iterator");t.exports=function(t){if(null!=t)return t[a]||t["@@iterator"]||o[i(t)]}},"37e8":function(t,e,n){var i=n("83ab"),o=n("9bf2"),a=n("825a"),r=n("df75");t.exports=i?Object.defineProperties:function(t,e){a(t);for(var n,i=r(e),s=i.length,l=0;s>l;)o.f(t,n=i[l++],e[n]);return t}},"3bbe":function(t,e,n){var i=n("861d");t.exports=function(t){if(!i(t)&&null!==t)throw TypeError("Can't set "+String(t)+" as a prototype");return t}},"3ca3":function(t,e,n){"use strict";var i=n("6547").charAt,o=n("69f3"),a=n("7dd0"),r=o.set,s=o.getterFor("String Iterator");a(String,"String",(function(t){r(this,{type:"String Iterator",string:String(t),index:0})}),(function(){var t,e=s(this),n=e.string,o=e.index;return o>=n.length?{value:void 0,done:!0}:(t=i(n,o),e.index+=t.length,{value:t,done:!1})}))},"3f8c":function(t,e){t.exports={}},"408a":function(t,e,n){var i=n("c6b6");t.exports=function(t){if("number"!=typeof t&&"Number"!=i(t))throw TypeError("Incorrect invocation");return+t}},"428f":function(t,e,n){var i=n("da84");t.exports=i},"44ad":function(t,e,n){var i=n("d039"),o=n("c6b6"),a="".split;t.exports=i((function(){return!Object("z").propertyIsEnumerable(0)}))?function(t){return"String"==o(t)?a.call(t,""):Object(t)}:Object},"44d2":function(t,e,n){var i=n("b622"),o=n("7c73"),a=n("9bf2"),r=i("unscopables"),s=Array.prototype;null==s[r]&&a.f(s,r,{configurable:!0,value:o(null)}),t.exports=function(t){s[r][t]=!0}},"44de":function(t,e,n){var i=n("da84");t.exports=function(t,e){var n=i.console;n&&n.error&&(1===arguments.length?n.error(t):n.error(t,e))}},4840:function(t,e,n){var i=n("825a"),o=n("1c0b"),a=n("b622")("species");t.exports=function(t,e){var n,r=i(t).constructor;return void 0===r||null==(n=i(r)[a])?e:o(n)}},4930:function(t,e,n){var i=n("d039");t.exports=!!Object.getOwnPropertySymbols&&!i((function(){return!String(Symbol())}))},"49d8":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","#","$","%","*","+",",","-",".",":",";","=","?","@","[","]","^","_","{","|","}","~"];e.decode83=function(t){for(var e=0,n=0;nu;)if((s=l[u++])!=s)return!0}else for(;c>u;u++)if((t||u in l)&&l[u]===n)return t||u||0;return!t&&-1}};t.exports={includes:r(!0),indexOf:r(!1)}},"50c4":function(t,e,n){var i=n("a691"),o=Math.min;t.exports=function(t){return t>0?o(i(t),9007199254740991):0}},5135:function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},5692:function(t,e,n){var i=n("c430"),o=n("c6cd");(t.exports=function(t,e){return o[t]||(o[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.6.5",mode:i?"pure":"global",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})},"56ef":function(t,e,n){var i=n("d066"),o=n("241c"),a=n("7418"),r=n("825a");t.exports=i("Reflect","ownKeys")||function(t){var e=o.f(r(t)),n=a.f;return n?e.concat(n(t)):e}},5899:function(t,e){t.exports="\t\n\v\f\r \u2028\u2029\ufeff"},"58a8":function(t,e,n){var i=n("1d80"),o="["+n("5899")+"]",a=RegExp("^"+o+o+"*"),r=RegExp(o+o+"*$"),s=function(t){return function(e){var n=String(i(e));return 1&t&&(n=n.replace(a,"")),2&t&&(n=n.replace(r,"")),n}};t.exports={start:s(1),end:s(2),trim:s(3)}},"5c6c":function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},"63a9":function(t,e,n){},6547:function(t,e,n){var i=n("a691"),o=n("1d80"),a=function(t){return function(e,n){var a,r,s=String(o(e)),l=i(n),c=s.length;return l<0||l>=c?t?"":void 0:(a=s.charCodeAt(l))<55296||a>56319||l+1===c||(r=s.charCodeAt(l+1))<56320||r>57343?t?s.charAt(l):a:t?s.slice(l,l+2):r-56320+(a-55296<<10)+65536}};t.exports={codeAt:a(!1),charAt:a(!0)}},"65f0":function(t,e,n){var i=n("861d"),o=n("e8b5"),a=n("b622")("species");t.exports=function(t,e){var n;return o(t)&&("function"!=typeof(n=t.constructor)||n!==Array&&!o(n.prototype)?i(n)&&null===(n=n[a])&&(n=void 0):n=void 0),new(void 0===n?Array:n)(0===e?0:e)}},"69f3":function(t,e,n){var i,o,a,r=n("7f9a"),s=n("da84"),l=n("861d"),c=n("9112"),u=n("5135"),d=n("f772"),p=n("d012"),h=s.WeakMap;if(r){var f=new h,m=f.get,v=f.has,g=f.set;i=function(t,e){return g.call(f,t,e),e},o=function(t){return m.call(f,t)||{}},a=function(t){return v.call(f,t)}}else{var b=d("state");p[b]=!0,i=function(t,e){return c(t,b,e),e},o=function(t){return u(t,b)?t[b]:{}},a=function(t){return u(t,b)}}t.exports={set:i,get:o,has:a,enforce:function(t){return a(t)?o(t):i(t,{})},getterFor:function(t){return function(e){var n;if(!l(e)||(n=o(e)).type!==t)throw TypeError("Incompatible receiver, "+t+" required");return n}}}},"6eeb":function(t,e,n){var i=n("da84"),o=n("9112"),a=n("5135"),r=n("ce4e"),s=n("8925"),l=n("69f3"),c=l.get,u=l.enforce,d=String(String).split("String");(t.exports=function(t,e,n,s){var l=!!s&&!!s.unsafe,c=!!s&&!!s.enumerable,p=!!s&&!!s.noTargetGet;"function"==typeof n&&("string"!=typeof e||a(n,"name")||o(n,"name",e),u(n).source=d.join("string"==typeof e?e:"")),t!==i?(l?!p&&t[e]&&(c=!0):delete t[e],c?t[e]=n:o(t,e,n)):c?t[e]=n:r(e,n)})(Function.prototype,"toString",(function(){return"function"==typeof this&&c(this).source||s(this)}))},7156:function(t,e,n){var i=n("861d"),o=n("d2bb");t.exports=function(t,e,n){var a,r;return o&&"function"==typeof(a=e.constructor)&&a!==n&&i(r=a.prototype)&&r!==n.prototype&&o(t,r),t}},7418:function(t,e){e.f=Object.getOwnPropertySymbols},"746f":function(t,e,n){var i=n("428f"),o=n("5135"),a=n("e538"),r=n("9bf2").f;t.exports=function(t){var e=i.Symbol||(i.Symbol={});o(e,t)||r(e,t,{value:a.f(t)})}},7839:function(t,e){t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},"7b0b":function(t,e,n){var i=n("1d80");t.exports=function(t){return Object(i(t))}},"7c73":function(t,e,n){var i,o=n("825a"),a=n("37e8"),r=n("7839"),s=n("d012"),l=n("1be4"),c=n("cc12"),u=n("f772"),d=u("IE_PROTO"),p=function(){},h=function(t){return"